我在小程序的【每日一题】中新增了订阅功能,这篇文章就来讲讲设计及开发过程中遇到的坑。
什么是订阅消息
消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验。
订阅消息推送位置:服务通知
订阅消息下发条件:用户自主订阅
订阅消息卡片跳转能力:点击查看详情可跳转至该小程序的页面
订阅消息包括两种:
一次性订阅消息
一次性订阅消息用于解决用户使用小程序后,后续服务环节的通知问题。用户自主订阅后,开发者可不限时间地下发一条对应的服务消息;每条消息可单独订阅或退订。
长期订阅消息
一次性订阅消息可满足小程序的大部分服务场景需求,但线下公共服务领域存在一次性订阅无法满足的场景,如航班延误,需根据航班实时动态来多次发送消息提醒。为便于服务,我们提供了长期性订阅消息,用户订阅一次后,开发者可长期下发多条消息。
目前长期性订阅消息仅向政务民生、医疗
、交通
、金融
、教育
等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。
开始开发
首先要明白一点,当用户订阅【每日一题】后,并不是马上发送订阅消息。用户订阅的目的是,当下次发布题目时,可以提醒用户去答题。因此需要建一个数据库表,把订阅的用户信息存起来。于是就建了一个非常简单的表,只需要保存订阅用户的 openid
即可。
然后想到以后万一其他地方有新的订阅功能时,岂不是又要新建表?
为了更好的扩展性,于是增加了一个字段,叫做 template_id
,用来存订阅模板的ID。这样所有的订阅都可以只用这一个表解决。
首次测试
在页面中订阅消息,然后可以在任意时间通过服务端发送消息。
在微信的“服务通知”中成功收到消息,NICE!
于是迫不及待的又调用了一次,结果报错了,字面意思很容易理解,“用户拒绝接受消息”
{
errcode: 43101,
errmsg: 'user refuse to accept the msg rid: 601cebc4-6c7fee57-1d276794'
}
定位问题
在上面提到了有两种订阅消息,我是用的是一次性订阅消息,在描述中有一句话很关键:开发者可不限时间地下发一条
对应的服务消息。
也就是说用户订阅后只能发送一条服务消息,如果需要再次发送,那么需要用户重新订阅。经过测试,如果用户订阅了一次后,在服务端发送消息前,用户再次订阅了一次,那么此时服务端可以向用户发送两条服务消息。也就是说用户订阅的次数是可以累加的。
那之前设计的数据库表就有很大的问题,现在无法判断是否还可以向每个用户发送消息,有可能之前已经发送过了,如果对每个用户都尝试发送,那会产生很多不必要的请求。
改进
还是从数据表着手,新增一个 count
字段,用来表示可以向该用户发送对应订阅消息的次数。
订阅:用户首次订阅,count
默认值为1,若重复订阅,count + 1。
发送消息:获取对应消息模板ID,及count值大于0的用户。发送成功后把count值减1,拒绝接受则把count置为0,其他错误则不做任何处理。
界面改进
"明日提醒"按钮最开始是设计成一直显示的,用户可以多次点击订阅,如果点击5次,那接下来的5天内,用户都会收到订阅消息。
到了第六天就会发送失败,这就会导致用户产生误解,难道是今天没发布题目吗?
为了避免这样的误解发生,当用户订阅成功后,会隐藏该按钮。
当然在进入该界面时,也需要查询用户是否已经订阅过“明日提醒”,这里我只需要判断是否有该用户订阅信息及 count 的值是否大于0即可。
自动化脚本
这个功能上线后,那必然是一个每天都要进行的任务,如果每天都手动的发送是一个相当无脑的行为。
来看看整个发送过程要进行哪些步骤吧:
第一步:获取今日题目,如果今日未发布题目,那就无需进行后面的操作,直接终止本次发送任务。并在随后每隔一小时定时执行。
第二步:获取当月的排名信息
第三步:获取当前可以发送订阅消息的用户
第四步:处理数据,这里有许多的情况,如:某个订阅用户在当月无任何打卡信息,那么他的排名应该是最后一名;每日更换“温馨提示”内容;
第五步:给符合条件的用户发送订阅消息
第六步:保存每次发送消息的返回信息,便于出现问题时定位原因
第七步:上面的步骤每天定时执行
欢迎访问我的个人网站 www.dengzhanyong.com
我的公众号:【前端筱园】