云原生微信小程序开发实战读书笔记-4
站在小程序的角度上,订阅消息最普遍的应用场景有两种,一种是被动的,一种是主动的。
被动的订阅消息指: 消息的发送需要用户的某些行为作为触发,然后小程序再针对性地向用户发送消息反馈。以电商类小程序为例,当用户支付成功之后,小程序会向用户推送一条消息,用户可以通过这条消息跟踪订单进度。
主动的订阅消息是指: 小程序可以定期或不定期地向用户发送消息通知,不需要用户的某些行为作为触发点。比如学习类小程序在每天的固定时间向用户发送消息,通知用户打卡。
在被动场景下,小程序会对用户的行为及时反馈,从而提升用户的产品体验,以及对小程序的认可度、依赖度。在主动场景下,小程序可以通过定期或不定期地发送通知,把离开的用户拉回来继续使用小程序。所以,这两种场景下的订阅消息都能帮小程序提高用户的留存率。
订阅消息属于微信提供的开放接口之一,调用有两种方式:
- 传统的调用方式,掌握这种方式后,你会明白订阅消息完整链路的基本原理;
- 云调用方式,教你用免鉴权的方式快速实现订阅消息的调用,提高研发效率。
订阅消息完整的流程可以简单概况成下面这张图:
- 在发送消息之前必须获得用户授权,这是第一步也最基本的一步。
- 用户授权之后,你需要把授权信息记录下来,因为小程序的订阅消息能定义多种类型,每种都需要得到用户的授权后才可以发送。
- 消息的发送需要一个触发点,根据订阅消息的两种应用场景,触发点可以是用户的某个行为比如支付订单,也可以是小程序主动触发,比如定时发送。
这三个步骤是小程序订阅消息的基本流程。
配置消息模板
小程序的订阅消息分为:一次性订阅消息和长期订阅消息。
- 一次性你可以简单理解成得到用户的授权之后只能发送一条消息,如果再有发送需求还要再次申请用户的授权。
- 长期订阅消息可以得到用户授权后发送多条消息。不过目前长期订阅消息只向政务民生、医疗、交通、金融、教育等线下公共服务开放(后面也许会开放出更多领域)。
配置完消息模板之后会拿到一个模板ID。
获取用户授权
小程序SDK提供了一个用来获取用户授权的API:wx.requestSubscribeMessage。你要用这个 API 为每一个模板 ID 授权,调用方式如下:
wx.requestSubscribeMessage({
tmplIds: ['tmplId_1','tmplId_2','tmplId_3'],
success (res) {
console.log(res)
/ **
{
errMsg: 'requestSubscribeMessage:ok',
tmplId_1: 'accept',
tmplId_2: 'reject',
tmplId_3: 'ban'
}
*/
}
})
其中参数 tmplIds 是一个数组,数组中的每个元素就是前面配置的消息模板 ID ,如果你需要一次性获取多个模板的用户授权就在 tmplIds 数组里写入多个元素。调用wx.requestSubscribeMessage 之后,用户会在小程序端收到一个弹窗:
用户可以对列表中的每个消息模板分别授权,也可以全部勾选(也就是全部授权)。用户点击“允许”按钮之后,将会触发 wx.requestSubscribeMessage 的 success 回调函数,返回的数据结构可以参考上面的示例代码,每个模板 ID 都有一个状态标识,accept 代表得到授权、reject 代表未获得授权、ban 代表被后台封禁。当然,正常情况下是不会出现 ban 状态的,除非你的订阅消息涉嫌骚扰用户或内容违禁。
流程如图:
发送消息的传统调用方式
调用微信开放接口需要临时凭证 access_token,发送订阅消息的接口作为微信开放接口的一员同样要遵循这条规则。
服务端需要调用微信提供的subscribeMessage.send接口向用户发送订阅消息,这个接口有几个请求参数需要你特别关注:
其中 template_id 是上一步得到用户授权的几个模板 ID 中的一个,请注意,你每次调用 subscribeMessage.send 接口只能发送一条消息给用户,而不能同时发送多条,这是微信的限制。touser 参数的值是接收消息的用户 openId,access_token 是临时凭证。
发送消息需要一个触发点(可以是用户的某个行为触发,也可以是服务端的定时任务,具体采用哪种方式需要根据业务场景来决定),以定时任务这种场景为例,对照下图讲解一下完整的发送消息流程:**
- 首先,服务器需要设定一个定时任务,比如每天 9 点触发一次,发送消息。
- 触发之后,第一步先检查本地缓存中是否存在有效期之内的 access_token ,如果不存在就需要重新请求微信的服务获取一个新的。
- 拿到有效的 access_token 之后,第二步是通过 subscribeMessage.send 接口向微信服务器发送一个请求。
- 微信服务器收到请求之后,发送一条订阅消息给指定的 openId 对应的用户,便完成了整个发送消息的流程
以上就是发送订阅消息的传统调用方式。你也看到了,在这套流程中,需要比较繁重的服务端开发工作,比如设定定时任务、缓存管理等,非常的麻烦。
发送消息的云调用方式
微信小程序的订阅消息功能提供了云调用的支持,你可以不用关注鉴权,也就是不需要关注 access_token,直接在云函数里调用微信 SDK 提供的openapi.subscribeMessage.sendAPI 就行,参数跟 subscribeMessage.send 接口一样,只是不再需要 access_token 了。
const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async (event, context) => {
try {
const result = await cloud.openapi.subscribeMessage.send({
touser: 'OPENID',
templateId: 'TEMPLATE_ID',
// ...其他参数
})
return result
} catch (err) {
return err
}
}
除了避免管理 access_token 的麻烦以外,在前面传统调用方式中还用到了一项能力:定时任务。这项需求云函数同样可以满足,你可以给云函数配置一个定时触发器,使用简单的 JSON 配置文件就可以设定一个定时任务。比如我刚刚说的每天 9 点触发一次就可以写成下面这种格式的云函数定时触发器:
{
// triggers 字段是触发器数组,目前仅支持一个触发器,即数组只能填写一个,不可添加多个
"triggers": [
{
// name: 触发器的名字,规则见下方说明
"name": "myTrigger",
// type: 触发器类型,目前仅支持 timer (即 定时触发器)
"type": "timer",
// config: 触发器配置,在定时触发器下,config 格式为 cron 表达式,规则见下方说明
"config": "0 0 9/23 1/1 * * *"
}
]
}
通过上面两个步骤就完成了跟传统调用方式一样的功能,而整个发送消息的流程也得到了简化:
对比这两种调用方式,你应该能够明显感受到不同。当然,这并不是说我们只学会用云调用而不用学习传统方式了。云调用的底层也是类似传统的调用方式,只不过帮你完成了定时任务、缓存管理这些服务端的开发工作而已。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!