小程序实现设备消息订阅

小程序实现设备消息订阅

一、说明

先说明一下什么是小程序的消息订阅,其实就是在小程序进行某个消息的订阅,订阅以后就可以在微信收到推送的消息了。推送走的服务端,在服务端调用微信的推送接口,然后推送至指定的微信用户。

二、创建模版

消息订阅是有个消息模版概念的,一般分为以下三种:

1.一次性订阅
2.长期订阅
3.设备消息订阅

设备消息订阅也是长期订阅。
这里以其举例,设备消息订阅需要先创建硬件设备,先去小程序管理台进行操作,如下图:

在这里插入图片描述


添加了设备后,消息订阅那会有该设备相应的长期消息订阅。然后可以创建消息模版,可以看到每个消息有自己的模版ID,这个在之后会用到。具体如下图:
在这里插入图片描述

从消息模版列表点进去详情之后可以看到详细内容,这里的详细内容格式后面会用到,具体如下图:
在这里插入图片描述


三、代码实现

代码实现分为小程序和服务端两部分。

1.小程序

小程序主要就是通过消息模版id和设备modelId来进行订阅。代码如下:

Page({
	data: {
        settingData: [
            {
                'tempId': 'modelId',
                'title': '门锁安全告警',
                'content': '未订阅'
            },

            {
                'tempId': 'modelId',
                'title': '门锁撬动告警',
                'content': '未订阅'
            },
            {
                'tempId': 'modelId',
                'title': '门锁故障告警',
                'content': '未订阅'
            },
            {
                'tempId': 'modelId',
                'title': '开关门提醒',
                'content': '未订阅'
            },
            {
                'tempId': 'modelId',
                'title': '有人逗留提醒',
                'content': '未订阅'
            },
            {
                'tempId': 'modelId',
                'title': '门锁电量不足提醒',
                'content': '未订阅'
            },
        ]
        ],
    },

    // ================== 页面加载
    onLoad(options) {
        this.getSettings();
    },


    // ================== 页面显示
    onShow() {
        this.getSettings();
    },
    

    // ================== 渲染订阅列表
    getSettings() {
        let that = this;
        wx.getSetting({ withSubscriptions: true, success(res) {
            console.log(" 获取状态 = ",res);
            var settingDic = res.subscriptionsSetting.itemSettings;     // 设置的状态
            console.log('订阅数据为->' + JSON.stringify(settingDic))
            for (let key in settingDic) {

                for (let i = 0; i < that.data.settingData[0].length; i++) {
                    var object = that.data.settingData[0][i];
                    if (object['tempId'] == key) {
                        if (settingDic[key] == 'accept') {
                            that.data.settingData[0][i].content = '接收';
                        }
                         if (settingDic[key] == 'acceptWithForcePush') {
                            that.data.settingData[0][i].content = '接收并提醒';
                        } 
                         if (settingDic[key] == 'reject') {
                            that.data.settingData[0][i].content = '已订阅,不接收';
                        } 
                    }
                }
            }
            // 刷新数据
            that.setData({ settingData: that.data.settingData })
        }})
    },
    

	// ================== 订阅事件
    tableCellItemEvent(e) {
        console.log(" 点击事件 = ", e.detail.tempId, app.getUserId());
        console.log(" 点击内容 = ", e.detail.content);
        let that = this;

        // ================== 未订阅
        if (e.detail.content === '未订阅') {

            wx.showLoading({ title: '加载中···', mask: true });
            let dicA = { sn: app.getUserId(),
                         modelId: '设备modelId' }
            deviceAPI.getSnTicket(dicA, (snTicket) => {
                console.log(" 获取票据信息 = ",snTicket);
                wx.hideLoading();

                // 弹出订阅授权框
                let dic = { tmplIds: [e.detail.tempId + ''],
                             sn: app.getUserId() + '',
                             snTicket: snTicket + '',
                             modelId: "设备modelId",}

                             console.log('dic=>>>',dic);

                wx.requestSubscribeDeviceMessage({  tmplIds: [e.detail.tempId + ''],
                                                    sn: app.getUserId() + '',
                                                    snTicket: snTicket + '',
                                                    modelId: "设备modelId", success(res) {
                    // "允许" 回调
                    console.log('允许" 回调==>',res)
                    that.getSettings();
                },fail(res) {    
                    // "取消" 回调 
                    console.log(res)
                }})

            })
            return;
        }

        // ================== 不接收
        if (e.detail.content === '不接收' || e.detail.content === '已订阅,不接收') {
            this.setData({ 
                tipsBox:"tipsBox",
                tipsMsg:" 该消息已订阅,但是未打开提醒,如需打开,请前往'设置'->'通知管理'->'接收并提醒' "
            });
            return;
        }

        // ================== 接收
        if (e.detail.content === "接收") {
            this.setData({ 
                tipsBox:"tipsBox",
                tipsMsg:" 该消息已订阅,但是未打开提醒,如需打开,请前往'设置'->'通知管理'->'接收并提醒' "
            });
            return;
        }

        // ================== 接收并提醒
        if (e.detail.content === '接收并提醒') {
            this.setData({ 
                tipsBox:"tipsBox",
                tipsMsg:" 该消息已设置接收并提醒,确定更改吗"
            });
            return;
        }
    }
})

说明:

1.样式这里就不放了
2.这里主要就是渲染下订阅列表,然后点击时进行订阅,直接将settingData渲染就行。
3.其中deviceAPI.getSnTicket是服务端实现的一个获取票据的接口,会在下文讲到。

2、服务端

1.获取票据
public String getSnTicket(String appid, String sn, String modelId){
   Map<String,String> requestUrlParam = new HashMap<>();
   requestUrlParam.put("access_token", getAccessToken(appid));

   Map<String,Object> requestBodyParam = new HashMap<>();
   requestBodyParam.put("sn", sn);
   requestBodyParam.put("model_id", modelId);

   String requestUrl = "https://api.weixin.qq.com/wxa/getsnticket";

   log.info("get sn ticket -> <request={}>", JSON.toJSONString(requestBodyParam));
   JSONObject jsonObject = JSON.parseObject(sendPost(requestUrl, requestUrlParam, JSON.toJSONString(requestBodyParam)));
   log.info("get sn ticket -> <response={}>", jsonObject.toJSONString());
   return jsonObject.getString("sn_ticket");
}

说明:

1.这里appid是你的小程序的appid,注意在小程序调接口时加上,我的是放在全局,所以看不到。
2.sn和modelId是小程序传的参数
3.getAccessToken是获取接口调用凭证,在下面会讲到
4.返回值是获取的票据

2.接口调用凭证
/**
 * 接口调用凭证
 */
private String getAccessToken(String appid, String secret) {
   Map<String,String> requestUrlParam = new HashMap<>();
   requestUrlParam.put("appid", appId);  //开发者设置中的appId
   requestUrlParam.put("secret", secret); //开发者设置中的appSecret
   requestUrlParam.put("grant_type", "client_credential");    //默认参数

   log.info("get access token -> <request={}>", JSON.toJSONString(requestUrlParam));

   String requestUrl = "https://api.weixin.qq.com/cgi-bin/token";
   JSONObject jsonObject = JSON.parseObject(sendPost(requestUrl, requestUrlParam, null));
   log.info("get access token -> <response={}>", jsonObject.toJSONString());
   return jsonObject.getString("access_token");
}

说明:

1.这里appid是你的小程序的appid
2.secret是小程序的秘钥

3.推送消息
/**
 * 向用户发送设备消息
 */
public JSONObject hardwareDeviceSend(String appid, List<String> openIds, String templateId, String modelId){

	Map<String, Map<String, String>> data = new HashMap<>();
    Map<String, String> timeMap = new HashMap<>();
    timeMap.put("value", DateUtils.getDateFormat(System.currentTimeMillis()));
    data.put("time1", timeMap);
    Map<String, String> tipMap = new HashMap<>();
    tipMap.put("value", pushMessage);
    data.put("enum_string2", tipMap);
    
    String page = "/pages/home/home?params="+param;  // 消息订阅跳转地址(对应微信小程序相应页面)
        
    Map<String,Object> requestUrlParam = new HashMap<>();
    requestUrlParam.put("access_token", getAccessToken(appid));
    Map<String,Object> requestBodyParam = new HashMap<>();
    requestBodyParam.put("to_openid_list", openIds);
    requestBodyParam.put("template_id", templateId);
    requestBodyParam.put("sn", sn);
    requestBodyParam.put("model_id", modelId);

    requestBodyParam.put("data", data);
    requestBodyParam.put("page", page);
    
    // developer为开发版; trial为体验版: formal为正式版: 默认为正式版
    requestBodyParam.put("miniprogram_state", "formal");  // 微信小程序版本切换配置

    log.info("hardware device send -> <request={}>", JSON.toJSONString(requestBodyParam));

    String requestUrl = "https://api.weixin.qq.com/cgi-bin/message/device/subscribe/send";
    JSONObject jsonObject = JSON.parseObject(sendPost(requestUrl, requestUrlParam, JSON.toJSONString(requestBodyParam)));
    log.info("hardware device send -> <response={}>", jsonObject.toJSONString());
    return jsonObject;
}

说明:

1.data中的参数根据消息模版列表中的详细内容格式来组装
2.page是你微信收到推送后点击时跳转的页面
3.appId是小程序的appid
4.openIds是要推送的为i想你用户的openId列表,可以一次性推送多个
5.templateId是消息模版的templateId
6.modelId是设备的modelId
7.sendPost是http工具请求方法,这个自己实现。jsonObject是推送的结果。

四、总结

总结一下设备消息推送的总流程,大概分为以下五步:

1.设备接入
2.获取模版ID
3.获取设备票据
4.发起订阅
5.发送设备消息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值