首先这个下发订阅消息,是可以后端处理的;因此关于后端的操作,我就不讲了,后端定时触发这个下发操作可以通过定时器执行(后端处理相对简单灵活)。但这里我们主要说云函数如何实现这个定操
「小程序·云开发」不仅支持通过云调用免 access_token
发送订阅消息,而且支持在 定时触发器 中实现云调用,因此我们可以使用这个切入口来实现我们得定时触发需求~
先写好授权订阅操作相关代码(有关授权操作细节可以看 微信小程序订阅消息及遇到的种种坑解决方法(全))
myCourse.wxml
在 “订阅课程提醒” 的按钮上绑定 tap 事件,点击触发授权操作
<button
data-info="{{ coueseInfo }}"
bindtap="courseSubscribe"
>
订阅课程提醒
button>
myCourse.js
在
courseSubscribe
函数内,调用微信 APIwx.requestSubscribeMessage
申请发送订阅消息权限,当用户在弹窗同意订阅之后,我们会收到success
回调,触发云函数addCourseMsg
并传递课程信息及模板ID写入库中
PS:这边的传值中课程信息是为了待会下发模板需要展示的一些信息
const SUBSCRIBE_ID = 'xxxxxxxxxxxxxxxx' // 下发的模板ID
courseSubscribe: function(e) {
// 获取课程相关信息
let coueseInfo = e.currentTarget.dataset.info;
wx.requestSubscribeMessage({
tmplIds: [SUBSCRIBE_ID],
success(res) {
if (res[SUBSCRIBE_ID] === 'accept') {
// 调用云函数subscribe
wx.cloud
.callFunction({
name: 'addCourseMsg',
data: {
data: coueseInfo,
templateId: SUBSCRIBE_ID,
},
})
.then(() => {
wx.showToast({
title: '订阅成功,我们将在xxx时间提醒您开课',
icon: 'success'
});
})
.catch(() => {
// dothing...
});
}
},
});
}
需要定时触发,势必要先对数据进行储存,然后需要的时候读取使用,所以我们要写个写库的函数及后面的增改查。
除此之外,云函数还要部署等…
将课程相关信息存入云开发数据库
首先创建一个云函数
addCourseMsg
,这个云函数的作用是将用户的订阅信息存入云开发数据库的集合course-message
中
在微信开发者工具的云开发面板中创建数据库集合 course-message
cloudfunctions/addCourseMsg/index.js
该云函数写写入数据到
course-message
集合中
const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();
exports.main = async (event, context) => {
// 向 course-message 集合库中写入相关数据
try {
const { OPENID } = cloud.getWXContext();
const result = await db.collection('course-message').add({
data: {
touser: OPENID, // 订阅者的openid
page: 'index', // 订阅消息卡片点击后会打开小程序的哪个页面,注意这里的界面是线下小程序有的,否则跳不过去
data: event.data, // 订阅消息的数据(课程信息)
templateId: event.templateId, // 订阅消息模板ID
isSend: false, // 消息发送状态设置为 false
},
});
return result;
} catch (err) {
console.log(err);
return err;
}
};
记得右键上传并部署(不上传node_modules)
如有不明白看文档 云开发 – 定时触发器
这个云函数就是查改库,对需要发送的订阅消息进行下发订阅
接下来我们需要实现一个定时执行的云函数 ,来检查数据库中是否有需要发送给用户的订阅消息
需要下发订阅的通过云调用 cloud.openapi.subscribeMessage.send
将订阅消息发送给用户
创建一个名叫 sendCourseSubscribe
的云函数,首先要配置云函数,在 config.json
的 permissions
中新增 subscribeMessage.send
的云调用权限,然后新增一个 sendCourseTimer
的定时触发器,定时触发器的语法和 linux 的 crontab
类似,比如,我们配置的 "0 * * * * * *"
代表每分钟执行一次云函数。
{
"permissions": {
"openapi": ["subscribeMessage.send"]
},
"triggers": [
{
"name": "sendCourseTimer",
"type": "timer",
"config": "0 * * * * * *"
}
]
}
config
里面的配置自行查文档进行设置,我就举个栗子:比如该课程在2021年04月25 早上7点整 发给用户(0 0 7 25 4 0 2021)
注意:
① 一次授权只有一次下发,所以不要搞个轮询定时触发,因为你只有一次,即使触发下发也不会发给用户,除非你用的是永久订阅的模板可以使用,而单单处理那种特定天数的话,写具体时间对应config
值即可
② 需要使用cloud.openapi.subscribeMessage.send
进行下发订阅消息,所以也要对应配置一下云函数的调用权限
上面配置好定时器后,我们来写云函数的逻辑:大概步骤就是循环消息列表,过滤出未发送的消息数据 (isSend: false),依次发送每条订阅消息,发送成功后将数据库中消息的状态改为已发送(isSend: true),这里只是简化了筛选条件,具体业务肯定还要其他条件
cloudfunctions/sendCourseSubscribe/index.js
const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();
exports.main = async (event, context) => {
try {
// 从云开发数据库中查询等待发送的消息列表
const messages = await db
.collection('course-message')
.where({
isSend: false,
})
.get();
// 循环消息列表依次处理下发订阅操作
const sendPromises = messages.data.map(async message => {
try {
// 发送订阅消息
await cloud.openapi.subscribeMessage.send({
touser: message.touser,
page: message.page,
data: message.data,
templateId: message.templateId,
});
// 发送成功后将消息的状态改为已发送
return db
.collection('course-message')
.doc(message._id)
.update({
data: {
isSend: true,
},
});
} catch (e) {
return e;
}
});
return Promise.all(sendPromises);
} catch (err) {
console.log(err);
return err;
}
};
大概就是上面这样,如何通过云函数实现一个定时下发订阅消息给用户的操作,文中如有错误可以指出,希望能帮到你~