Master student @ Fudan University
wxxshirley / wxxshirley.github.io Goto Github PK
View Code? Open in Web Editor NEW个人主页
Home Page: https://wxxshirley.github.io
个人主页
Home Page: https://wxxshirley.github.io
继续上一篇,在餐饮服务类小程序中,向用户发送订阅号消息是一个非常基本的需求。这里我们介绍用户下单后发送下单成功和商家做好后发送取餐提示的消息。
首先需要在微信公众平台创建订阅消息,具体在功能->订阅消息
中。点击选用即可根据自己的需求创建一个新的模版。选择自己需要发送的内容信息即可。
下图是我们添加的点餐成功的模版。这里向用户发送订单号、取餐号、点餐内容和时间信息。注意右侧的详细内容构成,之后我们发送消息需要严格遵守其命名规范规则。
var data = {
character_string1:{value:"对应的订单号"},
thing2:{value:"点餐内容"},
character_string3:{value:"取餐号码"},
time4:{value:"点餐时间"}
}
其实我们要发送的总共是三类消息:
这里我们仅介绍指定用户的。整体的时序过程是:用户下单,如果是首次会弹出接受订阅消息,都勾选了后会:
createOrder
,执行对订单数据库的插入操作subscribe
云函数存储该下单消息。具体来说,往Message
表中存储需要发送的下单成功消息内容。之后前端下单成功会界面重定向到该笔订单的界面wx.redirectTo
。我们会有一个定时的云函数,每隔一分钟轮询Message
表中尚未被发送的消息,发送给指定的用户。这样该用户即在下单的1分钟内收到下单成功消息推送。
新的下单信息也会推送给商家(可以在createOrder
中把一个新下单消息、即指定发送给管理员的写入Message
表中,需要提前在获得权限时使管理员勾选该类消息)。商家完成订单后在CMS后台修改该订单状态为已完成,会触发userCheckoutNotice
(Webhook模式)将取餐内容推送给该用户。也是依靠轮询Message
机制,用户将在1分钟内接收到消息。
var tmpId = "" // 下单模版ID
var checkoutId = "" // 取餐模版ID,都在微信公众平台
// 申请订阅消息权限
wx.requestSubscribeMessage({
tmplIds: [tmpId, checkoutId], // ID集合
success(res){
// 用户勾选后
if(res.errMsg == 'requestSubscribeMessage:ok'){
wx.cloud.callFunction({
name: 'subscribe', // 调用subscribe云函数,存储“下单”订阅消息
// 遵守模版格式,订单号、名称、取餐号、时间
data:{
data: {
character_string1: {
value: "订单号",
},
thing2: {
value: title,
},
character_string3:{
value: "取餐号码",
},
time4:{
value:utils.formatTime(new Date()),
}
},
// 这里对应下单成功的消息提示,因此传入的templateId是下单成功的模版ID
templateId: tmpId
}
}).then(()=>{
console.log("订阅成功")
})
}
}
})
Message
表设计与定时机制我们设计Message
表来存储所有需要发送给用户的消息,其中关键字done
为布尔型,用以标志消息是否已经被发送。
下图是Message
表中一条记录的展示。
openid
其中关键是templateId
, touser
, data
构成了要发送的内容数据。
考虑编写一个定时云函数send
,每隔1分钟扫描Message
表,将未发送的数据发送给指定的用户。
config.json
由于我们要使用定时功能和发送订阅消息,需要先配置config.json
. 其中triggers
定义了定时模式,与Linux中cron定时机制类似,其中0 * * * * * *
指明每隔1min执行1次。
{
"permissions": {
"openapi": [
"subscribeMessage.send"
]
},
"triggers":[
{
"name":"sendMessageTimer",
"type": "timer",
"config": "0 * * * * * *"
}
]
}
send
云函数:遍历Message
表发送未发送数据// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({env: '开发环境'})
const db = cloud.database()
const _ = db.command
// 云函数入口函数
exports.main = async (event, context) => {
try{
// 查询尚未发送的消息
const messages = await db.collection('Message').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("Message").doc(message._id).update({
data: {done: true}
});
}catch(e){
console.log("发送消息出现错误")
console.log(e)
return e;
}
})
return Promise.all(sendPromises)
}catch(err){
console.log("Try catch外部发送消息错误")
console.log(err)
return err
}
}
userCheckOutNotice
商家修改了某订单为完成,可以根据webhook
中的过滤条件取到该笔订单和对应用户。向Message
表中存储该取餐成功消息,包括:
同样地借助Message
表的轮询机制成功地发送给用户
本文介绍了处理发送订阅消息的一般流程:
但是在本次应用中,由于发送消息的多样性,我们把消息的发送变为轮询定时任务。将上述的最后两步变为插入Message
表和轮询发送消息。
今年寒假做了一个小程序点餐的外包项目,最近闲下来逐个对里面的技术点进行复盘和总结。
对于订餐类的应用,需要有一个完备的后台系统,基础功能包括显示完整的商品信息、订单信息;另外需要有实时新订单提示、修改订单为已完成等功能。
由于全程采用微信小程序云开发,对商家来说登陆微信小程序开发IDE查看数据显然不太现实,需要搭建一个基础的后台。
微信小程序的云开发提供了使用HTTP接口访问云端数据库的功能。对任何云数据库的操作,包括两部分:
access_token
var queryParams = { grant_type: client_credential,
appid: 微信小程序的APPID,
secret: 微信小程序的APPSECRET(以上可登陆微信公众平台-开发-开发设置中查看)};
access_token
有效期为两小时,但是它提供了平滑期,即已有access_token
有效的情况下,再次请求,旧的在五分钟内有效。access_token
,请求数据
var queryParams = {
"env":"对应微信小程序云开发的环境",
"query": "db.collection('Order').where({time: db.RegExp({regexp:'2021/03/17'})}).get()"
// 查询语句,上面查询了该日的订单信息
}
根据上面的API可以查询任何我们想要的云数据库的信息,在此基础上可以搭建一个后台。不过的确也非常麻烦(个人觉得一大麻烦就是在于每一次至多返回10条数据,分页策略请求很容易造成重复数据,需要有略复杂的处理手段;另外,实时消息提示和在后台修改状态后回调小程序端也困难重重。),还不如放弃小程序的云开发自建一个服务端.....
CMS是腾讯云提供的一站式后台管理服务,目前已经适配微信小程序云开发。
如果使用,需要在云开发控制台->更多->内容管理
手动开启。之后会提供一个该小程序的后台内容管理网址,在此基础上可以定制打造需要的后台管理服务。
下面是进入到这个后台管理的界面。
我们先介绍左侧的各个工具栏。
Cart
表,我们想在后台显示每一条记录的商品名、加入时间、用户的openid和数量,那么选择右侧对应的、填写数据库字段名即可。之后云数据库的内容会直接同步到内容集合中展示。这里的内容和云数据库同步,包括插入/删除/更新。在订单小程序中,有个需求是咖啡厅人员把某个订单从进行中改成了已完成,这个时候我们需要推送给用户取餐通知。这个大家在使用喜茶/乐乐茶都有体验。这个需求的实现就需要使用Webhook。
创建一个Webhook,是监听到CMS中数据项发生变化(包括数据插入、删除和更新后),触发外部回掉。目前支持HTTP和触发云函数。这里我们仅示例触发云函数。
下面是增加一个Webhook的填写表单。
这里我们想要监听订单表Order
中数据项更新,触发一个名为userCheckoutNotice
的云函数。
在小程序cloudfunctions
路径下,我们新建一个名为userCheckoutNotice
的云函数,可以先只打印该函数入口的内容event
, 然后我们在CMS系统中手动更新某笔订单,查看触发userCheckoutNotice
云函数中的事件信息。
下面是打印的event
内容
可以看到,event
本身封装了非常多的因素,其中最关键的是actionFilter
,即数据过滤条件,指定了本次我们更新的是哪一条数据。我们可以通过取actionFilter
, 找到该条数据项、顺理成章地得到该订单对应的用户的openid, 向她/他发送取餐消息即可。
最后是发送消息的核心代码。
这里由于有多类消息需要发送给用户:
Message
表中,每隔一分钟将该表中尚未发送的消息发送给指定的用户、并更新状态为已发送。具体发送消息的设计会在下一篇中介绍。// 云函数入口函数
exports.main = async (event, context) => {
// 用户取餐提示
console.log("触发用户取餐提示")
// 数据库过滤条件
var filterId = event.actionFilter._id
// 获取该笔订单数据
var entry = await db.collection('Order').doc(filterId).get()
console.log("查找到对应数据:")
console.log(entry)
if(entry && entry.data){
// title格式 e.g "美式咖啡,普通咖啡" string格式
let title = ""
... // 生成取餐标题
// 构造发送消息的内容 - 需要和微信公众平台订阅消息模版保持一致
var data = {
character_string1:{
value: entry.data.order_id , // 订单号
},
thing5:{
value: title // 商品详情
},
character_string4:{
value: entry.data.order_id // 取餐号
}
}
// 插入到Message表中,等待轮询被发送
try{
const result = await db.collection('Message').add({
data: {
touser: entry.data.openid, // 发送用户的openid
page: "myOrder", // 用户打开该消息进入小程序后进行的界面,这里进入订单界面
data: data,
templateId: "", // 对应的内容模版ID, 在微信公众平台
done: false, // 是否发送
}
});
return result
}catch(err){
console.log("插入到取餐提示消息失败:")
console.log(err)
}
}
}
总的来说,微信小程序的云开发功能愈发完善。使用它完成一个全栈开发非常容易,CMS的提供使得后台管理系统也非常轻松。Webhook功能更帮助我们实现了进一步的需求。希望明年这个时候能看到CMS系统直接集成观远数据平台/智能BI,直接一站式可视化所有数据、甚至一些NLP的工具也能使用🤣
以上就是关于我用到的CMS系统的内容。如有更新会即时补充。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.