写点什么

spring-boot-route(二十三)开发微信公众号

用户头像
Java旅途
关注
发布于: 2020 年 10 月 23 日

在讲微信公众号开发之前,先来大概了解一下微信公众号。微信公众号大体上可以分为服务号和订阅号,订阅号和服务号的区别如下:


  1. 服务号可以申请微信支付功能。

  2. 服务号只能由企业申请,订阅号可以有企业或个人申请。

  3. 订阅号和服务号每月推送消息次数不同,订阅号每天可以推送一次,服务号每月可以推送四次。

  4. 服务号推送的消息会出现在用户的聊天列表中,而订阅号推送的消息显示在订阅号文件夹中。

  5. 还有一些其他接口功能的区别和限制,总的来说服务号支持更高级的功能开发。


订阅号更加偏向于向用户传递咨询,一般各种技术类公众号都属于订阅号,订阅号的消息推送并不会有太显眼的提醒,如果你想让某个公众号的推送内容更加显眼,可以选择置为星标。置为星标后公众号会显示在所有订阅号的最顶部,同时收到消息后会有黄色五角星星标提醒。


一 公众号配置服务器


微信官方提供了非常完善的接入文档,如果想了解文档的具体内容,直接浏览器搜索微信开发文档就可以了。但是为了方便开发,一般不会直接去根据微信开发文档进行开发,gitee 上有许多开源项目对微信开发文档进行了封装,这里我使用mica-weixin开发包进行演示,mica-weixinjfinal-weixin的 boot 版本。


配置服务器信息很简单,具体流程就是微信服务发送请求一个请求给业务服务器,业务服务器验证请求后给微信服务一个响应


1.1 搭建业务服务


本地搭建一个spring-boot-weixin的项目,使用内网穿透工具进行穿透,使其可以与外网进行通信。


1.1.1 引入`mica-weixin`依赖


<dependency>    <groupId>net.dreamlu</groupId>    <artifactId>mica-weixin</artifactId>    <version>2.0.1</version></dependency>
复制代码


1.1.2 配置公众号信息


mica-weixin通过配置文件进行公众号信息的配置,如果你想通过数据库配置公众号信息,可以参考我以前写过的一篇文章jfinal-weixin自定义配置支持多公众号


dream:  weixin:    wx-configs:    - appId: xxxxxx      appSecret: xxxxxx      token: javatrip      encodingAesKey: xxxxxx
复制代码


appIdappSecret可在公众号后台进行查看,具体位置在菜单**开发—>基本配置**中,其中appSecret要妥善保管,现在公众号已经不支持查看appSecret了,如果你忘了appSecret,只能进行重置。


1.1.3 开发消息校验接口


mica-weixin已经为我们提供好了消息校验接口,只需要继承DreamMsgControllerAdapter就可以了。


@WxMsgController("/weixin/wx")public class WeiXinMsgController extends DreamMsgControllerAdapter {    @Override    protected void processInFollowEvent(InFollowEvent inFollowEvent) {    }
@Override protected void processInTextMsg(InTextMsg inTextMsg) { }
@Override protected void processInMenuEvent(InMenuEvent inMenuEvent) { }}
复制代码


同时,需要开启缓存,由于mica-weixin的将access_token等信息放在了缓存中。在启动类上加@EnableCaching就开启了。


@SpringBootApplication@EnableCachingpublic class WeixinApplication {    public static void main(String[] args) {        SpringApplication.run(WeixinApplication.class, args);    }}
复制代码


1.1.4 公众号后台配置服务器信息


使用内网穿透工具穿透内网地址,然后在公众号后台菜单开发—>基本配置中填写服务器配置信息。



填写完成后点击启用,这样就完成了微信服务器和业务服务器的关系配置。开启开发者配置后,自动回复、自定义菜单等功能都不能正常使用了。这时候就需要去调用对应的接口实现这些功能。



二 实现各种消息接口


2.1 关注消息


在一步中,自定义类WeiXinMsgController中需要重写三个父类中的方法,其中processInFollowEvent()就是关注和取消关注的方法,取消关注后用户虽然不能收到消息,但是后台可以接收到用户取消关注的事件。


@Overrideprotected void processInFollowEvent(InFollowEvent inFollowEvent) {
OutTextMsg defaultMsg = new OutTextMsg(inFollowEvent); // 关注 if(InFollowEvent.EVENT_INFOLLOW_SUBSCRIBE.equals(inFollowEvent.getEvent())){ // 可将关注用户录入db,此处可以获取到用户openid String openId = inFollowEvent.getFromUserName(); // 查询db,根据响应消息类型封装消息体 if("文本消息"){ OutTextMsg otm = new OutTextMsg(inFollowEvent); otm.setContent("消息内容"); render(otm); return; }else if("图片消息"){ OutImageMsg oim = new OutImageMsg(inFollowEvent); // 这里需要调用微信提供的素材接口,将图片上传至素材库。 oim.setMediaId("图片素材id"); render(oim); return; }else if("图文消息"){ OutNewsMsg onm = new OutNewsMsg(inFollowEvent); onm.addNews("标题","简介","图片地址","图文链接"); render(onm); return; }else if("视频消息"){ OutVideoMsg ovm = new OutVideoMsg(inFollowEvent); ovm.setTitle("标题"); ovm.setDescription("简介"); ovm.setMediaId("视频素材id"); render(ovm); return; }else{ defaultMsg.setContent("感谢关注"); } } // 取消关注 if(InFollowEvent.EVENT_INFOLLOW_UNSUBSCRIBE.equals(inFollowEvent.getEvent())){ log.info("用户取消关注了"); // 此处可以将取消关注的用户更新db }}
复制代码


2.2 关键词消息


响应内容跟关注消息一样,查询 db 去匹配关键词,然会根据消息内容封装对应的消息体进行返回,如果没匹配到关键词则回复统一的消息内容。processInTextMsg()方法就是用来回复关键词消息的。


@Overrideprotected void processInTextMsg(InTextMsg inTextMsg) {
String content = inTextMsg.getContent(); // 根据用户发送的content去查询db中的响应内容 if("文本消息"){ OutTextMsg otm = new OutTextMsg(inTextMsg); otm.setContent("消息内容"); render(otm); return; }else if("图片消息"){ OutImageMsg oim = new OutImageMsg(inTextMsg); // 这里需要调用微信提供的素材接口,将图片上传至素材库。 oim.setMediaId("图片素材id"); render(oim); return; }else if("图文消息"){ OutNewsMsg onm = new OutNewsMsg(inTextMsg); onm.addNews("标题","简介","图片地址","图文链接"); render(onm); return; }else if("视频消息"){ OutVideoMsg ovm = new OutVideoMsg(inTextMsg); ovm.setTitle("标题"); ovm.setDescription("简介"); ovm.setMediaId("视频素材id"); render(ovm); return; }else{ OutTextMsg otm = new OutTextMsg(inTextMsg); otm.setContent("暂未查到关键词..."); }}
复制代码


2.3 菜单消息


点击菜单后也是一样,通过processInMenuEvent()方法进行响应内容的回复。


@Overrideprotected void processInMenuEvent(InMenuEvent inMenuEvent) {    String eventKey = inMenuEvent.getEventKey();    // 根据用户发送的content去查询db中的响应内容    if("文本消息"){        OutTextMsg otm = new OutTextMsg(inMenuEvent);        otm.setContent("消息内容");        render(otm);        return;    }else if("图片消息"){        OutImageMsg oim = new OutImageMsg(inMenuEvent);        // 这里需要调用微信提供的素材接口,将图片上传至素材库。        oim.setMediaId("图片素材id");        render(oim);        return;    }else if("图文消息"){        OutNewsMsg onm = new OutNewsMsg(inMenuEvent);        onm.addNews("标题","简介","图片地址","图文链接");        render(onm);        return;    }else if("视频消息"){        OutVideoMsg ovm = new OutVideoMsg(inMenuEvent);        ovm.setTitle("标题");        ovm.setDescription("简介");        ovm.setMediaId("视频素材id");        render(ovm);        return;    }else{        OutTextMsg otm = new OutTextMsg(inMenuEvent);        otm.setContent("无效链接,请重试...");    }}
复制代码


三 接口 API 调用


目前,微信提供的接口对订阅号的限制比较大,未认证的订阅号基本上只有接收消息的几个功能接口。


调用接口的时候需要传递token,获取 token 需要在微信后台中配置业务服务器的白名单。如下:



如果需要配置多个白名单 ip,使用回车键将多个 ip 分隔开。


mica-weixin提供了所有的接口封装,具体可参考它的官方文档,如果要获取微信菜单,可以这样写:


@WxApi("weixin/api")public class WeiXinApiController {    @GetMapping("menu")    @ResponseBody    public String getMenu(){        ApiResult menu = MenuApi.getMenu();        return menu.getJson();    }}
复制代码


@WxApi这个是它的自定义注解,其实就是包含了@RequestMapping@Controller


四 其他事项


4.1 多公众号配置


mica-weixin提供了多公众号配置的功能,使用ThreadLocalappid进行绑定。只需要简单配置即可实现多公众号配置。


dream:  weixin:    wx-configs:      - appId: xxxxxx        appSecret: xxxxxx        token: javatrip        encodingAesKey: xxxxxx      - appId: xxxxxx        appSecret: xxxxxx        token: javatrip        encodingAesKey: xxxxxx
复制代码


4.2 redis 配置


access_token的有效期是 2 小时,并且该接口有调用次数限制,mica-weixinaccess_token存储在 redis 中,避免每次调用接口都去获取access-token,因此项目需要配置 redis。


spring:  redis:    host: localhost    port: 6379
复制代码


4.3 手动选择 ThreadLocal


如果想要开发微信公众号的后台管理功能,多公众号的时候就需要手动去指定当前线程使用哪个公众号信息。如下:


ApiConfigKit.setThreadLocalAppId(appid);
复制代码


至此,SpringBoot 开发微信公众号就算完成了,由于订阅号开放的接口太少了,好多功能不能正常演示。还有mica-weixin也许不是最好的选择,如果想试着开发微信公众号,可以在 gitee 上找一下开发包。至于我为什么会使用mica-weixin,是因为我曾用过一段时间的jfinal框架,与之配套的微信开发包就是jfinal-weixin,也就是 jfinal 版的mica-weixin




此是 spring-boot-route 系列的第二十三篇文章,这个系列的文章都比较简单,主要目的就是为了帮助初次接触 Spring Boot 的同学有一个系统的认识。本文已收录至我的github,欢迎各位小伙伴star


githubhttps://github.com/binzh303/spring-boot-route


点关注、不迷路


如果觉得文章不错,欢迎关注、*点赞*、收藏,你们的支持是我创作的动力,感谢大家。


如果文章写的有问题,请不要吝惜文笔,欢迎留言指出,我会及时核查修改。


发布于: 2020 年 10 月 23 日阅读数: 122
用户头像

Java旅途

关注

还未添加个人签名 2020.06.17 加入

公众号:Java旅途

评论

发布
暂无评论
spring-boot-route(二十三)开发微信公众号