当前位置:   article > 正文

微信小程序之订阅消息推送JAVA开发_wxmasubscribemessage

wxmasubscribemessage

2019年10月份微信发布了模板消息整改公告由模板消息更改为订阅消息:

file

具体公告地址:https://developers.weixin.qq.com/community/develop/doc/00008a8a7d8310b6bf4975b635a401?blockType=1 (悄悄告诉大家,大家没事可以看看评论老有意思了,骂声一片。龙哥:我14亿微信用你们教我怎么做产品吗????)

最可恨的是模板消息2020年1月10日下线。那也就是说从1月10日开始模板消息将不能使用。临近1月10日我出一篇关于订阅消息java开发的文章供大家参考。

先给大家看看最终效果:

file

一、开发前期资料准备:

1.1、登录微信小程序后台:https://mp.weixin.qq.com/

file

1.2、寻找Appid和AppSecret配置:路径:首页---》开发---》开发设置。

file

1.3、选择合适的模板消息进行推送:

file

1.4、找到模板id:

file

1.5、下载官方微信开发工具:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html

file

二、小程序订阅消息代码开发:

2.1、创建官方小程序DEMO:

file

2.2、获取code 打开app.js --->13行--->添加console.log("这就是我的code呀:"+res.code)

file

  1. 代码:
  2. console.log("这就是我的code呀:"+res.code)

2.3、添加一个按钮(可有可无)

file

2.3、给按钮添加执行函数:

file

  1. ,//记得添加逗号哦。
  2. sendDYMsg: function(e) {
  3. wx.requestSubscribeMessage({
  4. tmplIds: ['ooaZWfK6liHpqDAcnR2hgObdQuh2JqQP2Z_UR6vvraU'],
  5. success(res) {
  6. console.log("可以给用户推送一条中奖通知了。。。");
  7. }
  8. })
  9. }

2.4、获取推送权限:

输出可以给用户推送一条中奖通知了,就可以给用户推送一条消息。用户一直点击---可以一直推送哦~

file

真机调试页面展示:

file

三、服务端(java)代码开发:

3.1、老规矩先查看官网腾讯api文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html

file

3.2、给大家介绍一个关于微信开发的工具类(个人感觉非常优秀,可以自己去看看。):

git地址:https://github.com/Wechat-Group/WxJava

小程序文档地址:http://binary.ac.cn/weixin-java-miniapp-javadoc/

3.2、java工程介绍:

file

3.3、集成pom文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.2.2.RELEASE</version>
  9. <relativePath/>
  10. </parent>
  11. <groupId>cn.cnbuilder</groupId>
  12. <artifactId>sendmsg</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>sendmsg</name>
  15. <description>微信小程序订阅模板消息</description>
  16. <properties>
  17. <!-- base setting -->
  18. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  19. <project.build.locales>zh_CN</project.build.locales>
  20. <project.build.jdk>1.8</project.build.jdk>
  21. <!-- lib versions -->
  22. <WxJava.version>3.6.0</WxJava.version>
  23. </properties>
  24. <dependencies>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-web</artifactId>
  28. </dependency>
  29. <!-- 小程序开发包-->
  30. <dependency>
  31. <groupId>com.github.binarywang</groupId>
  32. <artifactId>weixin-java-miniapp</artifactId>
  33. <version>${WxJava.version}</version>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.projectlombok</groupId>
  37. <artifactId>lombok</artifactId>
  38. <optional>true</optional>
  39. </dependency>
  40. <dependency>
  41. <groupId>cn.hutool</groupId>
  42. <artifactId>hutool-all</artifactId>
  43. <version>4.1.21</version>
  44. </dependency>
  45. <dependency>
  46. <groupId>io.springfox</groupId>
  47. <artifactId>springfox-swagger2</artifactId>
  48. <version>2.9.2</version>
  49. </dependency>
  50. <dependency>
  51. <groupId>io.springfox</groupId>
  52. <artifactId>springfox-swagger-ui</artifactId>
  53. <version>2.9.2</version>
  54. </dependency>
  55. </dependencies>
  56. <build>
  57. <plugins>
  58. <plugin>
  59. <groupId>org.springframework.boot</groupId>
  60. <artifactId>spring-boot-maven-plugin</artifactId>
  61. </plugin>
  62. </plugins>
  63. </build>
  64. </project>

3.4、增加yml文件:

  1. application.yml
  2. spring:
  3. profiles:
  4. active: dev #选择要用那个配置文件
  5. application-dev.yml
  6. #小程序配置信息
  7. wx:
  8. miniapp:
  9. configs:
  10. - appid: xxxxx
  11. secret: xxxxx
  12. token: xxxxxx
  13. aesKey: xxxxxx
  14. msgDataFormat: JSON
  15. #项目端口号访问路径
  16. server:
  17. port: 12001

3.5、增加配置文件:

  1. WxMaConfiguration文件:
  2. package cn.cnbuilder.sendmsg.config;
  3. import cn.binarywang.wx.miniapp.api.WxMaService;
  4. import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
  5. import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
  6. import cn.binarywang.wx.miniapp.bean.WxMaTemplateData;
  7. import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
  8. import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
  9. import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
  10. import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
  11. import com.google.common.collect.Lists;
  12. import com.google.common.collect.Maps;
  13. import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
  14. import me.chanjar.weixin.common.error.WxErrorException;
  15. import org.springframework.beans.factory.annotation.Autowired;
  16. import org.springframework.boot.context.properties.EnableConfigurationProperties;
  17. import org.springframework.context.annotation.Configuration;
  18. import javax.annotation.PostConstruct;
  19. import java.io.File;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.stream.Collectors;
  23. /**
  24. * @author <a href="https://github.com/binarywang">Binary Wang</a>
  25. */
  26. @Configuration
  27. @EnableConfigurationProperties(WxMaProperties.class)
  28. public class WxMaConfiguration {
  29. private WxMaProperties properties;
  30. private static Map<String, WxMaMessageRouter> routers = Maps.newHashMap();
  31. private static Map<String, WxMaService> maServices = Maps.newHashMap();
  32. @Autowired
  33. public WxMaConfiguration(WxMaProperties properties) {
  34. this.properties = properties;
  35. }
  36. public static WxMaService getMaService(String appid) {
  37. WxMaService wxService = maServices.get(appid);
  38. if (wxService == null) {
  39. throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
  40. }
  41. return wxService;
  42. }
  43. public static WxMaMessageRouter getRouter(String appid) {
  44. return routers.get(appid);
  45. }
  46. @PostConstruct
  47. public void init() {
  48. List<WxMaProperties.Config> configs = this.properties.getConfigs();
  49. if (configs == null) {
  50. throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
  51. }
  52. maServices = configs.stream()
  53. .map(a -> {
  54. WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
  55. config.setAppid(a.getAppid());
  56. config.setSecret(a.getSecret());
  57. config.setToken(a.getToken());
  58. config.setAesKey(a.getAesKey());
  59. config.setMsgDataFormat(a.getMsgDataFormat());
  60. WxMaService service = new WxMaServiceImpl();
  61. service.setWxMaConfig(config);
  62. routers.put(a.getAppid(), this.newRouter(service));
  63. return service;
  64. }).collect(Collectors.toMap(s -> s.getWxMaConfig().getAppid(), a -> a));
  65. }
  66. private WxMaMessageRouter newRouter(WxMaService service) {
  67. final WxMaMessageRouter router = new WxMaMessageRouter(service);
  68. router
  69. .rule().handler(logHandler).next()
  70. .rule().async(false).content("模板").handler(templateMsgHandler).end()
  71. .rule().async(false).content("文本").handler(textHandler).end()
  72. .rule().async(false).content("图片").handler(picHandler).end()
  73. .rule().async(false).content("二维码").handler(qrcodeHandler).end();
  74. return router;
  75. }
  76. private final WxMaMessageHandler templateMsgHandler = (wxMessage, context, service, sessionManager) -> {
  77. service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder()
  78. .templateId("此处更换为自己的模板id")
  79. .formId("自己替换可用的formid")
  80. .data(Lists.newArrayList(
  81. new WxMaTemplateData("keyword1", "339208499", "#173177")))
  82. .toUser(wxMessage.getFromUser())
  83. .build());
  84. return null;
  85. };
  86. private final WxMaMessageHandler logHandler = (wxMessage, context, service, sessionManager) -> {
  87. System.out.println("收到消息:" + wxMessage.toString());
  88. service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson())
  89. .toUser(wxMessage.getFromUser()).build());
  90. return null;
  91. };
  92. private final WxMaMessageHandler textHandler = (wxMessage, context, service, sessionManager) -> {
  93. service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息")
  94. .toUser(wxMessage.getFromUser()).build());
  95. return null;
  96. };
  97. private final WxMaMessageHandler picHandler = (wxMessage, context, service, sessionManager) -> {
  98. try {
  99. WxMediaUploadResult uploadResult = service.getMediaService()
  100. .uploadMedia("image", "png",
  101. ClassLoader.getSystemResourceAsStream("tmp.png"));
  102. service.getMsgService().sendKefuMsg(
  103. WxMaKefuMessage
  104. .newImageBuilder()
  105. .mediaId(uploadResult.getMediaId())
  106. .toUser(wxMessage.getFromUser())
  107. .build());
  108. } catch (WxErrorException e) {
  109. e.printStackTrace();
  110. }
  111. return null;
  112. };
  113. private final WxMaMessageHandler qrcodeHandler = (wxMessage, context, service, sessionManager) -> {
  114. try {
  115. final File file = service.getQrcodeService().createQrcode("123", 430);
  116. WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);
  117. service.getMsgService().sendKefuMsg(
  118. WxMaKefuMessage
  119. .newImageBuilder()
  120. .mediaId(uploadResult.getMediaId())
  121. .toUser(wxMessage.getFromUser())
  122. .build());
  123. } catch (WxErrorException e) {
  124. e.printStackTrace();
  125. }
  126. return null;
  127. };
  128. }
  129. WxMaProperties文件:
  130. package cn.cnbuilder.sendmsg.config;
  131. import java.util.List;
  132. import org.springframework.boot.context.properties.ConfigurationProperties;
  133. import lombok.Data;
  134. /**
  135. * @author <a href="https://github.com/binarywang">Binary Wang</a>
  136. */
  137. @Data
  138. @ConfigurationProperties(prefix = "wx.miniapp")
  139. public class WxMaProperties {
  140. private List<Config> configs;
  141. @Data
  142. public static class Config {
  143. /**
  144. * 设置微信小程序的appid
  145. */
  146. private String appid;
  147. /**
  148. * 设置微信小程序的Secret
  149. */
  150. private String secret;
  151. /**
  152. * 设置微信小程序消息服务器配置的token
  153. */
  154. private String token;
  155. /**
  156. * 设置微信小程序消息服务器配置的EncodingAESKey
  157. */
  158. private String aesKey;
  159. /**
  160. * 消息格式,XML或者JSON
  161. */
  162. private String msgDataFormat;
  163. }
  164. }
  165. swagger配置(可配可不配)
  166. package cn.cnbuilder.sendmsg.config;
  167. import io.swagger.annotations.ApiOperation;
  168. import org.springframework.context.annotation.Bean;
  169. import org.springframework.context.annotation.Configuration;
  170. import springfox.documentation.builders.RequestHandlerSelectors;
  171. import springfox.documentation.spi.DocumentationType;
  172. import springfox.documentation.spring.web.plugins.Docket;
  173. import springfox.documentation.swagger2.annotations.EnableSwagger2;
  174. @Configuration
  175. @EnableSwagger2
  176. public class SwaggerConfig {
  177. @Bean
  178. public Docket swaggerSpringMvcPlugin() {
  179. return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).build();
  180. }
  181. }

3.6、根据code获取openid:

code:(重点)只能使用一次,并且只有5分钟有效期。划线,期末考!!!!!

file

获取openid:

file

  1. package cn.cnbuilder.sendmsg.controller;
  2. import cn.binarywang.wx.miniapp.api.WxMaService;
  3. import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
  4. import cn.binarywang.wx.miniapp.bean.WxMaSubscribeData;
  5. import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
  6. import cn.cnbuilder.sendmsg.config.WxMaConfiguration;
  7. import cn.hutool.json.JSONUtil;
  8. import io.swagger.annotations.Api;
  9. import io.swagger.annotations.ApiImplicitParam;
  10. import io.swagger.annotations.ApiImplicitParams;
  11. import io.swagger.annotations.ApiOperation;
  12. import me.chanjar.weixin.common.error.WxErrorException;
  13. import org.apache.commons.lang3.StringUtils;
  14. import org.springframework.web.bind.annotation.*;
  15. import java.util.ArrayList;
  16. /**
  17. * 微信小程序订阅消息推送接口
  18. * create By KingYiFan on 2019/01/06
  19. */
  20. @Api("微信小程序订阅消息推送接口")
  21. @RestController
  22. @RequestMapping("/wx/msg/{appId}")
  23. public class MsgController {
  24. /**
  25. * 根据code获取openid
  26. * create By KingYiFan 2020/01/06
  27. */
  28. @ApiOperation(value = "根据code获取openid", notes = "根据code获取openid")
  29. @ApiImplicitParams({
  30. @ApiImplicitParam(name = "appId", value = "小程序appId", dataType = "string", paramType = "query"),
  31. @ApiImplicitParam(name = "code", value = "用户code", dataType = "String", paramType = "query")})
  32. @GetMapping("/getOpenidByCode")
  33. public String login(@PathVariable String appId, String code) {
  34. if (StringUtils.isBlank(code)) {
  35. return "code都没有给俺,你哪啥换俺的openid啊?????";
  36. }
  37. try {
  38. final WxMaService wxService = WxMaConfiguration.getMaService(appId);
  39. //根据code获取openid
  40. WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
  41. return session.getOpenid();
  42. } catch (WxErrorException e) {
  43. e.printStackTrace();
  44. }
  45. return "我猜你code肯定失效了........要不就是过期了呢.......您觉得呢???";
  46. }
  47. }

测试:获取openid

file

用同样的code进行获取openid,腾讯会返回code已被使用。

file

3.6、最终环节进行小程序订阅消息推送

订阅消息传参和模板消息是不一样的,需要根据人家规则进行填写,加了正则校验了。

file

模板消息和订阅消息传参区别:

file

  1. java代码
  2. /**
  3. * 微信小程序推送订阅消息
  4. * create By KingYiFan on 2020/01/06
  5. */
  6. @ApiOperation(value = "微信小程序推送订阅消息", notes = "微信小程序推送订阅消息")
  7. @ApiImplicitParams({
  8. @ApiImplicitParam(name = "appId", value = "小程序appId", dataType = "string", paramType = "query"),
  9. @ApiImplicitParam(name = "openId", value = "用户openId", dataType = "String", paramType = "query")})
  10. @GetMapping(value = "/sendDYTemplateMessage")
  11. @ResponseBody
  12. public Object sendDYTemplateMessage(@PathVariable String appId, String openId) throws Exception {
  13. WxMaSubscribeMessage subscribeMessage = new WxMaSubscribeMessage();
  14. //跳转小程序页面路径
  15. subscribeMessage.setPage("pages/index/index");
  16. //模板消息id
  17. subscribeMessage.setTemplateId("ooaZWfK6liHpqDAcnR2hgObdQuh2JqQP2Z_UR6vvraU");
  18. //给谁推送 用户的openid (可以调用根据code换openid接口)
  19. subscribeMessage.setToUser(openId);
  20. //==========================================创建一个参数集合========================================================
  21. ArrayList<WxMaSubscribeData> wxMaSubscribeData = new ArrayList<>();
  22. // 订阅消息参数值内容限制说明
  23. // ---摘自微信小程序官方:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
  24. // 参数类别 参数说明 参数值限制 说明
  25. // thing.DATA 事物 20个以内字符 可汉字、数字、字母或符号组合
  26. // number.DATA 数字 32位以内数字 只能数字,可带小数
  27. // letter.DATA 字母 32位以内字母 只能字母
  28. // symbol.DATA 符号 5位以内符号 只能符号
  29. // character_string.DATA 字符串 32位以内数字、字母或符号 可数字、字母或符号组合
  30. // time.DATA 时间 24小时制时间格式(支持+年月日) 例如:15:01,或:201910115:01
  31. // date.DATA 日期 年月日格式(支持+24小时制时间) 例如:2019101日,或:201910115:01
  32. // amount.DATA 金额 1个币种符号+10位以内纯数字,可带小数,结尾可带“元” 可带小数
  33. // phone_number.DATA 电话 17位以内,数字、符号 电话号码,例:+86-0766-66888866
  34. // car_number.DATA 车牌 8位以内,第一位与最后一位可为汉字,其余为字母或数字 车牌号码:粤A8Z888
  35. // name.DATA 姓名 10个以内纯汉字或20个以内纯字母或符号 中文名10个汉字内;纯英文名20个字母内;中文和字母混合按中文名算,10个字内
  36. // phrase.DATA 汉字 5个以内汉字 5个以内纯汉字,例如:配送中
  37. //第一个内容: 奖品名称
  38. WxMaSubscribeData wxMaSubscribeData1 = new WxMaSubscribeData();
  39. wxMaSubscribeData1.setName("thing1");
  40. wxMaSubscribeData1.setValue("充气娃娃豪华版");
  41. //每个参数 存放到大集合中
  42. wxMaSubscribeData.add(wxMaSubscribeData1);
  43. // 第二个内容:用户昵称
  44. WxMaSubscribeData wxMaSubscribeData2 = new WxMaSubscribeData();
  45. wxMaSubscribeData2.setName("name6");
  46. wxMaSubscribeData2.setValue("非苍老鸡不娶");
  47. wxMaSubscribeData.add(wxMaSubscribeData2);
  48. // 第三个内容:领取方式
  49. WxMaSubscribeData wxMaSubscribeData3 = new WxMaSubscribeData();
  50. wxMaSubscribeData3.setName("thing7");
  51. wxMaSubscribeData3.setValue("请联系您的专属老鸡");
  52. wxMaSubscribeData.add(wxMaSubscribeData3);
  53. // 第四个内容:专属老师
  54. WxMaSubscribeData wxMaSubscribeData4 = new WxMaSubscribeData();
  55. wxMaSubscribeData4.setName("name3");
  56. wxMaSubscribeData4.setValue("小泽玛利亚老鸡");
  57. wxMaSubscribeData.add(wxMaSubscribeData4);
  58. // 第五个内容:温馨提醒
  59. WxMaSubscribeData wxMaSubscribeData5 = new WxMaSubscribeData();
  60. wxMaSubscribeData5.setName("thing4");
  61. wxMaSubscribeData5.setValue("小撸伤身,强撸灰飞烟灭~");
  62. wxMaSubscribeData.add(wxMaSubscribeData5);
  63. //把集合给大的data
  64. subscribeMessage.setData(wxMaSubscribeData);
  65. //=========================================封装参数集合完毕========================================================
  66. try {
  67. //获取微信小程序配置:
  68. final WxMaService wxService = WxMaConfiguration.getMaService(appId);
  69. //进行推送
  70. wxService.getMsgService().sendSubscribeMsg(subscribeMessage);
  71. return "推送成功";
  72. } catch (Exception e) {
  73. e.printStackTrace();
  74. }
  75. return "推送失败";
  76. }

进行代码推送:

file

我收到一条消息,我还以为有那个女生给我聊天呢?说不定就告别单身狗了哈哈哈哈~~

file

竟然发现自己中奖了,吓得我感觉打开:卧槽(奈何自己没文化,一句卧槽行天下。) 好牛逼的奖项!!!

file

到现在微信小程序订阅消息推送就到此结束了,是不是超级简单那种。

给大家分享一个,只给用户提示一次,下次就不用提示就可以一直发送通知的方案: 微信设置了总是保持以上选择,不在询问按钮,只要把这对勾给点击上。下次点击通知函数,就不会给用户提示哦。 我给点击了按钮,到现在我都没找到从哪能开启这个提示。

file

终、、本文就是小程序之java推送订阅消息,有什么问题可以联系我。


本文用到的小程序代码和java代码下载路径: https://download.csdn.net/download/weixin_39984161/12089252

没有积分可以移步到:https://blog.cnbuilder.cn/archives/wxdymsg

鼓励作者写出更好的技术文档,就请我喝一瓶哇哈哈哈哈哈哈哈。。你们的赞助决定我更新的速度哦!

微信:

支付宝:


  1. 感谢一路支持我的人。。。。。
  2. Love me and hold me
  3. QQ:6967380416年老号)
  4. EMAIL:itw@tom.com
  5. 友链交换
  6. 如果有兴趣和本博客交换友链的话,请按照下面的格式在评论区进行评论,我会尽快添加上你的链接。

  1. 网站名称:猿码优创
  2. 网站地址:http://blog.cnbuilder.cn
  3. 网站描述:年少是你未醒的梦话,风华是燃烬的彼岸花。
  4. 网站Logo/头像: [头像地址](https://blog.cnbuilder.cn/upload/2018/7/avatar20180720144536200.jpg)

欢迎关注猿码优创(联系小优优进内部群哦,新鲜技术优先更新):

file

 

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

闽ICP备14008679号