uni-app实现微信小程序模板消息推送与订阅消息配置

作者:技术拾光

时间:2026-06-07

浏览:81

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

文章目录

做uni-app开发,尤其是涉及微信生态的时候,订阅消息这块绝对是“事故高发区”。很多开发者习惯性地想用老一套模板消息的逻辑,结果发现根本走不通。今天咱们就把这里面的关键限制和几个一踩一个准的坑,彻底捋清楚。

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"这样带波浪线的时间段。

这里有个极易被忽略的细节:模板字段名是大小写敏感的,而且必须完全匹配,不能自己加空格、改下划线。 只要有一个字段名对不上,整条消息对应的那个字段就会显示为空白,查错都很难查。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章