前言
在微信小程序开发时,通常会有发送模板消息功能,但是微信的模板消息存在限制
大多数小程序资质,只能一次性订阅,不能长期订阅
当然,也存在各种技巧,可以实现假性"长期订阅"
这种情况下,我们可以选择用工关系来达成我们这一需求
配合微信官方文档食用效果更佳
文档地址:开放能力 / 用工关系
用工关系是什么?
用工关系功能,支持与小程序有用工关系的用户能与对应的小程序进行绑定。绑定后
- 小程序可以向已绑定的用户推送用工关系消息通知
- 绑定用户将能在微信「小程序助手」中接收用工关系消息通知
通过这个功能,确保小程序在用工场景下的关键业务信息高效触达。
如果存在发送微信消息进行通知的需求,就可以使用此功能进行实现
用工关系的前期准备
1. 添加小程序类目
此功能只支持非个人主体下的如下小程序类目
- 物流服务/医疗服务/政务民生/金融业
- 教育服务/交通服务/房地产服务/生活服务
- IT科技/餐饮服务/旅游服务/商家自营/商业服务
如果不巧你的类目不在里面,可以试试 商业服务 > 软件/建站/技术开发
在添加支持的小程序类目,并且审核通过以后,可以在公众平台看到多了个行业能力 > 用工关系 菜单

看到这个,你的第一步就完成了
2. 开通功能
点击用工关系

再点击去开通

填入表单信息之后,点击提交
然后等待审核,一般两三个小时就通过了

看到这个,你的第二步也完成了
3. 新增用工消息模版
我的模板,点击添加

填写模板信息

注意
- 为增加审核通过几率,模板的发送场景说明写详细一点,具体使用场景是什么?怎么触发的消息?
- 另外,标题不能太宽泛,需要具体一点
以下是错误示范
填写好模板信息,就可以提交审核了
微信给出的审核时间是7-15天,实际上一天内就会审核完成

看到这个,你的第三步也完成了,前期准备阶段结束
怎么使用用工关系?
这里有个原则:
- 绑定
openid,才能发送到具体人 - 绑定用工关系,才能接收消息
- 订阅消息模板,才能接收具体模板消息
1. 绑定用工关系
绑定用工关系接口(前端调用):wx.bindEmployeeRelation
这个接口会拉起一个弹框,用户可以选择允许 或拒绝

注意 ,要是选择了拒绝 ,那么只能24小时之后才能再次绑定
点击允许,会显示这样一个页面

因为我在wx.bindEmployeeRelation传入了模板id
所以可以在绑定的同时,订阅消息模板

绑定之后,你的微信首页会出现这样一个"小程序助手"
后续消息也是发到这个里面
点进去,可以看到

观察到这个,第一步完成
2. 发送用工消息
推送用工消息接口(后端调用):SendEmployeeRelationMsg
先去微信公众平台,点进要发送的消息模板详情,右下角有个这样的东西

这个就是模板消息变量 了,先记下来thing1、time1,后面会解释
我们可以设计一个这样的模板消息类(使用java实现,当然你也可以用其他语言)
java
@Data
public class TemplateMessageVo {
@Schema(description = "OPENID", required = true)
private String touser;
@Schema(description = "模板ID", required = true)
private String template_id;
@Schema(description = "模板跳转链接")
private String page;
@Schema(description = "发送内容")
private String data;
}
再构建一个消息发送测试方法
java
@Test
public void test() {
TemplateMessageVo params = new TemplateMessageVo();
params.setTouser("接收消息用户的openid");
params.setTemplate_id("要发送的消息模板id");
params.setPage("要跳转的小程序页面");
// 使用 HashMap 构建数据结构
Map<String, Object> data = new HashMap<>();
// 内层字段
Map<String, String> thing1 = new HashMap<>();
charString1.put("value", "1224-0059");
Map<String, String> time1 = new HashMap<>();
amount1.put("value", "2025年12月24日 08:11");
// 模板消息变量,有顺序要求
Map<String, Object> dataContent = new LinkedHashMap<>();
// 模板消息变量1
dataContent.put("thing1", thing1);
// 模板消息变量2
dataContent.put("time1", time1);
data.put("data", dataContent);
String dataString = JSON.toJSONString(data);
params.setData(dataString);
JSONObject messAge = JSONObject.parseObject(JSONObject.toJSONString(params));
System.out.println(messAge);
// 调用微信发送用工消息接口
wechatService.sendTemplateMessage(params);
}
可以看到,这里我们用上了上面说的thing1、time1
有先后顺序要求,必须和模板里面的顺序保持一致
注意,模板变量的值,存在违禁词,比如要是这样写入变量
javaMap<String, String> thing1 = new HashMap<>(); charString1.put("value", "焚烧");那调用微信接口时,会提示违禁词错误
哪些是违禁词可以看下微信官方的违禁词规则
调用成功之后,我们会在小程序助手中,看到这样一条消息

看到这个,就是发送成功了,第二步也成功完成了
至此,圆满结束
其他
至于其他的像 解绑用工关系、检查用工关系、数据库同步等,可以按需求进行设计
这里提几个常见的坑
该功能有版本要求
- 支持基础库版本:3.10.0以上
- 支持微信版本:8.0.62以上
该功能需要真机调试
消息模板只能订阅一次,已经订阅过了再订阅会报错
使用 wx. bindEmployeeRelation 或者 wx.requestSubscribeEmployeeMessage
如果在wx. bindEmployeeRelation已经订阅过模板了
再使用wx.requestSubscribeEmployeeMessage去订阅模板,会报错
data 参数格式
调用发送消息接口SendEmployeeRelationMsg时,要特别注意data格式:
json
{
"template_id": "bV8Jk-XXXXXX",
"page": "page/XXX",
"touser": "oL7T268t3zlOb64IvrN64-XXXXXX",
"data": "{"data":{"character_string1":{"value":"aaa"},"amount1":{"value":"222"}}}"
}
data的值是个json字符串,转化过来的json对象是这样的:
json
"data": {
"character_string1": {
"value": "aaa"
},
"amount1": {
"value": "222"
}
}

