Files
yunzerwebsiteallinone/go/docs/小程序订阅消息配置与使用.md
2026-10-31 19:17:37 +08:00

6.4 KiB
Raw Permalink Blame History

小程序订阅消息:配置与使用(怎么让用户收到提示)

一、先分清两条通道

消息推送(服务器配置) 订阅消息
方向 用户 → 你(用户发客服消息给你) 你 → 用户(你主动推提示给用户)
触发 用户在小程序点「客服」发消息 业务事件发生(审批待办、日程提醒、站内信…)
前置条件 无 用户必须在微信弹窗里点「允许」(一次性订阅:授权一次 = 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