一、准备工作
-
申请消息模板
在微信公众平台「订阅消息」功能中申请模板,获取模板ID及字段标识。 -
配置服务器域名
在小程序后台设置合法请求域名(如API接口域名和获取access_token的域名)。
二、前端实现流程
-
获取用户身份标识
通过uni.login
或wx.login
获取code
,调用接口换取用户openid
uni.login({
success: res => {
uni.request({
url: '后端接口/getOpenid',
data: { code: res.code }
});
}
});
2. 调起订阅弹窗
使用wx.requestSubscribeMessage
触发订阅请求,需传入模板ID列表:
wx.requestSubscribeMessage({
tmplIds: ['模板ID_1', '模板ID_2'],
success(res) {
if (res['模板ID_1'] === 'accept') {
console.log('用户同意订阅');
}
}
});
3. 提交模板数据
用户触发业务事件(如支付成功)时,向后端发送模板数据
data: {
templateData: {
thing1: { value: '商品名称' },
amount3: { value: '100元' }
}
}
三、后端实现流程
使用 WxMpTemplateMessage
(基于微信开发工具包 WxJava)发送小程序订阅消息的完整 Java 代码示例如下:
一、依赖引入(Maven)
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>4.5.0</version> <!-- 使用最新版本 -->
</dependency>
二、核心代码实现
1. 初始化微信配置
在 Spring Boot 中配置 WxMpService
:
@Configuration
public class WxMpConfig {
@Value("${wx.appid}")
private String appid;
@Value("${wx.secret}")
private String secret;
@Bean
public WxMpService wxMpService() {
WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
config.setAppId(appid);
config.setSecret(secret);
WxMpService service = new WxMpServiceImpl();
service.setWxMpConfigStorage(config);
return service;
}
}
2. 构建订阅消息并发送
@Service
public class SubscribeMessageService {
@Autowired
private WxMpService wxMpService;
/**
* 发送订阅消息
* @param openid 用户openid
* @param templateId 消息模板ID
* @param dataMap 模板数据(字段名与模板中定义的key对应)
*/
public void sendSubscribeMessage(String openid, String templateId, Map<String, String> dataMap) {
try {
// 1. 构建模板消息对象
WxMpSubscribeMessage message = WxMpSubscribeMessage.builder()
.toUser(openid)
.templateId(templateId)
.data(dataMap.entrySet().stream()
.map(entry -> new WxMpSubscribeMessage.MsgData(entry.getKey(), entry.getValue()))
.collect(Collectors.toList()))
.build();
// 2. 发送消息
wxMpService.getSubscribeMsgService().send(message);
} catch (WxErrorException e) {
// 处理微信接口异常
log.error("发送订阅消息失败: {}", e.getMessage());
throw new RuntimeException("消息发送失败");
}
}
}
3. 实际调用示例
@RestController
public class MessageController {
@Autowired
private SubscribeMessageService messageService;
@PostMapping("/sendOrderSuccessMsg")
public String sendOrderSuccessMsg(@RequestParam String openid) {
// 模板数据(根据模板字段定义)
Map<String, String> dataMap = new HashMap<>();
dataMap.put("thing1", "iPhone 15 Pro"); // 对应模板中的字段key
dataMap.put("amount3", "¥9999.00");
dataMap.put("time4", "2024-03-01 14:30:00");
// 发送消息
messageService.sendSubscribeMessage(openid, "TEMPLATE_ID_123", dataMap);
return "消息已发送";
}
}
三、关键注意事项
-
模板字段匹配
dataMap
中的键必须与模板详情中的字段名严格一致(如thing1
、amount3
),值需符合字段类型要求(如金额字段必须带单位¥
)。 -
用户授权要求
用户需通过前端wx.requestSubscribeMessage
授权当前模板消息,且授权状态有效(未拒绝过)。 -
错误码处理
捕获WxErrorException
异常时,需重点关注以下错误码:- 43101: 用户拒绝接受消息
- 41030: 模板ID无效
- 40003: openid 错误
-
消息触发限制
订阅消息仅限用户主动触发事件后 7 天内发送(如支付成功、表单提交等场景)。
四、扩展优化
- 模板数据动态构建
可将数据格式化为符合微信要求的格式(如日期时间转换):
dataMap.put("time4", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
2. 异步发送
使用 @Async
注解或消息队列异步发送消息,避免阻塞主线程:
@Async
public void sendSubscribeMessageAsync(...) { ... }
3. 模板配置中心化
将模板 ID 和字段映射关系存储在数据库或配置中心,方便动态管理。
通过以上代码,可以快速实现基于 WxJava
的小程序订阅消息推送功能。