1、获取模板 ID
在微信公众平台手动配置获取模板 ID:
登录 获取模板,
一次性订阅:如果没有合适的模板,可以申请添加新模板,审核通过后可使用。
永久订阅:不可以对模版进行修改
2、获取下发权限
详见小程序端消息订阅接口 wx.requestSubscribeMessage
// 订阅消息授权
getMsgInfo() {
let that = this
// 这里是获取下发权限地方,根据官方文档,可以根据 wx.getSetting() 的 withSubscriptions 这个参数获取用户是否打开订阅消息总开关。后面我们需要获取用户是否同意总是同意消息推送。所以这里要给它设置为true 。
wx.getSetting({
withSubscriptions: true, // 这里设置为true,下面才会返回mainSwitch
success: function (res) {
console.log(res)
// 调起授权界面弹窗
if (res.subscriptionsSetting.mainSwitch) {
// 用户打开了订阅消息总开关
if (!res.subscriptionsSetting.itemSettings) {
// 当用户没有点击 ’总是保持以上选择,不再询问‘ 按钮。那每次执到这都会拉起授权弹窗
// wx.showModal({
// title: '提示',
// content: '请授权开通服务通知',
// showCancel: true,
// success: function (ress) {
// if (ress.confirm) {
wx.requestSubscribeMessage({
// 调起消息订阅界面
// 永久 ETkJzRxc-wTKPKJJdeP-_3JvJr_F4aUPp8jVRga_KtA
// 一次性 rSELfotEiOJ_2GtKYxRHNoKdhnnwEEPt6cqGhsqqZzQ
tmplIds: ['ETkJzRxc-wTKPKJJdeP-_3JvJr_F4aUPp8jVRga_KtA'],
success(res) {
console.log('订阅消息 成功 ')
console.log(res)
// 用户同意的消息模板id
let moIdState = res['ETkJzRxc-wTKPKJJdeP-_3JvJr_F4aUPp8jVRga_KtA']
// Object res [TEMPLATE_ID]是动态的键,即模板id,值包括'accept'、'reject'、'ban'。
// 'accept'表示用户同意订阅该条id对应的模板消息,'reject'表示用户拒绝订阅该条id对应的模板消息,'ban'表示已被后台封禁。
if (moIdState === 'accept') {
// 用户同意总是保持是否推送消息的选择, 这里表示以后不会再拉起推送消息的授权
console.log('接受了消息推送')
} else if (moIdState === 'reject') {
console.log('拒绝消息推送')
} else if (moIdState === 'ban') {
console.log('已被后台封禁')
}
that.toMsgList()
},
fail(er) {
console.log('订阅消息 失败 ')
console.log(er)
if (res.errCode === 20004) {
wx.showModal({
title: '温馨提示',
content: '您已拒绝授权,将无法在微信中收到回复通知!',
showCancel: false,
success: (res) => {
if (res.confirm) {
that.toMsgList()
}
},
})
}
},
})
// }
// },
// })
} else {
// 用户同意总是保持是否推送消息的选择, 这里表示以后不会再拉起推送消息的授权
let moIdState = res.subscriptionsSetting.itemSettings['ETkJzRxc-wTKPKJJdeP-_3JvJr_F4aUPp8jVRga_KtA'] // 用户同意的消息模板id
if (moIdState === 'accept') {
console.log('接受了消息推送')
that.toMsgList()
} else if (moIdState === 'reject') {
console.log('拒绝消息推送')
wx.showModal({
title: '提示',
content: '检测到您没打开消息通知功能权限,是否去设置打开?',
success(res) {
if (res.confirm) {
console.log('用户点击确定')
wx.openSetting({
success: (res) => {
console.log(res)
},
})
} else if (res.cancel) {
console.log('用户点击取消')
// 拒绝跳转
that.toMsgList()
}
},
})
} else if (moIdState === 'ban') {
console.log('已被后台封禁')
}
}
} else {
console.log('订阅消息未开启')
}
},
fail: function (error) {
console.log(error)
},
})
},
注意事项
1、“总是保持以上选择,不再询问”
如果不勾选,用户每次触发订阅消息功能都会弹出授权窗口。
比如,你现在有两个订阅消息,第一个你勾选了不再询问,第二个没勾选,第二个下次点击还是会提示的,每个订阅消息是独立的。
如果用户勾选了订阅面板中的“总是保持以上选择,不再询问”时,模板消息会被添加到用户的小程序设置页,下次订阅调用 wx.requestSubscribeMessage 则不会出现弹窗,保持之前的选择。
需要通过 wx.getSetting 接口可获取用户对相关模板消息的订阅状态。
用户如果同意订阅这条消息之后,wx.requestSubscribeMessage后台还是会默认调用,只是没有弹出框了。比如你订阅了5次,就发5次,我测试是这样子的。
2、订阅消息目前分为「一次性订阅」和「永久订阅」
一次性订阅消息
用户订阅一次后,开发者可下发一条消息,不限时间。可以多个模版。
若用户勾选了“总是保持以上选择,不再询问”且点击了允许,那么以后都默认同意订阅这条消息。用户不再做多次选择,开发者也避免了更繁琐的提醒。
长期性订阅消息
用户订阅一次后,开发者可长期下发多条消息。
目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。
(长期订阅消息只针对特定行业开放,所以普通开发者并无法使用)
<view class="mask" bindtap="isAlert" data-type="1" catchtouchmove="stopEvent" wx:if="{{isShow}}">
<view class="alert" catchtap="stopEvent">
<view class="top-img">
<image src="../../assets/ling.png" mode="aspectFit" />
view>
<view class="title">
<text>订阅通知text>
view>
<view class="title-tip">
<text>订阅后您将获得以下事件状态的通知text>
view>
<view class="content">
<view class="list-item" wx:for="{{dataList}}" wx:key="index">
<view class="item-img">
<image src="../../assets/choose.png" mode="aspectFit" />
view>
<text>{{item.name}}text>
view>
view>
<view class="bottom">
<button bindtap="isAlert" data-type="2">取消button>
<button class="green" bindtap="subscribeAlert">我要订阅button>
view>
view>
view>
subscribeAlert.js
// components/subscribeAlert/subscribeAlert.js
const app = getApp()
const request = require('../../api/request.js')
Component({
/**
* 组件的属性列表
*/
properties: {},
/**
* 组件的初始数据
*/
data: {
isShow: false,
isTo: false, //是否有后续操作
state: false, //拒绝后是否需要弹窗
ids: '', //模版id
dataList: [
{
name: '诉求处理状态更新通知',
},
{
name: '关注事件办结通知',
},
{
name: '社区通知公告的推送',
},
],
},
created: function () {
this.getIds()
},
/**
* 组件的方法列表
*/
methods: {
// 之后去做的事情
toSubscribe() {
console.log('toSubscribe')
this.triggerEvent('toSubscribe')
},
// 阻止冒泡 阻止滑动
stopEvent() {
console.log('stopEvent')
return true
},
isShowSubscribe() {
// position fixed
this.triggerEvent('showSubscribe')
},
// 控制定位
isAlert(e) {
// 点击取消
if (e.target) {
e = e.target.dataset.type
}
console.log('isAlert', e)
// 父组件定位
if (e == 1) {
this.isShowSubscribe()
}
// 弹窗的取消按钮
if (e == 2) {
this.isShowSubscribe()
if (this.data.isTo) {
this.toSubscribe()
}
this.postChanel()
}
this.setData({
isShow: !this.data.isShow,
})
},
// 订阅消息授权
getSubscribeInfo(isTo) {
let that = this
// 这里是获取下发权限地方,根据官方文档,可以根据 wx.getSetting() 的 withSubscriptions 这个参数获取用户是否打开订阅消息总开关。后面我们需要获取用户是否同意总是同意消息推送。所以这里要给它设置为true 。
if (isTo) {
this.setData({
isTo: isTo,
})
}
wx.getSetting({
withSubscriptions: true, // 这里设置为true,下面才会返回mainSwitch
success: function (res) {
console.log(res)
// 调起授权界面弹窗
if (res.subscriptionsSetting.mainSwitch) {
// 用户打开了订阅消息总开关
if (!res.subscriptionsSetting.itemSettings) {
// 当用户没有点击 ’总是保持以上选择,不再询问‘ 按钮。那每次执到这都会拉起授权弹窗
// wx.showModal({
// title: '提示',
// content: '请授权开通服务通知',
// showCancel: true,
// success: function (ress) {
// if (ress.confirm) {
// type 1 组件显示/隐藏
if (that.data.state) {
that.isAlert(1)
} else {
if (that.data.isTo) that.toSubscribe()
}
// }
// },
// })
} else {
// 用户同意总是保持是否推送消息的选择, 这里表示以后不会再拉起推送消息的授权
let moIdState = res.subscriptionsSetting.itemSettings[that.data.ids] // 用户同意的消息模板id
if (moIdState === 'accept') {
console.log('接受了消息推送')
that.toSubscribe()
} else if (moIdState === 'reject') {
console.log('拒绝消息推送')
wx.showModal({
title: '提示',
content: '检测到您没打开消息通知功能权限,是否去设置打开?',
success(res) {
if (res.confirm) {
console.log('用户点击确定')
wx.openSetting({
success: (res) => {
console.log(res)
},
})
} else if (res.cancel) {
console.log('用户点击取消')
// 拒绝跳转
that.toSubscribe()
}
},
})
} else if (moIdState === 'ban') {
console.log('已被后台封禁')
}
}
} else {
console.log('订阅消息未开启')
}
},
fail: function (error) {
console.log(error)
},
})
},
subscribeAlert() {
let that = this
that.isAlert(1)
let ids = this.data.ids
wx.requestSubscribeMessage({
// 调起消息订阅界面
// 永久 ETkJzRxc-wTKPKJJdeP-_3JvJr_F4aUPp8jVRga_KtA
// 一次性 rSELfotEiOJ_2GtKYxRHNoKdhnnwEEPt6cqGhsqqZzQ
tmplIds: [ids],
success(res) {
console.log('订阅消息 成功 ')
console.log(res)
// 用户同意的消息模板id
let moIdState = res[ids]
// Object res [TEMPLATE_ID]是动态的键,即模板id,值包括'accept'、'reject'、'ban'。
// 'accept'表示用户同意订阅该条id对应的模板消息,'reject'表示用户拒绝订阅该条id对应的模板消息,'ban'表示已被后台封禁。
if (moIdState === 'accept') {
// 用户同意总是保持是否推送消息的选择, 这里表示以后不会再拉起推送消息的授权
console.log('接受了消息推送')
} else if (moIdState === 'reject') {
console.log('拒绝消息推送')
that.postChanel()
} else if (moIdState === 'ban') {
console.log('已被后台封禁')
}
that.toSubscribe()
},
fail(er) {
console.log('订阅消息 失败 ')
console.log(er)
if (er.errCode === 20004) {
wx.showModal({
title: '温馨提示',
content: '您已拒绝授权,将无法在微信中收到回复通知!',
showCancel: false,
success: (res) => {
if (res.confirm) {
that.toSubscribe()
}
},
})
}
},
})
},
// 获取模版ids
getIds() {
request
.get('wxapp/getTemplateId', {}, {})
.then((res) => {
if (res.retcode == 0) {
this.setData({
ids: res.templateId,
// 获取是否订阅提示
state: res.state,
// state: true,
})
}
})
.catch((e) => {
console.log('获取数据失败', e)
wx.showToast({
title: e,
icon: 'none',
})
})
},
// 选择取消
postChanel() {
request
.get('wxapp/rejectSubscribe', {}, {})
.then((res) => {
if (res.retcode == 0) {
this.setData({
state: false,
})
console.log('postChanel', this.data.state)
}
})
.catch((e) => {
console.log('获取数据失败', e)
wx.showToast({
title: e,
icon: 'none',
})
})
},
},
})
subscribeAlert.less
.mask {
width: 100%;
min-height: 100%;
background: rgba(0, 0, 0, 0.5);
overflow: hidden;
.alert {
width: 562rpx;
height: 569rpx;
background: #ffffff;
border-radius: 36rpx;
border: 1rpx solid #ffffff;
// filter: blur(8.489425981873111px);
margin: 200rpx auto 0;
image {
width: 100%;
height: 100%;
float: left;
}
.top-img {
width: 148rpx;
height: 148rpx;
margin: -74rpx auto 0;
}
.title {
font-size: 36rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
line-height: 34rpx;
text-align: center;
margin-top: 24rpx;
}
.title-tip {
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #5e6166;
line-height: 38rpx;
text-align: center;
margin-top: 24rpx;
}
.content {
width: 463rpx;
height: 168rpx;
padding: 20rpx;
background: rgba(220, 226, 230, 0.15);
border-radius: 8rpx;
margin: 24rpx auto 0;
.list-item {
line-height: 58rpx;
.item-img {
width: 30rpx;
height: 30rpx;
margin: 14rpx 24rpx 14rpx 11rpx;
float: left;
}
text {
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #5e6166;
}
}
}
.bottom {
display: flex;
margin-top: 24rpx;
button {
width: 222rpx;
height: 90rpx;
background: #f1f2f3;
border-radius: 45rpx;
font-size: 34rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #000000;
}
.green {
background: #04b971;
color: #ffffff;
}
}
}
}
调用
home.json
{
"usingComponents": {
"subscribeAlert":"../../components/subscribeAlert/subscribeAlert"
}
}
home.wxml
<subscribeAlert id="subscribeAlert" class="{{isShowSubscribe?'subscribeAlert':''}}" bind:showSubscribe="showSubscribe" bind:toSubscribe="clickInvite">subscribeAlert>
home.js
data: {
isShowSubscribe: false,
},
// 显示订阅消息弹窗
showSubscribe(e) {
// if (this.data.isShowSubscribe) {
// const child = this.selectComponent('.subscribeAlert')
// child.postChanel()
// }
this.setData({
isShowSubscribe: !this.data.isShowSubscribe,
})
},
// 订阅消息
getSubscribe(e) {
// 点击取消
if (e.target) {
e = e.target.dataset.type
}
// 调用子组件方法
const child = this.selectComponent('#subscribeAlert')
child.getSubscribeInfo(e)
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getSubscribe(false)
},
1.错误信息:
errMsg:“requestSubscribeMessage:fail can only be invoked by user TAP
gesture.”
解决:bindtap点击才行、不能延迟调用
2.错误信息:
errMsg:“requestSubscribeMessage:fail 开发者工具暂时不支持此 API 调试,请使用真机进行开发”
解决:真机调试才行
3.错误信息:
errCode: 20001 errMsg: “requestSubscribeMessage:fail No template data return, verify the template id exist”
解决:确认模板ID是订阅消息的模板ID且正确。
4.错误信息:
errCode:20003 errMsg:“requestSubscribeMessage:fail:Templates count out of max bounds”
解决:模版数量超出,最多3个
5.错误信息:
requestSubscribeMessage:fail last call has not ended
解决:如果申请的是“一次性订阅”,一次触发只有一次推送消息机会,所以我们会在其他页面点击事件去调用requestSubscribeMessage,获取更多次的推送消息机会。但是每个手机获取是有上限的,大概几十个吧。然后只有用掉推送消息次数,才能重新成功调用,否则会出现以上问题。
6.错误信息:
requestSubscribeMessage:fail can only be invoked by user TAP gesture
解决:表单提交,在高版本微信是没有问题的,但是在低版本无法调用订阅消息,低版本订阅消息api必须在点击事件中触发,需将form提交改为bindtap提交,一般可做成显示一个弹框友好的提示用户,然后再让用户点击按钮去手动触发订阅
注意-坑:
1.bindtap点击才可以调起
2.真机调试才行(–2020/01/03:貌似微信开发者工具也可以调用了)
3.不能延迟去调用wx.requestSubscribeMessage,如先调用其他接口请求成功再去它、使用定时器延迟调用
参考:
小程序订阅消息
小程序端消息订阅接口 wx.requestSubscribeMessage
小程序模板消息能力调整通知
针对新手很容易出现理解误区的微信小程序订阅消息模块
微信小程序订阅消息授权选择总是接收订阅消息,成功发送订阅消息一次过后,后续发送都返回43101错误?