微信小程序订阅消息使用
官方文档连接
本说明的使用场景例子为:用户在组队大厅发送招募信息,后台管理系统收到后对用户的信息进行审核,并将审核结果,通过消息推送发送给用户。
逻辑步骤
逻辑步骤0:等待用户点击触发需要发送消息的事件
逻辑步骤1:向用户申请获得发送消息的权限
逻辑步骤2:等待发送的触发行为
逻辑步骤3:向特定用户发送消息
操作步骤
操作步骤1:在微信公众号平台获得合适的模板
在公共模板库搜索适合的模板,找不到的话可以申请。
操作步骤2:编写查询发送权限函数
写一个获得访问权限的函数(也可以直接复制我的),封装好API里面,后面还需要用的话方便调用。
const checkSub = async(params)=>{//传入tmplId,检测用户是否开放权限,允许推送消息
var tmplIds = params.tmplIds //这里的tmplId是一个数组得注意一下
console.log(tmplIds)
return new Promise((resolve,reject)=>{
wx.getSetting({
withSubscriptions: true,
success(res){
console.log(res)
if(res.subscriptionsSetting.itemSettings!=undefined){
var flag = res.subscriptionsSetting.itemSettings[tmplIds[0]]
}else{
var flag = undefined
}
console.log(flag)
if(flag==undefined){
console.log("debug")
wx.requestSubscribeMessage({
tmplIds: tmplIds,
success(res){
console.log(res)
//点击完成后就返回成功就行
},
})
}else if(flag!='accept'){
wx.requestSubscribeMessage({
tmplIds: tmplIds,
success(res){
console.log(res)
resolve(true)//点击完成后就返回成功就行
}
})
}else{//直接返回true,原本以为用户选择一直同意之后,就可以一直推送,这里是一个bug
wx.requestSubscribeMessage({
tmplIds: tmplIds,
success(res){
console.log(res)
resolve(true)//点击完成后就返回成功就行
}
})
}
}
})
})
}
操作步骤3:用户触发点击事件,调起询问权限
在用户触发的事件开始前,调用询问权限函数,获得发送订阅消息的权限
在本例子中,用户提交组队的表单,在成功提交前,询问用户是否接受“审核通过通知”,无论用户选择是或否,表单信息都可以顺利提交。但是选择否,用户则无法顺利收到订阅信息。
代码如下
submit: async function() {
if(!this.checkTap()){ //防止用户多次点击,重复提交的函数
return 0
}
const { contestName,imgs,mates,status,currNum } = this.data
var imgUrls = [];
for (var i=0; i<imgs.length; i++) {
imgUrls.push(imgs[i].url);
}//提交数据的图片连接
var tmplIds = ['复制你的templId进来']//审核通过通知权限
var param = {tmplIds}
api.subscription.checkSub(param).then(res=>{//在这里调用检查函数
var params = {imgs: imgUrls,contestName,mates,status,currNum}
api.team.publish(params).then(res=>{ //提交表单的函数
//提交成功
})
})
}
PS:好了,现在用户点击了"是"之后,我们就可以向用户推送消息了,但是机会只有一次 ! 要好好把握 !
操作步骤4: 编写发出推送的函数
这里我们使用云函数,可以很方便的使用, 将不同的模板封装在同一个函数里面,使用哪个就调用哪个.
下面是我的代码
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database();
const _ = db.command
exports.main = async (event, context) => {
switch(event.action) { //通过传入的参数 action 来选择模板,其他模板为了方便阅读我删掉了,直接复制一下就搞自己的模板啦
case 'send1' :return send3(event)//审核模板通过模板
}
}
async function send1(event){
const {touser,status} = event.data //touser 是发送给用户的openid
now_db = formatDate2(event.data.now_db)
createTime = formatDate2(event.data.createTime) //待审核信息的创建时间
try{//这部分data的内容,和微信公众平台上的模板相对应
var data = {
thing2: {
value: "您发布的信息已审核"
},
phrase1: {
value:status//通过或拒绝
},
date3:{
value:now_db//现在的时间
},
date4:{
value:createTime //消息创建的时间
}
}
const result =await cloud.openapi.subscribeMessage.send({ // 此处发送
touser:touser,
page: 'pages/user/index/index', //用户点击消息后进入程序的页面
data: data,
templateId: '这里复制你的templateId',
miniprogramState: 'developer' // 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
});
return result
} catch(err){
return err
}
}
function formatDate2 (time) {//时间处理函数
const date = new Date(time);
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hour = date.getHours();
const minute = date.getMinutes();
return year + '年' + [month, day].map(formatNumber).join('月') + '日 ' + [hour, minute].map(formatNumber).join(':');
}
function formatNumber(n) {
n = n.toString();
return n[1] ? n : '0' + n;
}
操作步骤5:向用户推送消息的时间到,发出推送
就是,我们设定的推送时间,或者其他用户触发了向用户发送给推送消息的事,那么就是现在,发出推送.
这个例子中,就是管理员进行了操作,将用户的组队信息状态,从"wait"等待审核,变成了"accept",通过审核.状态发生改变的同时,我们向用户发出推送.
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database()
const _ = db.command
const $ = db.command.aggregate
// 云函数入口函数
exports.main = async (event, context) => {
switch (event.action) {//通过传入action参数选择函数
case 'changeStatus': return changeStatus(event)
default: return Promise.reject("unknown action")
}
}
async function changeStatus(event){//管理员改变信息的状态
var {teamID,touser,status} = event
var mp = {'reject':'拒绝','need':'通过'}//通过mp将英文转换为中文
var status2 = mp[status]
var time = new Date()
var createTime = event.createTime
console.log(createTime)
return new Promise((reslove,reject)=>{
db.collection('team').doc(teamID)
.update({
data:{
status:status //更新信息状态
}
})
.then(res=>{//成功之后发送订阅消息
cloud.callFunction({
name:'subscribe',
data:{
action:"send3",
data:{status:status2,touser:touser,now_db:time,createTime:createTime}
}//这里的数据都需要和模板中的数据对应,touser就是发送给目标用户的openid
}).then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)
})
reslove({code:200,message:"转换成功",data:res})
})
.catch(err=>{
reject({code:300,message:"转换失败",data:err})
})
})
}
测试
这里因为开发者工具和真机调试弹出来的页面有所不同,所以推荐最好是使用真机进行调试.
用户点击允许之后,再触发发送函数,就可以收到消息了,一开始可以用自己的openid作为touser,来进行测试.
!!!这里注意!!!
如果用户选择了"总是保持以上选择,不在询问",那么以后都不会调起这个界面,但是用户点击一次允许,我们才获得一次发送订阅消息的能力.所以这里会有一个BUG,目前还没有找到解决的方案.只能希望用户不选择这个了.
那么就到这里结束了,有什么问题欢迎留言交流,欢迎点赞关注收藏…好耶!
总结得很全面,支持
我的小程序是这么处理需要多次通知用户的。单独有一个订阅按钮,并告诉用户如需多次收到通知请多次点击订阅,就可以了。选中保持以上选择不再询问后,如果是允许,后续点击时会自动允许,如果是不允许,可调用wx.goSetting让用户自己进入通知管理中允许订阅消息。
1