微信小程序订阅消息设计
随着微信小程序的普及,开发者需要一种高效的方式向用户传递重要信息。订阅消息作为一种官方推送机制,可以在用户授权的前提下主动发送消息。本文将详细解析微信小程序订阅消息的使用场景、实现流程及注意事项,帮助开发者高效利用这一能力。
什么是订阅消息
订阅消息是一种无需用户主动触发即可发送的单向消息推送方式。不同于服务通知,订阅消息需要用户明确授权,开发者可以在特定场景下向用户发送事先约定的信息。
特点:
单向推送:消息从开发者单向发送给用户。
需用户授权:每次发送前必须获得用户的订阅授权。
消息限制:单次订阅只能发送一次消息。
使用场景
订阅消息适用于以下常见场景:
物流通知:提醒用户包裹的配送状态。
服务预约:通知用户服务时间的变更。
活动提醒:向用户推送活动报名成功或即将开始的通知。
订单状态更新:更新用户订单的支付、发货等状态。
实现流程
订阅消息的实现流程主要包括以下几个步骤:
01 在微信公众平台申请模板
在小程序管理后台:
进入 "基础功能 -> 订阅消息",选择 "选用"。
搜索或创建符合需求的消息模板。
保存模板后,记录模板ID,后续开发中需要用到。
可以选用已经审核通过的,也可以自行配置然后等待审核。
选用模板关键词:
02 配置启动消息推送功能
在小程序管理后台:
进入 "开发 -> 接口设置",开启 消息推送 功能。
设置消息推送的 推送地址 和 Token,该地址用于接收微信服务器推送的事件通知。
验证推送配置是否成功,例如可以通过接收微信推送的测试消息确认配置无误。
为什么需要配置消息推送?
消息推送功能为小程序提供了事件通知能力,比如用户授权订阅、模板消息的发送结果等。当用户完成订阅或消息发送失败时,微信服务器会主动推送事件到配置的推送地址,帮助开发者实时监控消息状态并进行相应处理。
可以在配置之前,通过微信开放平台调试工具中验证你的 api 接口,图中右侧有验证的结果。地址:https://developers.weixin.qq.com/apiExplorer
03 在前端请求用户订阅
调用 wx.requestSubscribeMessage
接口,向用户请求订阅。
示例代码:
/**
* 向用户请求订阅消息
*/
export function requestSubscribeMessage(templateIds: string[]) {
return new Promise((resolve, reject) => {
wx.requestSubscribeMessage({
tmplIds: templateIds,
success(res) {
// 筛选出状态为 accept 的 templateId
const acceptedTemplateIds = Object.entries(res)
.filter(([_, status]) => status === 'accept')
.map(([templateId, _]) => templateId);
resolve(acceptedTemplateIds); // 返回 accept 的模板 ID 数组
},
fail(err) {
console.error('订阅请求失败:', err);
reject(err); // 处理失败情况
}
});
});
}
注意:
用户可以选择“总是保持以上选择,不再询问”,此后微信前端不再唤起弹框,让用户选择。
模板ID必须提前在管理后台申请并启用。
04 服务端发送订阅消息
通过小程序的服务器接口 https://api.weixin.qq.com/cgi-bin/message/subscribe/send
向用户发送消息。
设计要点:
每次用户选择的模板 ID 列表需要和具体的订单号进行绑定,因为用户可以在前端每次都选择不同的模板,后端如果没有记录直接发送,那么会被微信服务器拒绝。
订阅消息是一次性的,使用完成后,如果用户没有再次进行授权的话,无法进行消息的发送。
很多订阅消息是后置的,是用户在选择接收的模板后,后续订单出现状态变化时,进行触发的。
在订单状态发送变化后,发送异步事件通知,在 EventListener 中进行统一处理
异步事件发送微信订阅消息,记得设置在数据库事务提交之后,按需加入一致性保障,一般失败可以丢弃或者立即重试几次。
最后,需要确保发送的字段与模板字段一一对应,否则会报错。
例如:签到微信订阅消息通知部分代码实例:
@Async
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void onAppointmentSigned(AppointmentSignedEvent event) {
try {
AppointmentOrderDetailDTO appointmentOrderDetail =
appointmentOrderQueryExecutor.getDetail(event.getOrderId());
UserAccountDTO userAccountDTO =
userAccountQueryExecutor.getDetail(Long.valueOf(appointmentOrderDetail.getUserId()));
WxSubscribeSignAppointmentCmd subscribeSignAppointmentCmd = WxSubscribeSignAppointmentCmd.builder()
.openId(userAccountDTO.getOpenId())
.orderNo(event.getOrderId())
.userName(userAccountDTO.getAccountName())
.coachName(appointmentOrderDetail.getCoachName())
.courseName(appointmentOrderDetail.getCourseName())
.signTime(appointmentOrderDetail.getSignTime()
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.build();
messageCmdExecutor.sendAppointmentSignMessage(subscribeSignAppointmentCmd);
} catch (Exception e) {
log.warn("发送预约签到订阅消息失败!", e);
}
}
总结
订阅消息作为小程序的重要能力,可以帮助开发者提升用户体验。然而,在实现过程中需严格遵守微信的接口规范和用户隐私保护要求,以保证功能的稳定性和用户的信任感。希望本文能为开发者提供清晰的指导,助力开发高效实用的小程序功能。
附录
参考个人微信小程序,进入 “预约” tab,发起预约:
欢迎关注我的公众号“Eric技术圈”,原创技术文章第一时间推送。