前言
在开发小程序订阅消息遇到以下问题:
- 官方文档写的不详细,很多接口返回情况及测试场景都没有给出详细的说明
- 长期订阅每个消息模板订阅后不能再触发弹窗,测试成本高
- 对于长期订阅与一次性订阅,接口返回情况还不一致
所以对以上问题进行梳理,方便了解。
调试
由于长期订阅消息只能弹一次窗,所以难以测试,但还好开发者工具给我们提供了清除授权
的操作,清除了后我们可以再次发起弹窗请求,但需要注意,开发者工具中订阅授权接口返回跟真机有所差别。例如:弹窗点击取消返回的数据不是在fail回调里面,但是真机是在fail回调中返回的。所以可以在开发中工具中清除授权,然后在真机中测试,也是可以触发弹窗的(需要有开发者权限)。
订阅消息类型
- 一次性订阅:用户订阅后,每次只能下发一条对应的服务消息,每条消息可单独订阅或退订;后续想再下发消息需要用户再进行主动订阅操作
- 长期订阅:用户订阅一次后,开发者可长期下发多条消息,仅向政务民生、医疗、交通、金融、教育等线下公共服务开放;后续不需要用户再进行主动订阅操作
几种场景说明
-
小程序设置页-订阅消息-接收通知按钮关闭/开启
-
小程序设置页-订阅消息-接收通知按钮开启-消息模板接收/不接收
-
长期订阅弹窗
-
一次性订阅弹窗
长期订阅的状态及接口返回
场景 | 调用授权接口是否弹窗 | 弹窗操作 | 授权接口结果返回 |
---|---|---|---|
未订阅-接收通知按钮关闭 | × | - | fail回调 |
未订阅-接收通知按钮开启 | √ | 授权弹窗点击取消 | fail回调 |
未订阅-接收通知按钮开启 | √ | 授权弹窗点击允许,后续不弹窗 | success回调 |
未订阅-接收通知按钮开启 | √ | 授权弹窗点击”拒绝,不再询问“,后续不弹窗 | success回调 |
已订阅-接收通知按钮关闭 | × | - | fail回调 |
已订阅-接收通知按钮开启 | × | - | success回调 |
假设我需要授权的两条消息模板id为A1和A2
-
未订阅长期订阅消息
- 【接收通知按钮关闭】调用wx.getSetting获取的订阅状态,mainSwitch=false;调用wx.requestSubscribeMessage 授权订阅,
不会有订阅弹窗!
// wx.getSetting获取的订阅状态 { itemSettings: {} // 没有需要授权消息模板的id,代表未订阅 mainSwitch: false }
注意!调用授权接口,这里是fail回调返回的,如果用了await调用接口,需要做
try catch处理
,否则会直接抛出异常// wx.requestSubscribeMessage接口返回 { errCode: 20004 errMsg: "requestSubscribeMessage:fail The main switch is switched off" }
- 【接收通知按钮开启】调用wx.getSetting获取的订阅状态,mainSwitch=true;调用wx.requestSubscribeMessage 授权订阅,
会有订阅弹窗!
// wx.getSetting获取的订阅状态 { itemSettings: {} // 没有需要授权消息模板的id,代表未订阅 mainSwitch: true }
【调用授权接口,有弹窗,点击取消】注意!调用授权接口,这里是fail回调返回的,如果用了await的调用接口语法,需要做
try catch处理
// wx.requestSubscribeMessage接口返回 { errMsg: "requestSubscribeMessage:fail cancle" }
【调用授权接口,有弹窗,点击”拒绝,不再询问“】会把授权的消息模板都设置为【reject】状态
// wx.requestSubscribeMessage接口返回 { A1: "reject" A2: "reject" errMsg: "requestSubscribeMessage:ok" }
【调用授权接口,有弹窗,点击允许】根据勾选消息模板情况设置对应的模板id为【accept】状态
// wx.requestSubscribeMessage接口返回 { A1: "accept" A2: "accept" errMsg: "requestSubscribeMessage:ok" }
- 【接收通知按钮关闭】调用wx.getSetting获取的订阅状态,mainSwitch=false;调用wx.requestSubscribeMessage 授权订阅,
-
已订阅长期订阅消息
- 【接收通知按钮关闭】,调用wx.getSetting获取的订阅状态,mainSwitch=false;调用wx.requestSubscribeMessage 授权订阅,
不会有订阅弹窗!
// wx.getSetting获取的订阅状态 { A1: "reject" A2: "accept" itemSettings: { A1: "reject", A2: "accept", } mainSwitch: false }
注意!调用授权接口,这里是fail回调返回的,如果用了await调用接口,需要做
try catch处理
,否则会直接抛出异常// wx.requestSubscribeMessage接口返回 { errCode: 20004 errMsg: "requestSubscribeMessage:fail The main switch is switched off" }
- 【接收通知按钮开启,已订阅过的消息都设置为不接收】调用wx.getSetting获取的订阅状态,mainSwitch=true;调用wx.requestSubscribeMessage 授权订阅,
不会有订阅弹窗!
// wx.getSetting获取的订阅状态 { A1: "reject" A2: "reject" itemSettings: { A1: "reject", A2: "reject", } mainSwitch: true } // wx.requestSubscribeMessage接口返回 { A1: "reject" A2: "reject" errMsg: "requestSubscribeMessage:ok" }
- 【接收通知按钮开启,已订阅过的消息都设置为接收】调用wx.requestSubscribeMessage授权订阅,
不会有订阅弹窗!
// wx.getSetting获取的订阅状态 { A1: "accept" A2: "accept" itemSettings: { A1: "accept", A2: "accept", } mainSwitch: true } // wx.requestSubscribeMessage接口返回 { A1: "accept" A2: "accept" errMsg: "requestSubscribeMessage:ok" }
- 【接收通知按钮关闭】,调用wx.getSetting获取的订阅状态,mainSwitch=false;调用wx.requestSubscribeMessage 授权订阅,
总结一下长期订阅:
- 只有在接收通知按钮开启,并且wx.getSetting返回中不存在待订阅的模板id时,调用wx.requestSubscribeMessage授权订阅才会有弹窗
- 只要已订阅过长期订阅,后续无论怎么操作调用wx.requestSubscribeMessage授权订阅都不会有弹窗
- 需要注意在【有弹窗并点击取消】或者【接收通知按钮关闭】的情况,错误消息会在fail回调中返回,await调用时,需要做try catch处理,否则会直接抛出异常
一次性订阅的状态及返回
官方文档:当用户勾选了订阅面板中的“总是保持以上选择,不再询问”时,模板消息会被添加到用户的小程序设置页,通过 wx.getSetting 接口可获取用户对相关模板消息的订阅状态。
一次性消息订阅调用wx.requestSubscribeMessage授权订阅始终有弹窗(不论用户是否订阅过),除非用户点击勾选了订阅面板中的“总是保持以上选择,不再询问”时,相当于把模板id当长期订阅的方式处理了,后续调用授权接口就不会再弹窗。
场景 | 调用授权接口是否弹窗 | 弹窗操作 | 授权接口结果返回 |
---|---|---|---|
未订阅-接收通知按钮关闭 | × | - | fail回调 |
未订阅-接收通知按钮开启 | √ | 授权弹窗点击取消 | success回调 |
未订阅-接收通知按钮开启 | √ | 授权弹窗点击允许 | success回调 |
未订阅-接收通知按钮开启 | √ | 授权弹窗点击”总是保持以上选择,不再询问“,后续不弹窗 | success回调 |
已订阅-接收通知按钮关闭 | × | - | fail回调 |
已订阅-接收通知按钮开启-不勾选“总是保持以上选择,不再询问” | √ | - | success回调 |
已订阅-接收通知按钮开启-勾选“总是保持以上选择,不再询问” | × | - | success回调 |
在接口返回方面,跟长期订阅还是不同,遇到有些区别(坑)如下:
- 【点击取消】消息不在fail回调中返回,在success中,且返回模板状态为reject
// wx.requestSubscribeMessage接口返回
{
A1: "reject"
A2: "reject"
errMsg: "requestSubscribeMessage:ok"
}
// wx.getSetting获取的订阅状态
{
itemSettings: {} // 相当于未订阅一样,下次调用授权接口还有弹窗
mainSwitch: true
}
- 【点击允许】
// wx.requestSubscribeMessage接口返回
{
A1: "accept"
A2: "accept"
errMsg: "requestSubscribeMessage:ok"
}
// wx.getSetting获取的订阅状态
{
itemSettings: {}
mainSwitch: true
}
- 【点击”总是保持以上选择,不再询问“】勾选相关模板允许授权订阅,后续调用授权接口不弹窗
// wx.requestSubscribeMessage接口返回
{
A1: "accept"
A2: "accept"
errMsg: "requestSubscribeMessage:ok"
}
// wx.getSetting获取的订阅状态
{
A1: "accept"
A2: "accept"
itemSettings: {
A1: "accept",
A2: "accept",
}
mainSwitch: true
}
- 【接收通知按钮关闭】调用wx.getSetting获取的订阅状态,mainSwitch=false;调用wx.requestSubscribeMessage 授权订阅,
不会有订阅弹窗!
注意!调用授权接口,这里是fail回调返回的,如果用了await调用接口,需要做// wx.getSetting获取的订阅状态 { itemSettings: {} // 没有需要授权消息模板的id,代表未订阅 mainSwitch: false }
try catch处理
,否则会直接抛出异常// wx.requestSubscribeMessage接口返回 { errCode: 20004 errMsg: "requestSubscribeMessage:fail The main switch is switched off" }
长期订阅处理逻辑
最后
看似小小功能亦有其复杂之处,上文如有不正确之处,敬请指出,望看后能少踩坑~