赞
踩
官方接口链接:
1、准备号小程序
2、小程序在订阅消息端创建消息模板拿到TemplateID
3、 前端需要配置消息ID,订阅服务通知
4、后端调接口发送通知到用户openId
在微信小程序添加订阅消息模板
1、注意消息模板的ID,前端和后端都需要
2、点击详情下面有对应的字段内容,后端需要返回对应字段JSON格式数据
封装成工具类使用
直接调用sendTemplateMsg()方法即可。
需要参数:
a、用户的openId、
b、消息模板ID
c、消息主体的JSON字段数据
注意:注意JSON格式,参照官网
如果JSON格式不对:(时间格式不能包含字母或无关符号)
result:{"errcode":47003,"errmsg":"argument invalid! data.character_string22.value rid: 66012b9d-00baed03-2e813aea"
1、构建工具类
- /**
- * 微信消息通知
- */
- public class WxMessageConfig {
- private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
-
- /**
- * 发送模板消息 注意格式
- */
- public static boolean sendTemplateMsg(String openId, String templateId,WxMessageDto wxMessageDto) {
- String access_token = getAccessToken();
-
- Map<String, Object> paramMap = wxMessageMap(wxMessageDto);
- paramMap.put("touser", openId);
- // 模版
- paramMap.put("template_id", templateId);
- // 跳转小程序(不加微信界面没有跳转那一行)
- paramMap.put("page", "index");
-
- String url = WxConstants.POST_MESSAGE_URL;
- String jsonStr = null;
- try {
- // 转JSON
- ObjectMapper objectMapper = new ObjectMapper();
- jsonStr = objectMapper.writeValueAsString(paramMap);
- } catch (JsonProcessingException e) {
- log.error("消息通知转JSON格式异常");
- e.printStackTrace();
- }
- try {
- jsonStr = HttpUtil.post(url, access_token, jsonStr);
- } catch (Exception e) {
- log.error("小程序服务通知异常-转化异常", e);
- }
- JSONObject jsonObj = JSONObject.parseObject(jsonStr);
- String errcode = jsonObj.get("errcode").toString();
- Object errmsg = jsonObj.get("errmsg");
- if (!errcode.equals("0")) {
- log.error("微信通知消息发送失败:code=" + errcode + "msg=" + errmsg);
- return false;
- }
- return true;
- }
-
- /**
- * 获取access_Token(发送消息需要)
- * @return
- */
- private static String getAccessToken() {
- /**
- * 非spring环境获取bean(注入redis工具类) 工具类 redis获取缓存的的token
- */
- RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
- /**
- * public static final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
- */
- String access_token = redisCache.getCacheObject("wx_access_token");
- if (access_token == null) {
- String url = WxConstants.GET_ACCESS_TOKEN_URL.replace("APPID", WxConstants.APPID)
- .replace("APPSECRET", WxConstants.SECRET);
- String jsonStr = HttpUtil.httpGet(url);
- JSONObject jsonObj = JSONObject.parseObject(jsonStr);
- access_token = jsonObj.getString("access_token");
- int expires_in = Integer.parseInt(jsonObj.getString("expires_in"));
- redisCache.setCacheObject("wx_access_token", access_token, expires_in, TimeUnit.SECONDS);
- }
- return access_token;
- }
-
- /**
- * 构建消息主体JSON数据
- * @param wxMessageDto
- * @return
- */
- public static Map<String, Object> wxMessageMap(WxMessageDto wxMessageDto){
- // 时间格式
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
- // 格式化时间
- String formattedDateTime = wxMessageDto.getTime().format(formatter);
-
- HashMap<String, Object> paramMap = new HashMap<>();
- // 创建消息内容的 Map 对象
- Map<String, Object> messageContent = new HashMap<>();
- messageContent.put("thing13", new HashMap<String, Object>() {{
- put("value", wxMessageDto.getProductName());
- }});
- messageContent.put("amount4", new HashMap<String, Object>() {{
- put("value", wxMessageDto.getPrice());
- }});
- messageContent.put("character_string22", new HashMap<String, Object>() {{
- put("value", wxMessageDto.getOrderNo());
- }});
- messageContent.put("thing24", new HashMap<String, Object>() {{
- put("value", wxMessageDto.getAddress());
- }});
- messageContent.put("time23", new HashMap<String, Object>() {{
- put("value", formattedDateTime);
- }});
- paramMap.put("data", messageContent);
-
- return paramMap;
- }
- }
2、微信相关链接、消息模板ID常量
- /**
- * 微信相关参数
- */
- public class WxConstants {
-
- public static final String APPID = "wxexxxxxxxxxxx";
- public static final String SECRET = "b9bc54xxxxxxxxxxxxxxxxxxxxxx";
- // public static final String GET_ACK_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code"; // 网页
- public static final String GET_ACK_URL2 = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_cod"; // 小程序
-
- public static final String GET_USER_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID"; // 网页
- // public static final String POST_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN";
-
- // 小程序消息通知
- public static final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
- public static final String POST_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send";
- public static final String WX_TEMPLATE_ID_ORDER1 = "8u_2j-thz_6TDIiEZUXOWqwNNbwDoVbdXIwlWB5K91k";
- }
3、消息主体的dto
- /**
- * 消息模类主体数据
- */
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- public class WxMessageDto implements Serializable {
- private String productName;
- private String price;
- private String orderNo;
- private String address;
- private LocalDateTime time;
- }
用微信开发工具做前端测试:
前端uni-app只需要发送对应请求订阅消息即可(官方规定不能页面加载触发订阅请求,只能点击某个事件触发订阅)
- <template>
- <view class="content">
- <image class="logo" src="/static/logo.png"></image>
- <view class="text-area">
- <text class="title">{{title}}</text>
- </view>
- <view >
- <text class="title">{{title}}</text>
- </view>
-
- <view class="content">
- <button @click="requestSubscription">点击订阅消息</button>
- </view>
- </view>
- </template>
-
- <script>
- export default {
- data() {
- return {
- title: 'Hello2',
- }
- },
- onLoad() {
- const that = this; // 保存组件实例的引用
- wx.login({
- success (res) {
- console.log('登录ok!' + res.code);
- that.title = res.code;
- }
- });
- },
- methods: {
- requestSubscription() {
- console.log('点击了订阅1')
- wx.requestSubscribeMessage({
- tmplIds: ['8u_2j-thz_6TDIiEZUXOWqwNNbwDoVbdXIwlWB5K91k'], // 数组,最多3个订阅
- success (res) {
- console.log('订阅消息结果', res);
- // 处理订阅消息的结果
- },
- error(){
- console.error(222)
- }
- });
- }
- }
- }
- </script>
-
- <style>
- .content {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
-
- .logo {
- height: 200rpx;
- width: 200rpx;
- margin-top: 200rpx;
- margin-left: auto;
- margin-right: auto;
- margin-bottom: 50rpx;
- }
-
- .text-area {
- display: flex;
- justify-content: center;
- }
-
- .title {
- font-size: 36rpx;
- color: #8f8f94;
- user-select: text;
- }
- </style>
点击订阅即可,每次最多订阅3个(手机端是下面弹出订阅,同时可以选择订阅!此处用模拟器测试前端订阅)
1、springboot测试
- @SpringBootTest
- @RunWith(SpringRunner.class)
- public class AppTest {
-
- @Test
- public void shouldAnswerWithTrue() throws Exception {
- String openId = "otvf_5HrOcky90_sqST2kvKTvr1k"; // 用户的openId
- String templateId = WxConstants.WX_TEMPLATE_ID_ORDER1; // 模板消息Id
-
- WxMessageDto wxMessageDto = new WxMessageDto(); // 消息主体
- wxMessageDto.setProductName("黄铜");
- wxMessageDto.setPrice("36.8元");
- wxMessageDto.setOrderNo("2024032516282222hs9999");
- wxMessageDto.setAddress("四川省成都市双流区龙桥地铁站");
- wxMessageDto.setTime(LocalDateTime.now());
-
- boolean boo = WxMessageConfig.sendTemplateMsg(openId, templateId, wxMessageDto);
- System.out.println("=====================================");
- System.out.println(boo);
- }
2、控制台输出:
注意:报错就参考官方错误码。注意用户是否订阅,不然报错:
用户为订阅报错:
或者代码配置参数问题:
result:{"errcode":47003,"errmsg":"argument invalid! data.character_string22.value rid: 66012b9d-00baed03-2e813aea"
发送成功字样 errcode:0 errmsg:ok
3、微信的服务通知提醒
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。