微信订阅消息的开发

2025-08-21 09:30
61
0

分成以下几个步骤

  1. 微信后台订阅消息模板选择或自定义
  2. 前端授权
  3. 后端接口收到授权通知
  4. 业务功能,发送订阅消息
  5. 授权有效期检测?

 

 

1、微信后台订阅消息模板选择或自定义

类型有“一次性订阅” 和 “长期订阅”两种,区别是

区别项 一次性订阅 长期订阅
消息发送次数 用户订阅一次,服务号可不限时间地下发一条对应的订阅通知,即用户同意一次,发一次消息。 用户订阅一次,服务号可长期多次下发通知。
触发条件 每次发送消息都需要用户单独授权。 用户只需首次访问时授权一次,后续满足条件即可持续触发消息发送,无需再重复询问用户。
有效期 通常没有明确的有效期限制,但每次授权仅对应一条消息的发送。 直到用户主动取消授权,否则服务号可一直下发消息。
用户体验 每次接收消息都需要授权,相对比较繁琐。 用户只需授权一次,后续能持续收到消息,体验更好。
应用场景 常用于单次事件的通知,如订单状态更新、活动提醒、预约提醒等。 适用于需要持续和多次通知的场景,如医疗健康类的定期检查提醒、政务民生类的政策更新通知等,不过长期订阅通知仅向特定的公共服务领域开放。

注意:长期订阅仅对医疗、政务、交通等公共服务领域开放(如医院定期体检提醒、政府政策更新),普通充电服务不在其开放范围内,无法申请;且长期订阅的 “持续多次下发” 特性,与你 “按单次充电事件触发” 的需求无关,反而可能导致权限冗余。

 

2、前端授权,并通知服务端

// 示例:在按钮的 bindtap 事件处理函数中
  async onSubscribeMessage() {
    // 1. 准备模板ID数组(从公众平台后台获取,替换成你自己的)
    const tmplIds = [
   'qPnBXl695E', // 例如:'A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6'
   'mTxfMUjf0zKWaGTVtx4'
    ];

    // 2. 调用 API 弹出订阅消息授权弹窗
    wx.requestSubscribeMessage({
   tmplIds: tmplIds, // 需要订阅的消息模板的id的集合
   success: (res) => {
     /* res 格式:
    {
      'Your_Template_ID_1': 'accept', // 'accept'表示用户同意订阅
      'Your_Template_ID_2': 'reject'  // 'reject'表示用户拒绝订阅
    }
     */
     console.log('订阅结果', res);

     // 3. 处理授权结果
     if (res[tmplIds[0]] === 'accept') {
    wx.showToast({ title: '订阅成功' });
    // 这里通常会将本次订阅成功的凭证(以及用户选择)发送到后端服务器保存
    wx.request({
      url: 'http://localhost:48080/app-api/wx/subscribe',
      method: 'POST',
      data: {
     templateId: tmplIds[0],
     subscribeStatus: 'accept'
      }
    })
     } else {
    wx.showToast({ title: '您拒绝了订阅', icon: 'none' });
     }
   },
   fail: (err) => {
     console.error('订阅接口调用失败', err);
     wx.showToast({ title: '订阅失败', icon: 'none' });
   }
    })
  },

 

3、后端接口收到授权通知

@PostMapping("/miniapp/subscribe")
public void subscribe(@RequestBody AppSubscribeMsgVO reqVO) {
System.out.println("------------------------");
System.out.println(JsonUtils.toJsonPrettyString(reqVO));
}

 

4、业务功能,发送订阅消息

@PostMapping("/miniapp/sendmsg")
public void sendmsg(@RequestBody AppSendMsgVO reqVO) {

Map<String, Object> data = new HashMap<>();
data.put("character_string6", MapUtil.of("value", "867339072445426"));
data.put("thing5", MapUtil.of("value", "南山小区雨棚"));
data.put("time2", MapUtil.of("value", "2025-08-20 19:00"));
data.put("amount9", MapUtil.of("value", "99.99"));
data.put("phrase20", MapUtil.of("value", "开始充电"));

wechatSubscribeServiceWebClient.sendSubscribeMessage(
weiXinService.getAccessToken(),
reqVO.getOpenid(),
reqVO.getTemplateId(), null, data)
.subscribe(response -> {
log.info("发送成功:{}", response);
System.out.println("【最终结果】: " + response);
}, error -> {
log.info("最终错误:{}", error.getMessage());
System.err.println("【最终错误】: " + error.getMessage());
});

// 这行代码会立即执行,不会等待微信的响应
System.out.println("发送请求已触发,等待响应中...");
}

 

public Mono<String> sendSubscribeMessage(String accessToken, String userOpenId, String templateId, String page, Map<String, Object> templateData) {

// String accessToken = "your_cached_access_token"; // 替换为你的Token获取逻辑

// 构建请求体Map
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("touser", userOpenId);
requestBody.put("template_id", templateId);
requestBody.put("page", page);
requestBody.put("data", templateData);


// 1. 打印请求日志(非常重要!)
System.out.println("【发送订阅消息请求】");
System.out.println("URL: https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken);
System.out.println("Request Body: " + JsonUtils.toJsonPrettyString(requestBody)); // 需要import com.fasterxml.jackson.databind.ObjectMapper;


return webClient.post()
.uri(uriBuilder -> uriBuilder
.path("/cgi-bin/message/subscribe/send")
.queryParam("access_token", accessToken)
.build())
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(requestBody)
.retrieve()
.bodyToMono(String.class) // 直接获取响应字符串
.map(response -> {
// 2. 打印响应日志(非常重要!)
System.out.println("【微信服务器响应】");
System.out.println("-----------Response: " + response);
return response;
})
.onErrorResume(e -> {
// 错误处理
System.err.println("【网络请求失败】");
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
return Mono.just("{\"errcode\": -1, \"errmsg\": \"Network Error: " + e.getMessage() + "\"}");
});
}

 

官方文档: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html#%E8%AE%A2%E9%98%85%E6%B6%88%E6%81%AF%E8%AF%AD%E9%9F%B3%E6%8F%90%E9%86%92

 

 

全部评论