uni-app小程序全局消息订阅通知自动下发实现方法

作者:技术拾光

时间:2026-06-17

浏览:407

先给个明确的结论:uni-app小程序端,不可能实现“自动下发”的全局消息订阅通知。这是微信平台的硬性规则,不是技术能力没跟上,而是平台逻辑本身就不允许任何非用户主动触发的订阅授权行为。所谓“自动下发”,在技术上既不可行,也直接踩了微信审核的红线。真正可行的路径其实很清楚:前端只负责引导用户点击授权

文章目录

先给个明确的结论:uni-app小程序端,不可能实现“自动下发”的全局消息订阅通知。这是微信平台的硬性规则,不是技术能力没跟上,而是平台逻辑本身就不允许任何非用户主动触发的订阅授权行为。所谓“自动下发”,在技术上既不可行,也直接踩了微信审核的红线。

真正可行的路径其实很清楚:前端只负责引导用户点击授权 + 后端按需调用微信接口推送。下面把几个关键实操点拆开来讲清楚。

uni.requestSubscribeMessage 必须由 button 点击触发

这不是什么兼容性问题,是微信划定的硬性限制。以下写法全部无效:

  • 把 uni.requestSubscribeMessage 放在 onLoad、onShow 或 setTimeout 里 → 直接报错 errCode: -1, errMsg: "requestSubscribeMessage:fail api scope is not declared"
  • 用 或 包裹调用 → 微信不识别,静默失败
  • 没加 open-type="subscribeMessage" 属性(uni-app 3.0+ 要求)→ 不弹授权框

正确写法只有这一种:

JS 中调用时,tmplIds 每次最好只传 1 个模板 ID。用户如果点“拒绝”,整批模板都会失效,后续再无触达机会。

uni.getSetting 检查权限必须带 withSubscriptions: true

很多开发者调了 uni.getSetting() 却拿不到订阅状态,问题就出在这个参数被遗漏了。

  • withSubscriptions: false 或不传 → 返回结果里根本没有 subscriptionsSetting 字段
  • withSubscriptions: true → 才能拿到 res.subscriptionsSetting.mainSwitch 和 res.subscriptionsSetting.itemSettings
  • itemSettings[templateId] 是 undefined?说明该模板从未被请求过,不是“拒绝”,而是“未触达”。

别只盯着 mainSwitch,它只是总开关。真正决定能否发消息的是具体模板的 itemSettings[templateId] 值,可能为 'accept'、'reject' 或 'ban'。

后端发送消息必须用缓存的 access_token

前端拿到 'accept' 后,要立刻把 openid 和模板 ID 传给后端;后端不能每次发都重新拉 access_token。

  • access_token 有效期仅 2 小时,且每 2 小时最多获取 1 次,日限 2000 次 → 不缓存必超限
  • 必须存在服务端内存或 Redis 中,并带过期时间自动刷新
  • 调用地址是:https://api.weixin.qq.com/cgi-bin/message/subscribe/sendaccess_token=xxx,不是旧的模板消息地址
  • data 字段必须严格匹配模板定义的字段名(如 thing1),结构必须是 { value: 'xxx' },不能直接传字符串

用户点了“拒绝”之后怎么补救

如果后端调用微信接口返回 {"errcode":43101,"errmsg":"user refuse to accept the msg"},说明用户当时点了“拒绝”,且没再手动打开设置。

  • 前端应提示“请前往设置开启”,并立即调用:uni.openSetting({ withSubscriptions: true })
  • 注意:这个 API 也必须由用户点击触发,不能自动调;否则会失败
  • 不要反复弹窗引导——微信对诱导授权非常敏感,可能被拒审

一次性模板的本质决定了它没法“全局自动下发”。所谓“全局”,只能靠业务侧在关键节点(如下单成功页、支付完成页)精准嵌入授权按钮,而不是幻想一个后台定时任务能推到用户手机上。

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›