老版本的订阅消息在2020年1月10日就下线了,相信不少人在接入新版本订阅系统的时候,或多或少会遇到一些问题,这里智库君跟大家介绍下新版订阅的机制和__不需要node/后端的情况下__ 独立完成功能开发。
一、新版订阅的机制
其实开发过程不难,但是要理清楚它里面的机制,智库君还是花了一些时间的,也踩了不少坑
先来看下官方介绍:
- 可以设置多个订阅选项
- 感叹号里面可以看到详情
- 有个默认不被选中的“总是”选项
这些就是新不同的地方,智库君在开发的时候也有很多疑问,点了“总是”再点“取消”按钮会怎样?部分选择订阅会怎样?下面为大家一一梳理
(1)部分选中
比如现在有三个选项 A,B,C,用户**“部分选中”**返回的情况:
这里用真机调试可以看到,有个返回值状态为“reject”。
如果我们反复几点点击同一个订阅后,这些值是如何计算的呢?
举例:
从这里看出,微信系统会自动记录用户点击的次数,并且做累加记录,如果用户只允许2次发送,而开发者发送了3次,最后一次将会被拒绝。
(2)点击“总是保持以上选择,不再询问”的情况
当用户点击“总是”之后,同一个类型的订阅将不再弹出,那如果有多个订阅选项呢?
举例
订阅AAA 三个订阅模板为 X Y Z
订阅BBB 二个订阅模板为 Y W
这时候如果“订阅AAA”按钮选择了“总是”,那么再点击“订阅BBB”按钮,将只会弹出__一个选项“W”__,不会有 “Y” 的模板,因为在之前 “订阅AAA” 按钮中已经包含了。
wx.requestSubscribeMessage({
tmplIds: ["MECDDOdhbC3SrQmMY5XrfqiIGbMTzpEN8Z7ScXJfcd0", "iSb2NIlNnnO60wlI-8Wx5Pe82jR7TRdwjotSXtM1-ww"],
success(res) {
console.log(res);
}
})
显示内容仅一个选项:
这里需要注意,“总是”选项是全局有效,不区分页面,选中“总是”的 W,X,Y,Z的模板,在全局任意页面中再次调用,再次调用将不再会显示!
返回值无提示用户是否选中“总是”。
(3)用户点击“总是”后,获取状态
wx.getSetting({
withSubscriptions: true,
success(res) {
console.log(res.authSetting)
// res.authSetting = {
// "scope.userInfo": true,
// "scope.subscribeMessage": true
// }
console.log(res.subscriptionsSetting)
// res.subscriptionsSetting = {
// SYS_MSG_TYPE_INTERACTIVE: 'accept',
// SYS_MSG_TYPE_RANK: 'accept',
// zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject',
// ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban',
// }
}
});
这里可以调用__wx.getSetting__方法,但是需要注意:如果用户第一次选“总是”后点击“取消”按钮或者订阅模板全部是未选中/reject的,那将获取不到状态(这里可能是BUG,期待官方未来修复)。
(4)用户点击“总是”后,让用户手动修改
前面说到用户点击“总是”后,系统将不再弹窗,但是我们可以通过**“wx.openSetting”**引导用户手动修改。
wx.openSetting({
success(res) {
console.log(res.authSetting)
// res.authSetting = {
// "scope.userInfo": true,
// "scope.userLocation": true
// }
}
})
当然用户自己也可以修改
总结
- 用户点击次数系统会自动累加,直接影响后台发送通知的次数。
- 用户选择“总是”后,小程序界面不再弹窗,但仍然有回调/callback。
- 任意订阅模板在用户选中“总是”(包括接受/拒绝2个状态)后,全局有效,就算其他订阅包含“此模板”也不再显示/弹出
- 当用户选择“总是”中“accept/选中/接受”的状态后,可以在__wx.getSetting__查询到用户是否选择“总是”。
- 当用户选择“总是”中“reject/未选中/拒绝”的状态后,返回值“无感知”(这里可能是BUG)
二、功能开发
使用微信自带的云开发,可以在没有node/后端开发支持下,完成整个订阅流程的开发。
(1)微信后台设置订阅模板和获取模板ID
1、打开小程序后台,找到订阅消息设置
2、在公共模板库找模板或者自己申请新模板,建议能用现成模板用现成的,因为申请周期可能较长,且容易被拒
3、选好模板后,点击详情
4、查看模板内容和发送DATA的结构
5、复制模板ID
(2)配置云函数
1、新建getOpenId云函数,用于获取用户的openID
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
return {
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
}
}
2、新建订阅推送通知云函数
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
//订阅推送通知
exports.main = async (event, context) => {
try {
const result = await cloud.openapi.subscribeMessage.send({
touser: event.openid, //接收用户的openId
page: 'pages/my/index', //订阅通知 需要跳转的页面
data: { //设置通知的内容
thing1: {
value: '小程序订阅填坑'
},
thing2: {
value: '智库方程式'
},
thing3: {
value: '一起学习,一起进步'
}
},
templateId: '5Efr7IqIooYO9nPw047Iggxbm9Ge2Km10GQ4amGOUac' //模板id
})
console.log(result)
return result
} catch (err) {
console.log(err)
return err
}
}
写完云函数记得__右键部署__下!!!
(3)小程序代码部分
<!------------html ------------->
<button bindtap="getOpenId" type='primary'>获取openId</button>
<view class="subBtn" catch:tap="sub">订阅AAA</view>
<view class="subBtn" catch:tap="send">订阅推送测试</view>
<view class="subBtn" catch:tap="setting">设置“总是”后,跳转修改</view>
//JS 部分
//获取用户的openid
getOpenId() {
wx.cloud.callFunction({
name: "getOpenId"
}).then(res => {
let openid = res.result.openid
console.log("获取openid成功", openid)
}).catch(res => {
console.log("获取openid失败", res)
})
},
//发送模板消息给指定的openId用户
send(openid){
wx.cloud.callFunction({
name: "sendSub",
data: {
openid: openid
}
}).then(res => {
console.log("发送通知成功", res)
}).catch(res => {
console.log("发送通知失败", res)
});
},
//消息订阅
sub: function () {
wx.requestSubscribeMessage({
tmplIds: ["5Efr7IqIooYO9nPw047Iggxbm9Ge2Km10GQ4amGOUac"],
success(res) {
console.log("订阅授权成功:"+res);
},
fail(res){
console.log("订阅授权失败:" + res);
}
})
},
//帮助用户跳转修改订阅状态
setting:function(){
wx.openSetting({
success(res) {
console.log(res.authSetting)
// res.authSetting = {
// "scope.userInfo": true,
// "scope.userLocation": true
// }
}
})
},
(4)测试流程
点击发送通知后,获得这样的效果:
获得对应返回值:
当errCode为0时,即发送通知成功。
当errCode为43101,说明用户只授权了一次,但是你发送了2次,超过用户授权次数。
三、进阶与思考
1、当你有__多个订阅模板__同时需要用户选择时,你可以通过以下代码记录,用户哪些选了,哪些没选。
wx.requestSubscribeMessage({
tmplIds: ["5Efr7IqIooYO9nPw047Iggxbm9Ge2Km10GQ4amGOUac", "OBB_Z10eh_Inm9p8EU6Ml_NS_mijXgTz3T07cxgKvX0","5Efr7IqIooYO9nPw047Iggxbm9Ge2Km10GQ4amGOUac"],
success(res) {
//console.log(res);
if (res.errMsg == "requestSubscribeMessage:ok") {
let acceptArray = []; //用户授权模板列表
for (let i = 0; i < tmplIds.length; i++) {
const element = tmplIds[i];
if (res[element] == "accept") {
acceptArray.push(element);
}
};
console.log(acceptArray);
if (acceptArray.length > 0) {
//执行下一步函数
}
}
}
})
2、一个关于是否需要记录用户对某个“订阅模板授权的次数”,以控制后台“发送的次数”,智库君在实战中认为,其实没有必要,顶多就是你发送返回一个错误码,微信之所有记录用户授权次数,也是为了保护用户不被骚扰。
3、你只需要记录用户点击了哪些需要授权的模板就行,为了是用户点击订阅后,改变按钮的状态,避免订阅按钮反复弹窗的问题,同时当检测到用户点错“总是”按钮后,可以自动跳转到“设置”界面。
4、这次智库君主要给大家简单介绍了下订阅全流程。后面大家可以根据自己的需要,添加和改进这些代码。比如:
- 配置云函数中的node函数,实现定时发送
- 配置云函数中的数据库,实现内容的自定义发送
最后,希望这篇文章能帮助到大家,一起学习,一起进步!
(官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html)
往期回顾: