1. 什么是小程序订阅消息
用户在小程序页面点击按钮,确认订阅消息,小程序可以按照消息模板格式在后续的任意时间发送消息给用户。
小程序订阅消息分两种:
一种是一次性订阅,一般都可以使用该服务,缺点就是用户订阅一次,小程序才能发送一次消息。
另一种是长期订阅,比较难,需要申请,只针对特定几个行业或分类的小程序。
2. 实现步骤(示例:一次性订阅)
1)在官网的小程序管理页面申请订阅消息
你会得到:模板ID,详细内容数据格等信息。
2)page.wxml 做个按钮,让用户订阅消息
<button type="primary" bindtap="onSubscribe">订阅次日训练通知</button>
3)page.js 中调用 wx.requestSubscribeMessage 获取用户订阅
onSubscribe: function (e) {
var that = this
let page = this.data.page
let noticeData = {"thing1": {"value": this.data.noticeTitle},"thing2": {"value": this.data.noticeContent}}
let templateId = '......' // 敏感信息省略,请用自己的模板ID
wx.requestSubscribeMessage({
tmplIds: [templateId],
success (res) {
// 申请订阅成功,将订阅信息调用云函数存入云开发数据
if (res.errMsg === 'requestSubscribeMessage:ok') {
// res[templateId]: 'accept'、'reject'、'ban'、'filter'
if(res[templateId] == 'accept') {
that.saveSubscribeInfo(page, noticeData, templateId)
}
}
}
})
},
注意 noticeData 的数据格式
4)再将用户订阅的信息保存到云数据库中
// 保存订阅信息
saveSubscribeInfo(page, noticeData, templateId) {
// 调用云函数
wx.cloud.callFunction({
name: 'v4_subscriber',
data: {
action: 'saveSubscribeInfo',
page: page,
data: noticeData,
templateId: templateId,
},
success: res => {
console.warn('[云函数] [v4_subsriber] saveSubscribeInfo 调用成功:', res)
wx.showToast({
icon: 'none',
title: '订阅成功',
})
},
fail: err => {
console.error('[云函数] [v4_subsriber] saveSubscribeInfo 调用失败:', err)
},
complete: () => {
}
})
},
云函数中的保存订阅消息代码
async function saveSubscribeInfo(openid, event) {
try {
return await db.collection('v4_trainingnotice').add({
data: {
touser: openid, // 发送对象
page: event.page, // 订阅消息卡片点击后会打开小程序的哪个页面
data: event.data, // 订阅消息的数据
templateId: event.templateId, // 订阅消息模板ID
done: false, // 消息发送状态设置为 false-未发送,true-已发送
createDate: new Date(), // 创建时间
}
})
} catch (e) {
console.error(e)
}
}
5)再创建一个send云函数
功能:从云数据库中获取待发送的消息,逐个发送给订阅消息的用户
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
traceUser: true,
env: '......' // 敏感信息省略,请用自己的云环境
})
const db = cloud.database()
const _ = db.command
// 云函数入口函数
exports.main = async (event, context) => {
try {
// 从云开发数据库中查询等待发送的消息列表
const messages = await db
.collection('v4_trainingnotice')
// 查询条件这里做了简化,只查找了状态为未发送的消息
.where({
done: 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('v4_trainingnotice')
.doc(message._id)
.update({
data: {
done: true,
updateDate: new Date(),
},
});
} catch (e) {
return e;
}
});
return Promise.all(sendPromises);
} catch (err) {
console.log(err);
return err;
}
}
6)send云函数自己怎么自动执行呢?答案:定义触发器
云函数的 config.json 文件中定义触发器
{
"permissions": {
"openapi": ["subscribeMessage.send"]
},
"triggers": [
{
"name": "sendMessagerTimer",
"type": "timer",
"config": "0 30 21 * * * *"
}
]
}
代码表示再每天的21点30分0秒,调用send云函数。
用户就可以收到订阅的消息啦!