跳转到内容

微信授权消息通知

刀刀

1/7/2025

0 字

0 分钟

想要的效果

客户想要后台分配线索时对应的微信能够获取到消息通知。

用户已订阅

思路

配合后端查看微信开发文档,得知后端需要调用 code2Session 方法获取用户的 openidunionidsession_key 等信息,前端需要把最新的 code 传递过去。前端想要获取 code 则需要调用 wx.login() 方法获取。

使用 wx.requestSubscribeMessage 方法调起客户端小程序订阅消息界面,返回用户订阅消息的操作结果。

参数

属性类型默认值必填说明
tmplIdsArray需要订阅的消息模板的id的集合,一次调用最多可订阅3条消息(注意:iOS客户端7.0.6版本、Android客户端7.0.7版本之后的一次性订阅/长期订阅才支持多个模板消息,iOS客户端7.0.5版本、Android客户端7.0.6版本之前的一次订阅只支持一个模板消息)消息模板id在[微信公众平台(mp.weixin.qq.com)-功能-订阅消息]中配置。每个tmplId对应的模板标题需要不相同,否则会被过滤。
successfunction接口调用成功的回调函数
failfunction接口调用失败的回调函数
completefunction接口调用结束的回调函数(调用成功、失败都会执行

注意

当用户勾选了订阅面板中的 “总是保持以上选择,不再询问” 时,模板消息会被添加到用户的小程序设置页,通过 wx.getSetting 接口可获取用户对相关模板消息的订阅状态

由上表可知,我们需要传 tmplIds ID数组(由后端提供),成功回调函数返回结果如下所示:

js
{
    后端给的id模版: "accept",
	errMsg: "requestSubscribeMessage:ok"
	muj-uJ6qNrFpdYZgnSCT5fTWvI9XTV2n3sdwUBRSCR4: "accept"
	constructor: (...)
	hasOwnProperty: (...)
	isPrototypeOf: (...)
	propertyIsEnumerable: (...)
	toLocaleString: (...)
	toString: (...)
	valueOf: (...)
	__defineGetter__: (...)
	__defineSetter__: (...)
	__lookupGetter__: (...)
	__lookupSetter__: (...)
	__proto__: Object
 }

其中,如果用户点击同意消息推送,键为后端给的 ID 模版的值为 accept ,反正如果是拒绝则返回 reject 。因此可以通过判断其值来获取用户是否同意推送。订阅成功后直接调用 wx.login 获取 code 给后端登录。

代码

js
async loginFn() {
    const that = this
    wx.requestSubscribeMessage({
        tmplIds: ['后端给的id模板'],
        success(messageRes) {
            console.log(messageRes);
            if (messageRes.errMsg === 'requestSubscribeMessage:ok' && messageRes['后端给的id模板'] === 'accept') {
                wx.showToast({
                    title: '已订阅成功',
                    icon: 'none'
                })
                that.myLoginFn()
            } else {
                that.openConfirm(); //如果拒绝,在这里进行再次获取授权的操作
            }
            
        },
        fail(err) {
            console.log(err);
            that.openConfirm(); //如果拒绝,在这里进行再次获取授权的操作
        },
    })
},
    
myLoginFn() {
    const data = {
        username: this.data.username,
        password: this.data.password,
        captcha: this.data.captcha,
        checkKey: this.data.checkKey
    }
    wx.login({
        async success(result) {
            const res = await loginApi({
                ...data,
                code: result.code
            })
            if (res.code === 200) {
                // 登录成功执行的操作,跳转至首页
                wx.reLaunch({
                    url: '/pages/clue/clue'
                })
            } else {
                // 登录失败的操作,给予提示
                wx.showToast({
                    title: res.message,
                    icon: 'none'
                })
            }
        }
    })
},

用户已拒绝

思路

如果用户选择 “拒绝,以后不再提示” 选项后,会拒绝授权且日后不再弹出获取授权的弹窗。

官方文档,并没有给出明显的说明和解决示例。但是用户拒绝后会进入接口的fail回调,那我们就可以在fail回调里想办法再次进行授权操作。

通过查资料我们发现,微信小程序其实是有一个设置功能界面的,在设置界面里面我们可以对小程序进行再次授权。然而,通过官方文档我们可以知道,有一个 API 可以实现打开设置界面的功能,就是 wx.openSetting ,可以调起客户端小程序设置界面,返回用户设置的操作结果。但是设置界面只会出现小程序已经向用户请求过的权限,因此可以按照这个思路解决问题。

参数

属性类型默认值必填说明最低版本
withSubscriptionsBooleanfalse是否同时获取用户订阅消息的订阅状态,默认不获取。注意:withSubscriptions 只返回用户勾选过订阅面板中的“总是保持以上选择,不再询问”的订阅消息。2.10.3
successfunction接口调用成功的回调函数
failfunction接口调用失败的回调函数
completefunction接口调用结束的回调函数(调用成功、失败都会执行)

代码

js
openConfirm() {
    const that = this
    wx.showModal({
        content: '检测到您没打开此小程序的消息通知权限,为了能更好的接收消息,是否去设置打开?',
        confirmText: "确认",
        cancelText: "取消",
        success: function (res) {
            console.log(res);
            //点击“确认”时打开设置页面
            if (res.confirm) {
                console.log('用户点击确认')
                wx.openSetting({
                    success: (res) => {
                        that.myLoginFn()
                    }
                })
            } else {
                console.log('用户点击取消')
                that.myLoginFn()
            }
        }
    });
},

踩坑日记

wx.getSetting判断订阅状态一直为true

在最开始我的想法是先通过 wx.getSetting 获取用户是否授权,已授权则直接调用登录接口,未授权才弹出授权框。

而该方法返回的参数一直是 true ,无法用于判断。百度了一下,最终在这篇帖子找到答案:getSetting的scope.userInfo一直为true,那如何判断是否授权? 。其中有一个回答是说,获取1万次,需要1万次授权;没有“已授权”一说了。

p9IRRqH.png

因此授权了就存储到数据库里,下一次进入小程序时直接去数据库取,不需要每次进入一次小程序就要点击一次授权。(需要后端配合)

报错requestSubscribeMessage:fail can only be invoked by user TAP gesture.

wx.requestSubscribeMessage 方法只能在点击事件内调用,不能在回调函数,函数引用的方式使用。