##消息管理
###簡介
在官方提供的開發者文檔中,可以看到各種接收消息和發送消息,所以我們要了解如何接收消息、相應消息以及消息的結構。
###消息交互流程
1. 接收消息:當普通用戶向公眾號發送消息時,微信服務器將POST消息的XML數據包發送到開發者填寫的URL上。
2. 發送消息:對于每一個POST請求,開發者在響應包中返回特定XML結構,并對該消息進行響應。
參與消息交互的實體有3個:用戶、微信服務器和公眾號服務器。而公眾號的消息交互流程描述如下:
1. 用戶通過微信客戶端向公賬號發送消息,消息首先會被微信服務器接收到;
2. 微信服務器收到消息后,會根據開發者在接口配置信息中填寫的URL,將消息通過HTTP POST方式傳遞到公眾號服務器;
3. 公眾號服務器接收到消息后,會按照業務邏輯進行相應的處理;
4. 處理完成后,公眾號服務器會將處理結果返回給微信服務器;
5. 微信服務器將公眾賬號服務器返回的消息通過公眾賬號發送給用戶;
* * * * *
######**提示**:消息交互流程中的服務器指的是后臺處理程序,不是物理硬件。例如公眾號服務器是指公眾號的后臺處理程序。
* * * * *
在整個消息交互過程中,公眾號服務器主要做3件事:
1. 接收微信服務器發來的消息;
2. 根據指定的業務邏輯對消息進行處理;
3. 將處理結果返回給微信服務器;
###消息分類
消息交互大概可以分為三類: 請求消息、事件和響應消息。其中請求消息和事件是由微信服務器傳給公眾號服務器,而響應消息是由公眾號服務器傳給微信服務器。
* 請求消息
請求消息是指用戶發送給公眾號的消息,它包括文本消息、圖片消息、語音消息、視頻消息、地理位置和鏈接消息。
* 事件
事件是指用戶對公眾號做出某種操作時,微信服務器會將對應的事件推送給公眾好服務器,比如前面我們說到的 自定義菜單里的 click 菜單。事件目前主要包括:關注事件、取消關注事件、掃描帶參數二維碼事件、上報地理位置事件和自定義菜單事件。
* 響應消息
響應消息是指公眾號回復給用戶的消息,響應消息包括文本消息、圖片消息、語音消息、視頻消息、音樂消息和圖文消息。圖片、語音和視頻消息屬于多媒體消息,在開發模式下回復多媒體消息時需要預先上傳多媒體文件到微信服務器。
###消息結構的封裝
* **封裝請求消息**
當微信用戶向公眾號發送消息時,微信服務器會將消息以XML格式通過POST方式發送到我們填寫的URL(公眾號服務器的入口)上,每種請求消息的結構可查看開發者文檔的“消息管理 - 接收普通消息”
**1.請求消息基類**
為減少代碼冗余,我們將每種類型的請求消息都包含的參數提取出來封裝成消息基類,這些參數包括: ToUserName,FromUserName,CreateTime,MsgType和MsgId。
* * * * *
######1. **ToUserName** 是公眾賬號的原始微信號,格式為gh_xxxxxxxxxxx,可以在公眾平臺的賬號信息中看到。
######2.**FromUserName** 即 OpenId,是一個唯一字符串,并不是用戶的微信號,而是針對一個公眾號內用戶的唯一ID。對于同一個公眾號,用戶的openId是固定不變的,因此我們會通過openId來定位一個用戶。但對于不同的公眾號,同一個用戶的openId是不一樣的。
######3.**CreateTime**是一個整形的時間。
######4.**MsgType**表示消息類型,公眾號服務器通過它來判斷用戶發送的是哪類消息。
* * * * *
請求消息基類代碼如下
~~~
/**
* 請求消息基類(普通用戶 -> 公眾帳號)
*/
public class BaseMessage {
// 開發者微信號
private String ToUserName;
// 發送方帳號(一個OpenID)
private String FromUserName;
// 消息創建時間 (整型)
private long CreateTime;
// 消息類型
private String MsgType;
// 消息id,64位整型
private long MsgId;
public String getToUserName() {
return ToUserName;
}
public void setToUserName(String toUserName) {
ToUserName = toUserName;
}
public String getFromUserName() {
return FromUserName;
}
public void setFromUserName(String fromUserName) {
FromUserName = fromUserName;
}
public long getCreateTime() {
return CreateTime;
}
public void setCreateTime(long createTime) {
CreateTime = createTime;
}
public String getMsgType() {
return MsgType;
}
public void setMsgType(String msgType) {
MsgType = msgType;
}
public long getMsgId() {
return MsgId;
}
public void setMsgId(long msgId) {
MsgId = msgId;
}
}
~~~
**2.文本消息**
當用戶向公眾賬號發送一段文字時,微信服務器會向公眾號服務器發送如下格式的消息
~~~
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
</xml>
~~~
其中,Content表示文本消息的內容。文本消息類需要繼承基類BaseMessage,代碼如下
~~~
/**
* 文本消息
*/
public class TextMessage extends BaseMessage {
// 消息內容
private String Content;
public String getContent() {
return Content;
}
public void setContent(String content) {
Content = content;
}
}
~~~
**3....**
ps:其他還有圖片消息、語音消息、視頻消息、小視頻消息、地理位置消息、鏈接消息,封裝規則一樣,可參考 開發者文檔中進行封裝,這里不一一列出了。
* **封裝事件**
**1.事件基類**
每種事件都包含ToUserName、FromUserName、CreateTime、MsgType和Event 5個參數,其中 Event為事件類型。代碼如下
~~~
/**
* 事件基類
*/
public class BaseEvent {
// 開發者微信號
private String ToUserName;
// 發送方帳號(一個OpenID)
private String FromUserName;
// 消息創建時間 (整型)
private long CreateTime;
// 消息類型
private String MsgType;
// 事件類型
private String Event;
public String getToUserName() {
return ToUserName;
}
public void setToUserName(String toUserName) {
ToUserName = toUserName;
}
public String getFromUserName() {
return FromUserName;
}
public void setFromUserName(String fromUserName) {
FromUserName = fromUserName;
}
public long getCreateTime() {
return CreateTime;
}
public void setCreateTime(long createTime) {
CreateTime = createTime;
}
public String getMsgType() {
return MsgType;
}
public void setMsgType(String msgType) {
MsgType = msgType;
}
public String getEvent() {
return Event;
}
public void setEvent(String event) {
Event = event;
}
}
~~~
**2.自定義菜單事件**
點用戶點擊click類型的菜單按鈕時,微信服務器會向公眾號服務器發送一條事件類型 CLICK的消息,結構如下:
~~~
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[CLICK]]></Event>
<EventKey><![CDATA[EVENTKEY]]></EventKey>
</xml>
~~~
這里的EventKey 與 自定菜單接口中的Key值相對應,通過它來識別用戶點擊的是哪個菜單按鈕。自定義菜單事件的消息結構對應的Java類代碼如下:
~~~
/**
* 自定義菜單事件
*/
public class MenuEvent extends BaseEvent {
// 事件KEY值,與自定義菜單接口中KEY值對應
private String EventKey;
public String getEventKey() {
return EventKey;
}
public void setEventKey(String eventKey) {
EventKey = eventKey;
}
}
~~~
**注意:**點擊view類型的菜單按鈕時,微信服務器不會推送自定義菜單事件。
**3....**
其他略
* **封裝響應消息**
公眾號服務器在接收到用戶發送的消息后,可以通過返回特定的XML結構對消息進行響應,詳細信息可以參考 開發者文檔中的“發送被動響應消息”。
**1.響應消息基類**
每種類型的響應消息都包含參數 ToUserName、FromUserName、CreateTime和MsgType。封裝基類代碼如下:
~~~
/**
* 消息基類(公眾帳號 -> 普通用戶)
*/
public class BaseMessage {
// 接收方帳號(收到的OpenID)
private String ToUserName;
// 開發者微信號
private String FromUserName;
// 消息創建時間 (整型)
private long CreateTime;
// 消息類型
private String MsgType;
public String getToUserName() {
return ToUserName;
}
public void setToUserName(String toUserName) {
ToUserName = toUserName;
}
public String getFromUserName() {
return FromUserName;
}
public void setFromUserName(String fromUserName) {
FromUserName = fromUserName;
}
public long getCreateTime() {
return CreateTime;
}
public void setCreateTime(long createTime) {
CreateTime = createTime;
}
public String getMsgType() {
return MsgType;
}
public void setMsgType(String msgType) {
MsgType = msgType;
}
}
~~~
**2.文本消息**
當公眾號服務器受到用戶發送的消息之后,如果需要回復一條文本消息給用戶,需要構造如下格式的數據:
~~~
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
~~~
參數Content表示消息內容,長度不能超過 2048字節,否則微信服務器會放棄響應,用戶則收不到回復。對應封裝java類如下:
~~~
/**
* 文本消息
*/
public class TextMessage extends BaseMessage {
// 回復的消息內容
private String Content;
public String getContent() {
return Content;
}
public void setContent(String content) {
Content = content;
}
}
~~~
**3.圖片消息**
回復一條圖片消息給用戶,需要構造如下格式的數據
~~~
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[media_id]]></MediaId>
</Image>
</xml>
~~~
參數MediaId 是媒體文件的ID。回復圖片、語音、視頻等多媒體消息時,需要預先上傳多媒體文件到微信服務器,上傳成功后微信服務器會返回多媒體文件的ID。圖片消息對應的Java類如下:
~~~
/**
* 圖片消息
*/
public class ImageMessage extends BaseMessage {
// 圖片
private Image Image;
public Image getImage() {
return Image;
}
public void setImage(Image image) {
Image = image;
}
}
~~~
**4. ......**
其他略
###消息的處理