以前介绍了自动回复,下面介绍一些常见的消息处理样式java
当咱们公众号发送一些关键词的时候,公众号会回复自动回复有关关键词的信息。git
为便于扩展,将消息处理的方法写到服务层,新建收发信息的dtogithub
1、便于扩展为不一样类型的消息,修改收发消息的封装,改用dto模式spring
@Data
@XmlAccessorType(XmlAccessType.FIELD) // 映射类中的全部字段到XML
public class MsgSendEntity {
/** * 公有部分 */
// 开发者微信号
@XmlElement(name = "ToUserName") // 指定名称映射
private String toUserName;
// 发送方账号(一个OpenID)
@XmlElement(name = "FromUserName")
private String fromUserName;
// 消息建立时间 (整型)
@XmlElement(name = "CreateTime")
private Long createTime;
// 消息类型
@XmlElement(name = "MsgType")
private String msgType;
// 消息id,64位整型
@XmlElement(name = "MsgId")
private Long msgId;
}
复制代码
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class MsgReplyEntity {
// 用户的OpenID
@XmlElement(name = "ToUserName")
private String toUserName;
// 测试号的微信号
@XmlElement(name = "FromUserName")
private String fromUserName;
// 消息建立时间 (整型)
@XmlElement(name = "CreateTime")
private Long createTime;
// 消息类型
@XmlElement(name = "MsgType")
private String msgType;
// 文本消息内容
@XmlElement(name = "Content")
private String content;
}
复制代码
@Data
@XmlRootElement(name = "xml") // 根节点
@XmlAccessorType(XmlAccessType.FIELD) // 映射类中的全部字段到XML
public class MsgSendDto extends MsgSendEntity {
// 文本消息内容
@XmlElement(name = "Content")
private String content;
}
复制代码
@Data
@XmlRootElement(name="xml")
@XmlAccessorType(XmlAccessType.FIELD)
public class MsgReplyDto extends MsgReplyEntity {
}
复制代码
2、抽取消息处理的服务类与消息处理的方法到服务层json
@Service
public class MsgHandleServiceImpl implements IMsgHandleService {
@Override
public MsgReplyEntity handle(MsgSendEntity msgSend) {
WeChatUtil.getLogger().info("客户端接收的内容为:{}"+msgSend);
// 服务端消息回复的实体类
MsgReplyEntity msgReply = new MsgReplyEntity();
// 根据接收的信息回复,接收和发送方相反
msgReply.setFromUserName(msgSend.getToUserName());
msgReply.setToUserName(msgSend.getFromUserName());
msgReply.setCreateTime(new Date().getTime());
String msgType = msgSend.getMsgType();
String contentReply = null;
// 处理不一样类型的消息
if (msgType.equals(WeChatConstants.MSG_TYPE_TEXT)) {
// 默认回复相同的类型消息
msgReply.setMsgType(msgType);
String contentSend = msgSend.getContent();
// 关键词处理
if (contentSend.contains("你好")) {
contentReply = "你好吗\r\nhow are you";
} else if (contentSend.contains("哈哈")||contentSend.contains("haha")) {
contentReply = "我也喜欢哈哈大笑";
} else if (contentSend.contains("chet")){
msgReply.setMsgType(WeChatConstants.MSG_TYPE_NEWS);
//设置图文个数
msgReply.setArticleCount(1);
//设置图文明细列表
ArticleItem item = new ArticleItem();
item.setTitle("chet的github博客");
item.setPicUrl("https://chetwhy.github.io/");
item.setDescription("chet的掘金博客");
item.setUrl("https://juejin.im/timeline");
msgReply.setItem(new ArticleItem[]{item});
}else {
// 非关键字,原样返回
contentReply = msgSend.getContent();
}
msgReply.setContent(contentReply);
}
WeChatUtil.getLogger().info("服务端回复的内容为:{}"+msgReply);
return msgReply;
}
}
复制代码
3、封装的常量类api
public class WeChatConstants {
/** * 公众号appid */
public static String APP_ID = "wxa02348cd5ec17d28";
/** * AppSecret */
public static String APPSECRET = "2ffbf0ff3516af025942ec8ca67f27d8";
/** * 公众号配置相关 */
public static final String URL = "ups.tiaodu.cn";
public static final String TOKEN = "123qwe";
/** * 消息类型 */
public static final String MSG_TYPE_TEXT = "text";
public static final String MSG_TYPE_NEWS = "news";
}
复制代码
在手机微信或电脑微信直接发送带【关键字】的信息便可springboot
微信公众号有多种不一样事件信息,包括其触发事件的类型,响应处理。最多见的,当咱们点击关注某公众号以后,公众号将自动推送给咱们介绍信息后者活动宣传等。微信
1、参考微信公众平台技术文档->消息管理->接收事件推送app
2、查看对应消息事件格式,扩展消息实体的dto微信公众平台
3、在原消息基础上,添加事件的逻辑判断
下面以关注/取消事件和自定义菜单事件作演示
1为MsgSendDto添加事件属性
...
public class MsgSendDto {
...
// 事件类型 subscribe(订阅)、unsubscribe(取消订阅)、CLICK(点击菜单)
@XmlElement(name = "Event")
private String event;
}
复制代码
2增长常量类
public class WeChatConstants {
...
public static final String MSG_TYPE_EVENT = "event";
public static final String MSG_TYPE_EVENT_SUBSCRIBE = "subscribe";
}
复制代码
3消息处理方法,增长判断逻辑
@Service
public class MsgHandleServiceImpl {
public MsgReplyEntity handle(MsgSendEntity msgSend) {
...
// 处理不一样类型的消息
if (msgType.equals(WeChatConstants.MSG_TYPE_TEXT)) {
...
}else if(msgType.equals(WeChatConstants.MSG_TYPE_EVENT)){
// 订阅事件
if(msgSend.getEvent().equals(WeChatConstants.MSG_TYPE_EVENT_SUBSCRIBE)){
msgReply.setMsgType(WeChatConstants.MSG_TYPE_TEXT);
msgReply.setContent("感谢关注chetwhy![亲亲]\r\n如今回复【chet】\r\n立刻查阅java博客![大兵]");
}
}
WeChatUtil.getLogger().info("服务端回复的内容为:{}"+msgReply);
return msgReply;
}
}
复制代码
1、先取消对测试公众的关注(断点调试依然能够看到消息类型为event)
2、在测试号管理中再次扫描二维码关注
代码开发
当咱们点开一个订阅的公共号时,点击聊天输入框最左侧的按钮,能够切换到公众号的菜单栏,有的菜单选项中多个子菜单,有的菜单选择会自动跳转到其余页面。这为咱们的公众号提供更为便捷的窗口和功能的扩展。
1、参考微信公众平台技术文档->自定义菜单->【自定义菜单...接口】和消息管理->接收事件推送->[4-6菜单事件]
2、按照文档,咱们应先建立自定义的菜单。简单的说:
公众平台以access_token为接口调用凭据,来调用接口,全部接口的调用须要先获取access_token,access_token在2小时内有效,过时须要从新获取,但1天内获取次数有限,开发者需自行存储
3、根据请求示例,封装好咱们自定义的json数据
4、根据文档->获取access_token,编写工具类获取返回的token
1封装自定义菜单的json数据
{
"button":[
{
"type":"click",
"name":"今日歌曲",
"key":"V1001_TODAY_MUSIC"
},
{
"name":"菜单",
"sub_button":[
{
"type":"view",
"name":"搜索",
"url":"http://www.soso.com/"
},
{
"type":"miniprogram",
"name":"wxa",
"url":"http://mp.weixin.qq.com",
"appid":"wx286b93c14bbf93aa",
"pagepath":"pages/lunar/index"
},
{
"type":"click",
"name":"赞一下咱们",
"key":"V1001_GOOD"
}]
}]
}
复制代码
起名字费劲,我这里照搬的微信的菜单名,两个按钮型一级菜单,其中有两个子菜单
2建立获取access token的工具类方法
public class WeChatUtil {
// 获取access_token的路径模板
public static final String GET_ACCESSTOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
public static String accessToken;
public static long expiresTime;
/** * 获取access_token * @return access_token */
public static String getAccessToken(){
// 第一次获取或access token已过时
if(accessToken==null||new Date().getTime()>expiresTime){
// 替换示例种参数,发送https的get请求
String result = HttpUtil.get(GET_ACCESSTOKEN_URL.replace("APPID", WeChatConstants.APP_ID).replace("APPSECRET", WeChatConstants.APPSECRET));
JSONObject json = JSONObject.parseObject(result);
accessToken = json.getString("access_token");
// 有效事件,单位秒
Long expires_in = json.getLong("expires_in");
// 设置凭据的失效时间,默认7200s,提早五分钟过时
expiresTime = new Date().getTime()+((expires_in-60*5)*1000);
WeChatUtil.getLogger().info("access_token={},expires_time={}",accessToken,expiresTime);
}
return accessToken;
}
}
复制代码
3船舰自定菜单的工具类方法
public class WeChatUtil {
// 自定义菜单接口
public static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
/** * 建立自定义菜单 * @param menuJson */
public static void createMenu(String menuJson){
//发起请求到指定的接口,而且带上菜单json数据
String result = HttpUtil.post(CREATE_MENU_URL.replace("ACCESS_TOKEN",getAccessToken()), menuJson);
WeChatUtil.getLogger().info("建立自定义菜单结果:{}", result);
}
}
复制代码
4.写一个主方法,将以前封装的json传入createMenu方法。运行便可
public static void main(String[] args) {
String menu = "...";
createMenu(menu);
}
复制代码
1、直接运行上述的main方法,查看运行日志,生成成功
2、查看微信客户端的聊天页面,点开二级菜单
3、若日志显示成功,客户端没反应,尝试从新关注订阅号,或重启natapp
1、封装菜单事件的参数,扩展dto
2、增长消息处理的业务逻辑
1、消息发送实体类
public class MsgSendDto extends MsgSendEntity {
...
// 菜单的key值
@XmlElement(name = "EventKey")
private String eventKey;
}
复制代码
2、消息处理方法,key即为json中的"key"键
@Service
public class MsgHandleServiceImpl implements IMsgHandleService {
@Override
public MsgReplyEntity handle(MsgSendDto msgSend) {
...
// 处理不一样类型的消息
if (msgType.equals(WeChatConstants.MSG_TYPE_TEXT)) {
...
}else if(msgType.equals(WeChatConstants.MSG_TYPE_EVENT)){
// 订阅事件
if(msgSend.getEvent().equals(WeChatConstants.MSG_TYPE_EVENT_SUBSCRIBE)){
...
}else if(msgSend.getEvent().equals(WeChatConstants.MSG_TYPE_EVENT_CLICK)){
String eventKey = msgSend.getEventKey();
//判断按钮的key值
if ("V1001_TODAY_MUSIC".equals(eventKey)){
contentReply = "《年少有为》- 李荣浩\n" +
"《The Spectre》- Alan Walker";
}else if("V1001_GOOD".equals(eventKey)){
contentReply = "谢谢您的点赞关注[拇指]";
}
msgReply.setMsgType("text");
msgReply.setContent(contentReply);
}
}
WeChatUtil.getLogger().info("服务端回复的内容为:{}"+msgReply);
return msgReply;
}
}
复制代码
1、运行springboot
2、点开微信菜单栏,点击菜单按钮
这个也很常见,好比当咱们在公众号平台购买商品后,平台会发送下单结果的通知信息,这个相似与邮寄同样,也是模板信息。文档也说,模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。
1、参考微信公众平台技术文档->消息管理->模板消息接口
2、在测试公众号中配置新增模板
3、编写工具类方法,支持https的post请求,url为:
api.weixin.qq.com/cgi-bin/tem…
1、测试公众号->模板消息接口->新增配置模板
我这里依然使用官方文档的例子
如图
2、封装发送模板信息的json数据,相关信息都改为本身的,template_id即上面的【模板ID】
{
"touser":"o50E15lhQXW0SlsYg3bKFrywtKC8",
"template_id":"RXl8FLezLbHaBrPWTwK295CNgkNpR69Et40K3oOoK0",
"url":"http://weixin.qq.com/download",
"miniprogram":{
"appid":"xiaochengxuappid12345",
"pagepath":"index?foo=bar"
},
"data":{
"first": {
"value":"恭喜你购买成功!",
"color":"#173177"
},
"keyword1":{
"value":"巧克力",
"color":"#173177"
},
"keyword2": {
"value":"39.8元",
"color":"#173177"
},
"keyword3": {
"value":"2014年9月22日",
"color":"#173177"
},
"remark":{
"value":"欢迎再次购买!",
"color":"#173177"
}
}
}
复制代码
3、建立发送模板信息的方法
// 发送模板消息的接口
public static final String SEND_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
/** * 发送模板信息 * @param data 模板json数据 */
public static void sendTemplate(String data){
String result = HttpUtil.post(SEND_TEMPLATE_URL.replace("ACCESS_TOKEN", getAccessToken()),data);
WeChatUtil.getLogger().info("发送模板消息结果:{}",result);
}
复制代码
使用第二步的json数据,直接在main方法测试便可
(持续更新)