文档
小程序订阅消息(用户通过弹窗订阅)开发指南 | 微信开放文档
1.报错10004
- errCode: 10004
- errMsg: "requestSubscribeMessage:fail Invalid template id"
真机调试也不行
wx.requestSubscribeMessage({
tmplIds: result,
// 用户同意与否都需要传标识给后端
success(res) {
}
[{ "templateId": "MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD", "title": "福利包到账提醒" },
{ "templateId": "sDCqzUaMapgSETh_LHpuf0VuKaLXKMDltrOSlz8YADE", "title": "优惠券过期提醒" },]
原因:tmplIds参数必须是数组
const result = ["MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD",
"sDCqzUaMapgSETh_LHpuf0VuKaLXKMDltrOSlz8YADE"]
2.用户第一次拒绝,第二次不掉弹窗直接到success
wx.requestSubscribeMessage接口的success中res参数
我试着加了第三个模板ID:发现第二次弹窗只谈了加的模板id对应的模板title,之前被拒绝过的没有再显示
const result = ["MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD-bHW4",
"sDCqzUaMapgSETh_LHpuf0VuKaLXKMDltrOSlz8YADE","PokxmMG5bvk_LK7hrz40qqaliqKzAn6vyKkJPwbN7Sc"]
3.用户选择总是保持以上选择后,点击了拒绝
正常情况下,用户选择了总是保持以上选择后,点击了拒绝,之后就不会再次弹窗,如果下次进入时想要弹窗,需要通过微信小程序wx.openSetting()去引导用户到设置页面主动设置接收订阅消息
主要流程:
- 调用后端接口获取需要授权的模板ID;
- 通过wx.requestSubscribeMessage调用订阅消息授权弹窗;
- 检测到有拒绝授权情况就引导用户去设置页面设置接收订阅消息;
- 否则直接调用后端接口将已经同意过的模板进行上报;
/**
* 根据pushSceneId场景ID获取没有授权的模板
* @param {*} pushSceneId
*/
function commSubscribeMessage(pushSceneId) {
return new Promise((resolve, reject) => {
// 根据场景ID获取需要订阅消息的模板
// ajax('get', 'api/wechat/auth/unsubscribe/list', {
// pushSceneId
// }, ({ code, msg, result }) => {
// console.log('订阅结果上报', code, result)
// // 模板ID不为空才进行授权弹窗
// if (code === 0 && result.length > 0) {
// wx.requestSubscribeMessage调起授权订阅消息弹窗
// 优惠券
// const tmplIds = ["MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD-bHW4",
// "sDCqzUaMapgSETh_LHpuf0VuKaLXKMDltrOSlz8YADE"]
// 活动
// const tmplIds = ["PokxmMG5bvk_LK7hrz40qqaliqKzAn6vyKkJPwbN7Sc"]
const tmplIds = ["Uc-DA-Jr3N4ih7d5M3PkPrTFOi6t-AX0MGj4S8hvHqU"]
// 提单
// const tmplIds = ["3d6zsNMfQ3Wpgq1V8duO31v9gE8un7Lka_2E17sJZjs"]
wx.requestSubscribeMessage({
tmplIds,
// 用户同意与否都需要传标识给后端
async success(res) {
let acceptTmplIds = [];
let rejectTmplIds = [];
tmplIds.forEach(item=>{
if(res[item] === 'accept'){
acceptTmplIds.push(item);
}else if( res[item] === 'reject'){
rejectTmplIds.push(item);
}
});
// 检测到有拒绝授权情况
if(rejectTmplIds.length > 0){
console.log("引导用户授权");
await guideOpenSubscribeMessage(tmplIds,pushSceneId);
resolve(true);
}else{
console.log("用户之前已经同意过授权");
await agreeSubscribe(tmplIds,pushSceneId);
resolve(true);
}
},
async fail(res) {
console.log("用户拒绝授权", res);
if (res.errCode == 20004) {
// console.log(res, 'fail:用户关闭了主开关,无法进行订阅,引导开启---');
await guideOpenSubscribeMessage(tmplIds,pushSceneId);
resolve(true);
}
}
})
});
}
function guidSubscribeMessageAuthAfter(templateIds) {
return new Promise((resolve, reject) => {
//引导用户 开启订阅消息 之后,「openSetting」 接口暂时不会返回,用户手动设置后的状态,所以采用「getSetting」接口重新进行查询
wx.openSetting({
success: res => {
console.log(res, "guidSubscribeMessageAuthAfter");
}
})
resolve(true);
});
}
function guideOpenSubscribeMessage(templateIds,pushSceneId) {
return new Promise((resolve, reject) => {
//引导用户,手动引导用户去设置页开启,
wx.showModal({
title: '提示',
content: '检测到您有未开启的订阅消息权限,是否去设置?',
showCancel: true,
confirmText: '确认',
success: function (res) {
if (res.confirm) {
// 新版禁用,需要通过按钮触发
console.log("去设置授权信息");
guidSubscribeMessageAuthAfter(templateIds);
resolve(true);
} else {
console.log(`您已拒绝订阅消息授权,无法预约领取`);
disagreeSubscribe(templateIds,pushSceneId);
resolve(true);
}
}
})
});
}
function agreeSubscribe(templateIds,pushSceneId) {
ajax('post', '/api/wechat/auth/subscribe', {
templateIds,
pushSceneId,
allow: 1
}, res1 => {
console.log('订阅结果上报', res, res1)
})
}
function disagreeSubscribe(templateIds,pushSceneId) {
ajax('post', '/api/wechat/auth/subscribe', {
templateIds,
pushSceneId,
allow: 0
}, res1 => {
console.log('用户拒绝授权订阅结果上报', res, res1)
})
}
使用:
async goPage(e) {
// 授权订阅消息弹窗
await commSubscribeMessage("SC_001");
}
4.不引导用户去设置页面,但是要将用户是否选择过永远选中此项传给后端;且需要传openId和每个模板id都有个是否允许授权订阅的状态
let openId = wx.getStorageSync('userInfo').openId;
5.弹窗涉及所有成功或失败场景:
- 1.模板数据超过3个,报错20003
- 2.用户关闭了总开关(设置里面订阅消息的总开关关闭) 20004
- 3.之前弹窗过,且选择了拒绝,且选中了永远保持以上选择,只会返回以下信息,不会弹窗
MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD-bHW4: "reject"
PokxmMG5bvk_LK7hrz40qqaliqKzAn6vyKkJPwbN7Sc: "reject"
Uc-DA-Jr3N4ih7d5M3PkPrTFOi6t-AX0MGj4S8hvHqU: "reject"
- 4.用户手动在设置页面设置了接收消息,不会弹窗,只会显示一下信息
- MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD-bHW4: "accept"
- PokxmMG5bvk_LK7hrz40qqaliqKzAn6vyKkJPwbN7Sc: "accept"
- Uc-DA-Jr3N4ih7d5M3PkPrTFOi6t-AX0MGj4S8hvHqU: "accept"
- 5.所以想在获取用户是否选中了永远保持以上选择需要通过 wx.getSetting 进行获取
6.用户弹窗总流程
1.通过wx.getSetting()判断用户是否选择了"永远保持以上选择",如果选中了,需要通知后端,同时通知后端拒绝或者接受订阅的模板
2.如果用户没有选中,每次都会调用弹窗,调用微信小程序接口wx.requestSubscribeMessage()调起弹窗
7.小程序userId和openId关系
- userid是用户登录小程序的荷叶的唯一标识
- openid是小程序账号的唯一标识
- openid跟手机号没关系的,跟微信号一一对应;
- 次数限制是订阅一次推一次,看产品意思是userid维度订阅,一天订阅一次是咱们这边业务上的限制,不是微信的限制,微信一天内不限制一次性订阅的次数
- 还有个场景,如果推送消息也是按userid维度推送,小程序只能登录一个手机号,如果同一个小程序多个手机号登录且订阅授权过,那推送消息的时候,当时小程序登录的只有其中一个手机号,那么其他未登录手机号的订阅消息会在同一个小程序内收到,或者其他手机号在另外的微信上登录,一个userid可能对应多个openid,会在两个小程序上都收到订阅消息
- 推送消息,使用userid+openid维度进行推送