当前位置:   article > 正文

spring boot 发送微信小程序订阅消息

spring boot 发送微信小程序订阅消息

首先我们需要订阅一个消息:

订阅教程本文章并未提起,感兴趣的同学自行百度。

我们可以看到订阅消息中【消息内容】有很多参数,我们在发送消息时就需要将这些参数进行填充,当然填充的时候要注意格式,如果格式不对还是会报错。 

教程开始:

1、创建一个实体类,用来填充对应的数据

  1. import lombok.Data;
  2. import java.util.Date;
  3. @Data
  4. public class LeaveResultMsg {
  5. /**
  6. * 请假结果通知 -- 模板ID
  7. */
  8. public static String RESULTID = "Qd0*************T8k";
  9. /**
  10. * 请假人OpenId
  11. */
  12. private String openId;
  13. /**
  14. * 请假人名称
  15. */
  16. private String name;
  17. /**
  18. * 请假开始时间
  19. */
  20. private Date startTime;
  21. /**
  22. * 请假结束时间
  23. */
  24. private Date endTime;
  25. /**
  26. * 审核人
  27. */
  28. private String examine;
  29. /**
  30. * 请假结果(同意,不同意)
  31. */
  32. private String status;
  33. /**
  34. * 请假类型
  35. */
  36. private String type;
  37. }

2、实现类

  1. import cn.hutool.http.HttpUtil;
  2. import cn.hutool.json.JSONUtil;
  3. import lombok.RequiredArgsConstructor;
  4. import org.dromara.common.api.service.ApiWeChatUtilsService;
  5. import org.dromara.common.api.utils.DateUtil;
  6. import org.dromara.school.domain.LeaveResultMsg;
  7. import org.dromara.school.service.ISubscribeMsgService;
  8. import org.dromara.system.service.ISysConfigService;
  9. import org.springframework.stereotype.Service;
  10. import java.nio.charset.StandardCharsets;
  11. import java.util.Collections;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. @Service
  15. @RequiredArgsConstructor
  16. public class SubscribeMsgService implements ISubscribeMsgService {
  17. private final static String SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";
  18. // private final WeChatTokenUtil weChatTokenUtil;
  19. private final ISysConfigService configService;
  20. private final ApiWeChatUtilsService apiWeChatUtilsService;
  21. /**
  22. * 请假结果通知
  23. * @param msg
  24. * @throws Exception
  25. */
  26. public void leaveResultW(LeaveResultMsg msg){
  27. try {
  28. System.out.println(msg.toString());
  29. Map<String, Object> params = baseParams(msg.getOpenId());
  30. params.put("template_id", LeaveResultMsg.RESULTID);
  31. Map<String, Object> data = new HashMap<String, Object>();
  32. // 传入转换后的 UTF-8 编码字节数组
  33. data.put("thing2", Collections.singletonMap("value", new String(msg.getName().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8)));
  34. data.put("time3", Collections.singletonMap("value", DateUtil.getStringDateFormat(msg.getStartTime())));
  35. data.put("time4",Collections.singletonMap("value", DateUtil.getStringDateFormat(msg.getEndTime())));
  36. data.put("thing7", Collections.singletonMap("value",new String(msg.getExamine().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8)));
  37. data.put("phrase1",Collections.singletonMap("value", new String(msg.getStatus().getBytes(StandardCharsets.UTF_8),StandardCharsets.UTF_8)));
  38. params.put("data", data);
  39. System.err.println(params);
  40. String post;
  41. try {
  42. post = HttpUtil.post(SEND_URL + apiWeChatUtilsService.getAccessTokenByRedis(0), JSONUtil.toJsonStr(params));
  43. }catch (Exception e) {
  44. post = HttpUtil.post(SEND_URL + apiWeChatUtilsService.getAccessTokenByRedis(1), JSONUtil.toJsonStr(params));
  45. }
  46. // String post = HttpUtil.post(SEND_URL + weChatTokenUtil.getAccessToken(), JSONUtil.toJsonStr(params));
  47. System.err.println(post);
  48. }catch (Exception e){
  49. e.printStackTrace();
  50. }
  51. }
  52. }

关联到的其他方法:

3、组装参数

  1. @Service
  2. @RequiredArgsConstructor
  3. public class SubscribeMsgService implements ISubscribeMsgService {
  4. /**
  5. * 组装基础参数
  6. *
  7. * @param openId
  8. * @return
  9. */
  10. private Map<String, Object> baseParams(String openId) {
  11. Map<String, Object> map = new HashMap<String, Object>();
  12. String touser = openId;
  13. String page = "/pages/home/index";
  14. // 微信-小程序订阅跳转版本,developer:开发版,trial:体验版,formal:正式版
  15. String miniprogramState = configService.selectConfigByKey("***.version"); //小程序版本
  16. map.put("touser", touser);
  17. map.put("page", page);
  18. map.put("miniprogram_state", miniprogramState);
  19. return map;
  20. }
  21. }

4、时间转换

  1. import java.text.ParseException;
  2. import java.text.SimpleDateFormat;
  3. import java.time.LocalDate;
  4. import java.time.ZoneId;
  5. import java.time.temporal.ChronoUnit;
  6. import java.util.Calendar;
  7. import java.util.Date;
  8. import java.util.TimeZone;
  9. public class DateUtil {
  10. /**
  11. * 获取当前时间,转换成String(yyyy-MM-dd HH:mm:ss)
  12. * @return yyyyMMddHHmmss
  13. */
  14. public static String getStringDateFormat(Date date){
  15. //Thu May 11 11:08:15 GMT+08:00 2023
  16. //设置日期格式
  17. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  18. //获取String类型的时间
  19. String str = df.format(date);
  20. return str;
  21. }
  22. }

5、获取token

  1. package org.dromara.system.dubbo;
  2. import cn.hutool.http.HttpUtil;
  3. import cn.hutool.json.JSONUtil;
  4. import lombok.RequiredArgsConstructor;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.dromara.common.api.service.ApiWeChatUtilsService;
  7. import org.dromara.common.api.utils.StringUtil;
  8. import org.dromara.common.api.utils.https.HttpClientUtil;
  9. import org.dromara.common.core.exception.ServiceException;
  10. import org.dromara.common.core.exception.base.BaseException;
  11. import org.dromara.common.core.utils.StringUtils;
  12. import org.dromara.common.redis.utils.RedisUtils;
  13. import org.dromara.system.service.ISysConfigService;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import org.springframework.http.HttpEntity;
  16. import org.springframework.http.HttpHeaders;
  17. import org.springframework.http.ResponseEntity;
  18. import org.springframework.stereotype.Service;
  19. import org.springframework.util.MultiValueMap;
  20. import org.springframework.web.client.RestTemplate;
  21. import java.time.Duration;
  22. import java.util.HashMap;
  23. import java.util.Map;
  24. /**
  25. * 字典 业务层处理
  26. *
  27. * @author Lion Li
  28. */
  29. @RequiredArgsConstructor
  30. @Service
  31. @Slf4j
  32. public class ApiWeChatUtilsServiceImpl implements ApiWeChatUtilsService {
  33. @Autowired
  34. ISysConfigService sysConfigService;
  35. /**
  36. * 0正常获取,1可能token失效了,重新获取(线上线下冲突)
  37. * @return
  38. */
  39. @Override
  40. public String getAccessTokenByRedis(int state) {
  41. String key = "wx.access_token";
  42. String accessToken;
  43. if (state==0){
  44. accessToken = RedisUtils.getCacheObject(key);
  45. if (StringUtil.isEmpty(accessToken)) {
  46. accessToken = getAccessTokenByAddress();
  47. if (!StringUtil.isEmpty(accessToken))
  48. RedisUtils.setCacheObject(key, accessToken, Duration.ofMinutes(120));
  49. }
  50. }else {
  51. accessToken = getAccessTokenByAddress();
  52. if (!StringUtil.isEmpty(accessToken))
  53. RedisUtils.setCacheObject(key, accessToken, Duration.ofMinutes(120));
  54. }
  55. return accessToken;
  56. }
  57. private String getAccessTokenByAddress() {
  58. String appid = sysConfigService.selectConfigByKey("***.appid");
  59. String secret =sysConfigService.selectConfigByKey("***.secret");
  60. String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
  61. String result = HttpUtil.get(url);
  62. HashMap<String, String> resultMap = (HashMap<String, String>) JSONUtil.parse(result).toBean(HashMap.class);
  63. String accessToken = resultMap.get("access_token");
  64. if (StringUtil.isEmpty(accessToken))
  65. throw new BaseException(resultMap.get("errmsg"));
  66. return accessToken;
  67. }
  68. /**
  69. * 获取手机号
  70. * @param code
  71. * @return
  72. */
  73. @Override
  74. public String getPhoneByCode(String code) {
  75. String accessToken = getAccessTokenByRedis(0);
  76. String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
  77. HttpHeaders headers = new HttpHeaders();
  78. RestTemplate restTemplate = new RestTemplate();
  79. HttpEntity<Map<String, String>> httpEntity;
  80. if (code.contains("code")) {
  81. httpEntity = new HttpEntity(code,headers);
  82. }else {
  83. Map<String, String> params = new HashMap<>();
  84. params.put("code", code);
  85. httpEntity = new HttpEntity(params,headers);
  86. }
  87. ResponseEntity<Object> response = restTemplate.postForEntity(url, httpEntity, Object.class, new Object[0]);
  88. HashMap<String, Object> resultMap = (HashMap<String, Object>) JSONUtil.parse(response.getBody()).toBean(HashMap.class);
  89. int errcode = ((Integer) resultMap.get("errcode")).intValue();
  90. if (errcode != 0) {
  91. if (errcode == 40001){
  92. //可能会出现多个服务器重复获取,导致accessToken失效的情况
  93. accessToken = getAccessTokenByRedis(1);
  94. url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
  95. response = restTemplate.postForEntity(url, httpEntity, Object.class, new Object[0]);
  96. resultMap = (HashMap<String, Object>) JSONUtil.parse(response.getBody()).toBean(HashMap.class);
  97. errcode = ((Integer) resultMap.get("errcode")).intValue();
  98. if (errcode != 0){
  99. throw new ServiceException("获取手机号出错,报错类型------>{}",errcode);
  100. }
  101. }else {
  102. throw new ServiceException("获取手机号出错,报错类型------>{}",errcode);
  103. }
  104. }
  105. HashMap<String, Object> phoneInfo = (HashMap<String, Object>) JSONUtil.parse(resultMap.get("phone_info")).toBean(HashMap.class);
  106. String phone = (String) phoneInfo.get("purePhoneNumber");
  107. return phone;
  108. }
  109. /**
  110. * 获取手机号2
  111. * @param code
  112. * @return
  113. */
  114. public String getPhoneByCode2(String code) {
  115. String accessToken = getAccessTokenByRedis(0);
  116. String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
  117. // String jsonStr = "{\"code\":\"" + code + "\"}";
  118. String httpOrgCreateTestRtn = HttpClientUtil.doPost(url, code, "utf-8");
  119. System.out.println("获取到的手机号----------->"+httpOrgCreateTestRtn);
  120. return httpOrgCreateTestRtn;
  121. }
  122. /**
  123. * 获取openid
  124. * @param code
  125. * @return
  126. */
  127. @Override
  128. public String getOpenidByCode(String code) {
  129. String appid = sysConfigService.selectConfigByKey("weChat.mini.appid");
  130. String secret =sysConfigService.selectConfigByKey("weChat.mini.secret");
  131. //https://api.weixin.qq.com/sns/jscode2session
  132. String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + secret +
  133. "&js_code=" + code + "&grant_type=authorization_code";
  134. String result = HttpUtil.get(url);
  135. HashMap<String, String> resultMap = (HashMap<String, String>) JSONUtil.parse(result).toBean(HashMap.class);
  136. String openId = resultMap.get("openid");
  137. // System.out.println("获取到的openId----------->"+openId);
  138. if (StringUtils.isNotEmpty(openId)) {
  139. return openId;
  140. } else {
  141. throw new ServiceException("用户信息获取错误,请稍候重试",Integer.valueOf(resultMap.get("errcode")) );
  142. }
  143. }
  144. }

以上用到的config类是配置类,配置的内容是由你申请小程序时候得到的数据。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/982499
推荐阅读
相关标签
  

闽ICP备14008679号