6.4 KiB
6.4 KiB
小程序订阅消息:配置与使用(怎么让用户收到提示)
一、先分清两条通道
| 消息推送(服务器配置) | 订阅消息 | |
|---|---|---|
| 方向 | 用户 → 你(用户发客服消息给你) | 你 → 用户(你主动推提示给用户) |
| 触发 | 用户在小程序点「客服」发消息 | 业务事件发生(审批待办、日程提醒、站内信…) |
| 前置条件 | 无 | 用户必须在微信弹窗里点「允许」(一次性订阅:授权一次 = 1 次推送机会) |
| 微信后台位置 | 开发管理 → 开发设置 → 消息推送 | 功能 → 订阅消息 |
| 本工程实现 | services/wechatmini/push.go + controllers/api_wechat_mini.go |
services/wechatmini/subscribe.go + controllers/api_mini_subscribe.go |
结论:想让用户「收到提示」,靠的是订阅消息,不是消息推送。消息推送只是接收端(顺带做客服自动回复)。
二、完整流程(4 步)
第 1 步:微信后台选一个订阅消息模板
小程序后台 → 功能 → 订阅消息 → 公共模板库 → 选用模板(例如「审批进度通知」「待办提醒」)。
选完后记下两样东西:
- 模板 ID(一串字母数字)
- 模板的字段名(如
thing1、phrase2、time3、character_string4)
模板选错会导致推送报 40066 / 47003,字段名对不上则报「模板字段不匹配」。
第 2 步:平台端登记模板
平台后台 → 系统设置 → 小程序配置 → 编辑小程序 → 订阅消息模板 → 新增模板
| 字段 | 填什么 |
|---|---|
| 场景码 | notice(站内通知/通用提醒;同一个小程序下唯一) |
| 场景名称 | 如「站内通知」 |
| 模板 ID | 第 1 步复制的模板 ID |
| 跳转页面 | 用户点击消息进入的小程序页面,如 pages/index/index |
| 字段映射 | JSON:{"thing1":"title","phrase2":"content","time3":"time"} |
字段映射怎么读:左边是微信模板的字段名,右边是平台这边的变量名。平台会提供三个变量:
title—— 标题(如「您有新的审批待办」)content—— 内容time—— 推送时间(2026-10-31 19:00)
映射里写了哪个字段,就把对应变量填进去;模板有但没映射的字段会自动填 -。
第 3 步:小程序端让用户授权
已接入的位置:小程序「我的 → 消息通知」,点一下会拉起微信的订阅授权弹窗。
import { requestSubscribeNotice } from '@/utils/subscribe.js'
await requestSubscribeNotice()
建议在用户确实可能需要收到提醒的时机也调用一次(比如进入工作台、提交完审批之后)——因为微信一次性订阅,授权一次只有一次推送机会,用完了要再授权。
小程序端也可以直接调接口:
GET /api/mini/subscribe/templates取模板列表POST /api/mini/subscribe/authorize上报授权结果POST /api/mini/subscribe/test给自己发一条测试消息
第 4 步:业务侧触发
已接入的触发点(业务照常发,订阅消息自动跟上,不影响主流程,失败只记日志):
| 业务 | 代码位置 |
|---|---|
| 站内信(平台端手动发通知) | services/system_sitereminder.go → SendSiteReminder |
| OA 日程提醒(定时任务) | services/reminder_scheduler.go → SiteMsgSender.Send |
| 审批待办(租户侧审批人生成待办) | services/approval/engine.go → createTasks |
自己接新场景时,直接调:
wechatmini.PushTenantNotice(租户用户ID, "标题", "内容")
// 或指定场景码:
wechatmini.PushSubscribeToTenantUser(租户用户ID, "notice", "", map[string]string{
"title": "标题", "content": "内容", "time": "2026-10-31 19:00",
})
三、一次性订阅的规则(最容易踩坑)
- 用户点一次「允许」= 1 次推送机会,服务器记在
yz_platform_wechat_mini_subscribe.remain - 推送成功自动
remain - 1;用户拒绝或机会用尽(微信返回 43101)自动清零 remain = 0时不会调微信接口,直接跳过(不浪费配额)- 微信一次弹窗最多 3 个模板,前端已自动分批
- 「长期订阅」只有部分类目能用,��务小程序基本用不了,所以要设计好再次引导授权的时机
四、常见错误码
| errcode | 含义 | 处理 |
|---|---|---|
| 43101 | 用户未订阅 / 拒绝订阅 | 引导用户在小程序里重新点「消息通知」授权 |
| 40066 | 模板 ID 无效 | 检查是不是填了「功能 → 订阅消息」里真正的模板 ID |
| 47003 | 模板字段不匹配 | 检查字段映射与微信模板字段是否一致 |
| 40003 | openid 无效 | 该用户不是用这个小程序登录的,或 openid 与 AppID 不匹配 |
| 40001 | access_token 失效 | 工具会自动刷新,稍后重试 |
平台端「测试」按钮会直接返回中文排查建议。
五、接口清单
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/mini/subscribe/templates |
小程序端:可订阅模板列表(含剩余次数) |
| POST | /api/mini/subscribe/authorize |
小程序端:上报授权结果 |
| POST | /api/mini/subscribe/test |
小程序端:给自己发一条测试消息 |
| GET | /platform/wechatMini/templates |
平台端:模板列表 |
| POST | /platform/wechatMini/template/save |
平台端:保存模板 |
| POST | /platform/wechatMini/template/delete/:id |
平台端:删除模板 |
| POST | /platform/wechatMini/template/test |
平台端:给指定租户用户发测试消息 |
六、相关文件
| 文件 | 作用 |
|---|---|
go/services/wechatmini/subscribe.go |
订阅消息 / 客服消息发送、模板 CRUD、授权记录、推送编排 |
go/controllers/api_mini_subscribe.go |
小程序端接口 |
go/controllers/platform_wechat_mini.go |
平台端模板管理接口 |
go/models/wechat_mini.go |
WechatMiniTemplate / WechatMiniSubscribe 模型 |
go/docs/sql/create_wechat_mini_template.sql |
建表脚本 |
uniapp/utils/subscribe.js |
小程序端授权助手 |
uniapp/api/subscribe.js |
小程序端接口封装 |
uniapp/pages/profile/profile.vue |
「我的 → 消息通知」授权入口 |
建表脚本:
mysql -h <host> -P <port> -u <user> -p <db> < go/docs/sql/create_wechat_mini_template.sql