宝哥软件园

用户拒绝/关闭订阅消息后 如何引导用户重新打开小程序?并得到用户的操作?

编辑:宝哥软件园 来源:互联网 时间:2021-12-03

前言

我已经有一段时间没有为小程序烦恼了。据说小程序年前发布了一条消息,模板消息分发功能将于1月10日下线。所有订阅消息都要用户手动触发确认同意,难度太大。之前对wx.openSetting、wx.getPhoneNumber、wx.getUserInfo等API的调整会让我很痛苦,而这次。

直接打js不难受吗?如果你不用手动确认,酷是肯定的,但是如果你从用户的角度不做任何事情,你就会得到我的信息,每天推给我一堆垃圾信息,这肯定会让你心烦,所以从这个角度来说,微信的调整也是为了尊重用户的隐私,毕竟用户第一。

今天主要想分享一下。今天在处理这个订阅消息的逻辑时,遇到了用户拒绝后如何重启并打开“订阅消息”通知,打开后获取其状态的问题。

如果你处理过小程序的订阅消息,你应该知道。在用户拒绝或关闭消息主开关后,我们指导用户手动开启“订阅消息”功能(即在openSettingAPI的调用回调中,scope.subscribeMessage状态不可用)。一开始我纠结了很久,百度和谷歌都用上了。我也发现很多同学也遇到过这样的问题,但是都没有找到解决的办法。终于,就在我要放弃的时候,突然灵光一闪,想到了一个解决的办法,于是我斗胆BB说了几句,分析了一下:

小贴士:我书看得少,但我喜欢一些关于盲BB的话。内容仅为个人解决的思路,仅供参考。缺点请见谅,不要喷,谢谢~

授权API示例

我们先来看一下调用的例子:

wx . request subscribe message({ tmplids :[' template id '],success (res) {}})同时官方也表示成功回调的模板有三种状态:

接受=同意拒绝=拒绝禁止=后台禁止失败也有相应的状态代码,如下所示:

小程序订阅消息用户拒绝/关闭后,如何引导用户再开启?并获得用户的操作呢(图1)

这次我想说的是错误代码20004和拒绝状态,

根据以往的经验,如果我们拒绝,肯定会直接使用openSetting来引导用户手动打开授权(),例如:

//以微信活动为例,导出默认类标志扩展wepy . page { config={ navigationbarbakgroundcolor : ' # fff ',navigationbar标题文本:' win points ',};组件={ Toast: Toast,Modals : Modals };methods={ };数据={ sign history :[]};Getrundata () {wx。getwerundata({ success : RES=}.用于处理运动步骤的逻辑} });} setauth(){ wx . getsetting({ success : RES={//第一步是检查是否有授权-如果没有授权(!Res. authsetting ['作用域。我们运行']) {/Step 2,开始授权,但是有一个漏洞(腾讯bug),之前被授权但是被拒绝了,所以会辜负WX。授权({scope 3360' scope。我们跑,成功3360()={这.},fail: ()={//Step 3,引导用户,手动引导用户点击按钮设置页面打开,# modal是自定义组件本。$ invoke ('modal ',' _ _ modal confirm _ ',['检测到您没有权限玩微信活动,要设置吗?',' openSetting ',//第四步,进入设置页面的回调——成功RES={ let { authsetting }=RES . detail;

if (authSetting['scope.werun']) { this.getRunData(); } else { this.$invoke('Toast', '__warning__', [ `您没有同意授权微信运动,获取步数失败` ]); } }, //第五步,点击取消按钮的回调 () => { this.$invoke('Toast', '__warning__', [ `您已拒绝微信运动授权,无法获取步数` ]); } ]); } }); } else { //第六步,已经授权直接进入保存逻辑 // console.log("授权了") this.getRunData(); } } }); }}

上面代码执行截图如下:

小程序订阅消息用户拒绝/关闭后,如何引导用户再开启?并获得用户的操作呢(图2)

小程序订阅消息用户拒绝/关闭后,如何引导用户再开启?并获得用户的操作呢(图3)

上述代码,this.$invoke('Modals'……)部分为自定义弹窗,即引用用户确定,去设置页,

requestSubscribeMessage 问题点

但是 在openSetting的回调里,是没有scope.subscribeMessage这一项的,下面是列出的scope 列表官方清单(文档地址):

小程序订阅消息用户拒绝/关闭后,如何引导用户再开启?并获得用户的操作呢(图4)

//提交订阅消息示例export default class Sign extends wepy.page {  config = {    navigationBarBackgroundColor: '#fff',    navigationBarTitleText: '赢积分',  };  setClock(e) {    let that = this;    if (wx.requestSubscribeMessage) {      wx.requestSubscribeMessage({        tmplIds: [pushReservationTmplIds],        success(res) {          if (res[pushReservationTmplIds] === 'accept') {            //发起请求……          } else if (res[pushReservationTmplIds] === 'reject') {            // 用户历史操作有设置了拒绝 or 关闭了订阅消息的主(总)开关,导致无法推送            that.guideOpenSubscribeMessage();          } else {            wx.showToast({              title: '授权订阅消息有误',              icon: 'none'            });          }        },        fail(res) {          // 20004:用户关闭了主开关 或在 消息通知 里 “拒绝接收”操作,无法进行订阅,引导开启          if (res.errCode == 20004) {            console.log(res, 'fail:用户关闭了主开关,无法进行订阅,引导开启---');          }        }      });    } else {      wx.showToast({        title: '请更新您微信版本,来获取订阅消息功能',        icon: 'none'      });    }  }  guideOpenSubscribeMessage() {    //引导用户,手动引导用户去设置页开启,    this.$invoke('Modals', '__modalConfirm__', [      '检测到您没有开启订阅消息的权限,是否去设置?',      'openSetting',      res => {        console.log('openSetting的回调数据:', res);        //但是这个回调数据里,并没有 「订阅消息」 相关 open/close 的状态返回      },      //用户点击了取消按钮      () => {        // console.log("取消了")        this.$invoke('Toast', '__warning__', [          `您已拒绝订阅消息授权,无法预约`        ]);      }    ]);}

小程序订阅消息用户拒绝/关闭后,如何引导用户再开启?并获得用户的操作呢(图5)

上图为openSetting的回调数据,而网上说回调里不做任何处理,用户是否有手动开启,则让提示让他再手动点击一次业务按钮,如果有开启,则回到最初的逻辑,订阅消息成功,否则则又循环进入openSetting设置页,俗称“死缠烂打授权法”,这当然不失为一种方法,但体验不是最好,

对于追求完美的我来说,不能接受,继续寻找更好的方案,把官方文档来回看,终于发现了新大陆,——wx.getSetting

小程序订阅消息用户拒绝/关闭后,如何引导用户再开启?并获得用户的操作呢(图6)

文档有有这么一个属性:subscriptionsSetting,感谢苍天,终于让我看到了订阅消息相关的东西,

//官方示例wx.getSetting({  withSubscriptions: true,  success (res) {    console.log(res.authSetting)    // res.authSetting = {    //   "scope.userInfo": true,    //   "scope.userLocation": true    // }    console.log(res.subscriptionsSetting)    // res.subscriptionsSetting = {    //   mainSwitch: true, // 订阅消息总开关    //   itemSettings: {   // 每一项开关    //     SYS_MSG_TYPE_INTERACTIVE: 'accept', // 小游戏系统订阅消息    //     SYS_MSG_TYPE_RANK: 'accept'    //     zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject', // 普通一次性订阅消息    //     ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban',    //   }    // }  }})

在wx.getSetting的回调里,有一项mainSwitch,还有一项withSubscriptions: true,最后回调里还能一项zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject',到这里,但它也只是在getSetting方法里啊,跟openSetting没有扯上任何关系,怎么办?

其实道理很简单,但人有时候就是这样,思维如果没有转换过来,你可以就会一直杠在那个死胡同里出不来,

openSetting回调里取不到状态, 那么我们是否可以在它的回调里,再做一次getSetting的调用里呢? ,取getSetting回调里的状态来判断,刚才用户在设置页的行为操作,直接看示例吧:

//提交订阅消息示例const pushReservationTmplIds = 'PVC_DBcvvdtffd1fO0vdS8YpSe0c7Br3QW54';export default class Sign extends wepy.page {  config = {    navigationBarBackgroundColor: '#fff',    navigationBarTitleText: '赢积分',  };  submitClock() {    fetchJson({      type: 'POST',      url: '/api/steps/clock',      data: {      },      success: res => {        wx.showToast({          title: '预定成功',          icon: 'success',          duration: 2000        });      }    });  }  setClock(e) {    let that = this;    if (wx.requestSubscribeMessage) {      wx.requestSubscribeMessage({        tmplIds: [pushReservationTmplIds],        success(res) {          if (res[pushReservationTmplIds] === 'accept') {            that.submitClock();          } else if (res[pushReservationTmplIds] === 'reject') {            // 用户历史操作有设置了拒绝 or 关闭了订阅消息的主(总)开关,导致无法推送            // console.log(res, '0 拒绝 or 关闭了订阅消息的主(总)开关---');            that.guideOpenSubscribeMessage();          } else {            wx.showToast({              title: '授权订阅消息有误',              icon: 'none'            });          }        },        fail(res) {          // 20004:用户关闭了主开关,无法进行订阅,引导开启          if (res.errCode == 20004) {            // console.log(res, 'fail:用户关闭了主开关,无法进行订阅,引导开启---');            that.guideOpenSubscribeMessage();          }        }      });    } else {      wx.showToast({        title: '请更新您微信版本,来获取订阅消息功能',        icon: 'none'      });    }  }  guidSubscribeMessageAuthAfter() {    //引导用户 开启订阅消息 之后,「openSetting」 接口暂时不会返回,用户手动设置后的状态,所以采用「getSetting」接口重新进行查询    wx.getSetting({      withSubscriptions: true,      success: res => {        let {          authSetting = {},          subscriptionsSetting: { mainSwitch = false, itemSettings = {} } = {}        } = res;        if (          (authSetting['scope.subscribeMessage'] || mainSwitch) &&          itemSettings[pushReservationTmplIds] === 'accept'        ) {          this.submitClock();          // console.log('用户手动开启同意了,订阅消息');        } else {          this.$invoke('Toast', '__warning__', [            `您没有同意授权订阅消息,预约领取失败`          ]);        }      }    });  }  guideOpenSubscribeMessage() {    //引导用户,手动引导用户去设置页开启,    this.$invoke('Modals', '__modalConfirm__', [      '检测到您没有开启订阅消息的权限,是否去设置?',      'openSetting',      //用户点击了确定按钮,进入设置页的回调      res => {        console.log('openSetting的回调数据:', res);        this.guidSubscribeMessageAuthAfter();      },      //用户点击了取消按钮      () => {        // console.log("取消了")        this.$invoke('Toast', '__warning__', [          `您已拒绝订阅消息授权,无法预约领取`        ]);      }    ]);  }}

结尾

到这里,wx.requestSubscribeMessage的问题,也就得到了解决,看到网上有贴子在喷requestSubscribeMessageAPI的设计,比如:wx.requestSubscribeMessage的接口参数结构设计反人性,实习生设计的吗?,其实我也想说这么庞大的一个生态体系,更新方案就考虑的这么不全面吗?还是说就是这么反人类?getSetting里给requestSubscribeMessage的相关状态,openSetting里又压根没有,然后又把它的引导开启逻辑UI也放在设置页里面,我就郁闷了,

今天的分享,为我个人的解决思路方案,如有不足之处,请指出,勿喷~谢谢!!

更多资讯
游戏推荐
更多+