微信服务号消息通知最佳实践
概述
小程序原生消息通知存在频次与授权限制:用户每次接收消息前需要单独授权,无法一次授权接收多条通知。通过将服务号与小程序关联,可以使用服务号模板消息实现对同一用户持续、主动、定向的多次通知。本文提供从账号准备到项目集成、页面配置与行为流调用的完整实施指南。
前提条件
- 必须创建微信服务号(公众号分为订阅号与服务号,只有服务号可以对用户进行主动、定向的长期通知)
- 必须开通微信认证
- 个人服务号不支持此功能,需要企业或政府主体
准备工作
注册微信开放平台开发者账号
访问微信开放平台 并注册开发者账号。
绑定服务号和小程序
在微信开放平台中将服务号与小程序进行绑定。
配置服务号模板消息
-
登录微信公众平台 的服务号
-
在左侧菜单中找到”模板消息”(如果无法找到此菜单,需要在功能中添加,审核需要 2-3 天)
- 配置模板参数
- thing 开头参数:普通文本类型参数,支持汉字、数字、字母或符号组合,限制 20 个字符以内,如图中的 thing16、thing6
- time 开头参数:时间类型参数,支持 24 小时制时间格式(可包含年月日),格式为 HH:MM:SS 或 HH:MM;可填写时间段,两个时间点之间用”~“连接,例如「15:01」或「2019年10月1日 15:01」,如图中的 time15
- 更多参数限制详情请参考微信模板消息官方文档
获取服务号凭证并配置 IP 白名单
-
在服务号”设置与开发” → “基本配置”中查看并保存 AppID 与 AppSecret
-
添加以下 IP 白名单(必须配置,否则无法获取 AccessToken):
- 172.28.0.1
- 172.17.0.1
- 172.29.0.29
- 139.196.127.46
- 139.196.192.129
- 161.189.55.83(AWS)
项目配置
从模板项目导入内容
参考服务号通知模板项目 ,将模板中的行为流、API、数据模型复制到你的项目中。重要:请为 service_number_user_info
表的 open_id
字段添加唯一约束,约束名称必须为 unique_open_id
。
配置行为流参数
- 获取服务号AccessToken 行为流代码块 → 修改
appId
、appSecret
、APP_ID
- 更新本地服务号用户信息 行为流代码块 → 修改
ACTION_FLOW_UNIQUE_ID_GET_LATEST_TOKEN
、GET_OPENID_API_ID
、GET_UNIONID_API_ID
- 发送服务号单条消息 和 发送服务号多条消息 行为流代码块 → 修改
ACTION_FLOW_UNIQUE_ID_GET_LATEST_TOKEN
、ACTION_FLOW_UNIQUE_ID_UPDATE_LOCAL_USER_INFO
配置页面参数
将真实的模板消息 templateId
与跳转相关信息填入发送消息的自定义行为参数中,字段必须与服务号模板占位符严格对应。
单条消息发送
参数示例及说明:
const basicInput = {
templateId: 'Fj7qiQV7WSDjOjEhQwp0i*****', // 模板消息ID,必填,文本类型
receiverAccountId: 1000000000000001, // 接收者accountId,必填,整数类型
url: '', // 跳转链接,可选,如需跳转到其他网页需填写
miniprogramAppId: '', // 小程序appId,可选,如需点击消息直接进入小程序需填写
miniprogramPagePath: '' // 小程序页面路径,可选,如需点击消息直接进入小程序需填写
}
const content = {
thing16: '', // 客户姓名,文本类型
time15: '', // 提交时间,文本类型
short_thing5: '', // 工单状态,文本类型
thing6: '' // 工单类型,文本类型
}
多条消息发送
与单条发送基本相同,主要区别如下:
basicInput
中的receiverAccountId
变为receiverAccountIds
,即单个用户变为多个用户- 在页面上通过数据源筛选出要发送的多个用户,注意配置所需的筛选条件
参数示例及说明:
const basicInput = {
templateId: 'Fj7qiQV7WSDjOjEhQwp0i*****', // 模板消息ID,必填,文本类型
receiverAccountIds: [1000000000000001, 1000000000000002], // 多个接收者accountId,必填,数组类型
url: '', // 跳转链接,可选
miniprogramAppId: '', // 小程序appId,可选
miniprogramPagePath: '' // 小程序页面路径,可选
}
const content = {
thing16: '', // 客户姓名,文本类型
time15: '', // 提交时间,文本类型
short_thing5: '', // 工单状态,文本类型
thing6: '' // 工单类型,文本类型
}
在行为流中调用发送消息
如果需要在行为流中执行发送单条消息(例如在支付回调行为流中调用),请添加代码块节点:
const templateId = context.getArg('templateId');
const receiverAccountId = context.getArg('receiverAccountId');
const url = context.getArg('url');
const miniprogramAppId = context.getArg('miniprogramAppId');
const miniprogramPagePath = context.getArg('miniprogramPagePath');
const thing16 = context.getArg('thing16');
const time15 = context.getArg('time15');
const short_thing5 = context.getArg('short_thing5');
const thing6 = context.getArg('thing6');
const af_id = context.getArg('af_id'); // 填写行为流ID,发送单条或发送多条消息的行为流ID
const basicInput = {
templateId: templateId,
receiverAccountId: receiverAccountId,
url: url,
miniprogramAppId: miniprogramAppId,
miniprogramPagePath: miniprogramPagePath
}
const content = {
thing16: thing16,
time15: time15,
short_thing5: short_thing5,
thing6: thing6
}
context.callActionFlow(
af_id,
null,
{content, basicInput}
);
常见问题与排查
1. 参数验证问题
- 参数为空或不合法:发送时所有必填参数必须非空
- 字段类型不匹配:字段类型需与模板定义一致(如
thing*
不超过 20 个字符,time*
为时间格式)
2. AccessToken 获取失败
- 检查是否已正确绑定 IP 白名单
- 验证 AppID/AppSecret 是否正确
- 确认服务出口 IP 是否有变化
3. 模板字段不一致
- 页面或行为流中
content
的字段名必须与服务号模板占位符一一对应 - 确保字段名称拼写正确,区分大小写
Last updated on