wechat_message_push.md
5.95 KB
微信小程序订阅消息推送后端开发文档(适用于 Spring Boot 微服务)
1. 背景与目标
本方案通过微信小程序的 订阅消息(Subscribe Message) 能力,在用户授权的前提下,在特定时间向用户推送服务通知。例如在订餐周期开启前提醒用户开始订餐。
微信要求订阅消息必须通过用户主动操作获得授权,且每次授权只能发送一次消息(非特权行业除外)。(Medium)
2. 模板申请与配置
2.1 登录微信公众平台
- 登录微信公众平台(小程序管理后台)。
- 在左侧菜单选择 功能 → 订阅消息。
- 在 公共模板库 中查找最符合业务场景的模板;如无合适模板,可新建申请。
- 按需选择关键词组合并提交审核。
- 审核通过后在“我的模板”中得到 模板 ID。
说明:该模板 ID 将用于消息发送接口参数。(aigwa.com)
3. 小程序前端授权流程简述
在前端,当用户在小程序产生关键交互(例如提交订单成功后)时,需要通过 wx.requestSubscribeMessage 调起订阅授权。
wx.requestSubscribeMessage({
tmplIds: ['TEMPLATE_ID'],
success(res) {
// 例如:res['TEMPLATE_ID'] = "accept" | "reject" | ...
// 结果上报后端
}
})
提示:
- 用户点击“允许”后即获得一次性发送权限。(intl.cloud.tencent.com)
4. 后端核心概念与数据模型
4.1 订阅授权状态表(示例)
CREATE TABLE wx_subscribe_permission (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
openid VARCHAR(64) NOT NULL,
template_id VARCHAR(64) NOT NULL,
biz_type VARCHAR(32) NOT NULL,
order_cycle_id VARCHAR(32),
status ENUM('PENDING','USED','FAILED') NOT NULL DEFAULT 'PENDING',
retry_count INT DEFAULT 0,
last_error VARCHAR(255),
authorized_at DATETIME,
used_at DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-
PENDING:用户已授权但未发送; -
USED:发送成功; -
FAILED:发送失败且不再重试。
5. 微信服务端 API 调用
5.1 获取 access_token
用于后端所有接口调用授权凭证:
GET https://api.weixin.qq.com/cgi-bin/token
?grant_type=client_credential
&appid=APPID
&secret=APPSECRET
返回示例:
{
"access_token": "ACCESS_TOKEN",
"expires_in": 7200
}
5.2 发送订阅消息
使用订阅消息下发接口:
POST https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN
请求 JSON 示例
{
"touser": "USER_OPENID",
"template_id": "TEMPLATE_ID",
"page": "pages/order/index?cycleId=202501",
"data": {
"thing1": { "value": "下次订餐即将开启" },
"time2": { "value": "周一 09:00" },
"thing3": { "value": "请点击跳转完成订餐" }
}
}
字段说明:
-
touser:接收用户微信 OpenID; -
template_id:模板 ID; -
page:消息点击跳转页面路径; -
data:模板关键词对应数据。(gitcode.csdn.net)
6. 后端主要接口设计
6.1 授权结果回传 API(POST)
URL: /api/wechat/subscribe/authorize
请求示例
{
"openid": "xxxx",
"templateId": "TEMPLATE_ID",
"bizType": "ORDER_REMIND",
"orderCycleId": "202501",
"result": "accept"
}
响应示例
{ "code": 0, "msg": "ok" }
逻辑:
- 若 result =
accept,写入wx_subscribe_permission表; - 否则记录拒绝状态。
6.2 定时发送任务
后端定时任务(如 @Scheduled)在规定时间触发:
- 查询所有
status = PENDING且对应用户未订餐的记录; - 将消息入队(如 MQ);
- 消费执行发送逻辑;
- 更新
status与retry_count。
7. 发送逻辑与重试策略
7.1 核心发送逻辑(伪码)
for (Permission p : pendingList) {
try {
sendSubscribeMessage(p);
p.setStatus("USED");
p.setUsedAt(now());
} catch (WeChatApiException e) {
if (canRetry(e) && p.getRetryCount() < 3) {
p.incrementRetry();
} else {
p.setStatus("FAILED");
p.setLastError(e.getMessage());
}
}
update(p);
}
8. 常见错误码处理
| 错误码 | 说明 | 处理方式 |
|---|---|---|
43101 |
用户拒绝 | 标记 FAILED 不再重试 |
40001 |
access_token 错误 | 刷新 Token 并重试 |
| 网络错误 | 网络抖动 | 按退避重试 |
9. 测试建议
- 先使用测试 OpenID 调用发送接口;
- 检查模板字段是否与后台组装一致;
- 校验跳转页面路径参数是否正确。
10. 参考链接
- 微信官方订阅消息后端发送接口说明(subscribeMessage.send)(gitcode.csdn.net)
- 小程序端授权调用说明(wx.requestSubscribeMessage)(wdk-docs.github.io)
如果你需要,我可以进一步提供 Spring Boot 样板代码(包括定时任务 & 消息发送 Service 实现)。