以前介紹了自動回覆,下面介紹一些常見的消息處理樣式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方法測試便可
(持續更新)