做uni-app开发,尤其是涉及微信生态的时候,订阅消息这块绝对是“事故高发区”。很多开发者习惯性地想用老一套模板消息的逻辑,结果发现根本走不通。今天咱们就把这里面的关键限制和几个一踩一个准的坑,彻底捋清楚。 首先,一个核心认知必须扭转:在uni-app里,你没法直接“发送”模板消息,必须走微信官方
uni-app实现微信小程序模板消息推送与订阅消息配置
时间:2026-06-07
浏览:81
文章目录
做uni-app开发,尤其是涉及微信生态的时候,订阅消息这块绝对是“事故高发区”。很多开发者习惯性地想用老一套模板消息的逻辑,结果发现根本走不通。今天咱们就把这里面的关键限制和几个一踩一个准的坑,彻底捋清楚。

首先,一个核心认知必须扭转:在uni-app里,你没法直接“发送”模板消息,必须走微信官方的订阅消息流程,而且只能用“一次性”模板。 更关键的是,那个关键的授权弹窗API——uni.requestSubscribeMessage,绝对不能想当然地自动调用,否则必然失败,这是微信的硬性规定。
uni.requestSubscribeMessage 必须由 button 点击触发
微信对这个API的调用场景卡得非常死,必须由用户真实点击一个原生button组件来触发。任何试图绕过这个限制的操作,比如在页面生命周期onLoad、onShow里调用,或者用setTimeout延时触发,都会被微信直接拦截,通常表现为静默失败或者返回一个errCode: -1。
这里有几个典型的错误示范:
- 在
view或者text组件上绑定@click事件来调用——不行,微信不认,必须是原生的button。 - 用了
button,但没加open-type="subscribeMessage"属性——在uni-app 3.0+版本里,这也是无效的(这个属性是后来才支持的)。
所以,正确的写法长这样:
对应的JS方法:
handleSubscribe() {
uni.requestSubscribeMessage({
tmplIds: ['YOUR_TEMPLATE_ID'],
success: (res) => {
if (res['YOUR_TEMPLATE_ID'] === 'accept') {
// 用户同意了,这里可以立即调用后端接口发送消息
}
},
fail: (err) => {
console.error('订阅消息授权失败', err)
}
})
}
怎么判断用户是否已授权某模板 ID
前端光弹窗还不够,还得会判断状态。很多人只知道用uni.getSetting({withSubscriptions: true})去看总开关mainSwitch,但这远远不够。真正的关键,在于检查具体模板ID的授权状态,也就是itemSettings对象。
itemSettings['YOUR_TEMPLATE_ID'] === 'accept':恭喜,用户已授权。但注意,对于一次性模板,发完这次消息,这个授权就失效了,下次需要重新引导用户点击授权。=== 'reject':用户之前点过“拒绝”。这时候你再调用requestSubscribeMessage,弹窗是不会出来的。正确的做法是引导用户前往小程序设置页手动开启,调用uni.openSetting({withSubscriptions: true})。=== 'ban':这个模板被微信封禁了。虽然少见,但确实存在。- 字段不存在:如果
itemSettings里压根没有你这个模板ID的字段,那说明用户从未对它做出过选择。这时候,才是你调用requestSubscribeMessage弹出授权窗口的最佳时机。
另外提个醒,调用uni.getSetting时,withSubscriptions: true这个参数千万别漏,否则你拿到的itemSettings永远是个空对象。
后端发送时三个高频踩坑点
前端授权成功,只是万&里长征第一步。后端真正调用微信接口发送消息时,失败率极高,问题主要出在下面三个地方:
access_token管理不当:这玩意儿必须缓存!微信规定它每两小时失效一次,而且有获取频率限制。如果你每次都重新获取,或者硬编码一个过期的token,妥妥的会收到40001错误。最佳实践是服务器缓存token,并在每次使用前检查其有效性。touser字段搞错:这个字段必须填当前小程序的用户openid。用成了其他小程序的openid、测试号的openid,或者更常见的——误用了同一用户公众号体系的openid,都会导致发送失败,错误码通常是errcode: 43101。- 模板字段名对不上:这是最隐蔽的坑。你申请模板时,每个字段都有一个固定的
name,比如thing1、time4。后端构造请求数据时,key必须和这个name一字不差。如果你写成了content、message或者自己编的名字,微信不会报错,但那个字段的内容就会显示为空。
最后记住发送接口地址:https://api.weixin.qq.com/cgi-bin/message/subscribe/send。别和已经废弃的旧模板消息接口搞混了。
模板 ID 和字段名必须严格对齐后台配置
订阅消息的模板,都是在微信公众平台「开发管理 → 订阅消息 → 我的模板」里创建的。每个模板会生成一个全局唯一的templateId,同时,模板里的每个字段都有一个微信规定的、固定的name(例如character_string1、time4)。
- 前端的任务相对简单,就是在调用
requestSubscribeMessage时,把需要授权的templateId放在tmplIds数组里传过去。 - 后端的活儿就细了。构造请求体中的
data对象时,每一个键(key)都必须严格使用微信后台模板详情里展示的那个字段name,值(value)则是你要填充的字符串内容。 - 字段值有严格限制:比如
thing.DATA类型的字段,最多只能填20个字符;time.DATA类型的字段,值必须是YYYY-MM-DD HH:mm这样的格式,或者是像"09:00~12:00"这样带波浪线的时间段。
这里有个极易被忽略的细节:模板字段名是大小写敏感的,而且必须完全匹配,不能自己加空格、改下划线。 只要有一个字段名对不上,整条消息对应的那个字段就会显示为空白,查错都很难查。
实用工具推荐
绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
选择画质和输出格式,预览压缩前后的大小。