官术网_书友最值得收藏!

4.3 接收消息

接收的消息是微信服務(wù)器發(fā)送給公共賬號(hào)的消息。在第3章中我們已經(jīng)介紹了微信服務(wù)器的數(shù)據(jù)交互方式,當(dāng)訂閱用戶給微信公眾號(hào)發(fā)送消息時(shí),微信服務(wù)器會(huì)將消息封裝成XML數(shù)據(jù),以POST方式發(fā)送到我們配置的URL上。根據(jù)消息類型的不同,XML數(shù)據(jù)的格式也有所不同,下面我們將詳細(xì)介紹每種消息格式。

4.3.1 文本消息

文本消息是最常使用的交互方式,發(fā)送的所有文字(包括URL)都是文本消息。文本消息的結(jié)構(gòu)如下:

     <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>

參數(shù)說明如表4-4所示。

表4-4 參數(shù)說明

表格中的部分參數(shù)詳細(xì)解釋如下:

  • ToUserName 微信公共賬號(hào)的原始ID,在公共賬號(hào)的賬號(hào)信息里能看到,類似gh_******的格式,這個(gè)字段對公共賬號(hào)的開發(fā)者而言沒什么用途。
  • FromUserName 消息發(fā)送者的OpenID,類似于og17nt6kNCcqq25b77C8L2zEJXdQ的格式。對于同一個(gè)公共賬號(hào),訂閱用戶的OpenID是固定不變的,而對于不同的公共賬號(hào),用戶的OpenID是不同的。
  • CreateTime 消息創(chuàng)建的時(shí)間,是一個(gè)整型數(shù)字,表示從1970年1月1日0時(shí)0分0秒到現(xiàn)在經(jīng)過的秒數(shù)。
  • MsgType 消息類型?,F(xiàn)在微信服務(wù)器提供6種類型的消息,即文本消息(text)、圖片消息(image)、語音消息(voice)、視頻消息(video)、地理位置消息(location)、鏈接消息(link)。

下面給出具體的代碼。因?yàn)槲⑿欧?wù)器是以POST的方式發(fā)送數(shù)據(jù)的,所以首先解析POST請求,提取出數(shù)據(jù),代碼如下:

     /**
          *解析接收到的post數(shù)據(jù)
          * @return SimpleXMLElement
          */
         public function parsePostRequestData()
         {
             $rawData = $GLOBALS['HTTP_RAW_POST_DATA'];
             $data = simplexml_load_string($rawData, 'SimpleXMLElement', LIBXML_NOCDATA);
             if ($data !== false)
                 $this->_postData = $data;

return $data; }

$GLOBALS['HTTP_RAW_POST_DATA']從$GLOBALS全局變量中獲取POST數(shù)據(jù),這時(shí)得到的數(shù)據(jù)是無類型的,通過simplexml_load_string函數(shù)解析成xml對象,就能供后續(xù)使用了。

isTextMsg用于判斷消息的類型是否為文本消息:

     const MSG_TYPE_TEXT = 'text';
     /**
          *判斷是否是文字信息
          * @return boolean
          */
         public function isTextMsg()
         {
             return $this->_postData->MsgType == self::MSG_TYPE_TEXT;
     }
     //發(fā)送消息
     $this->text("你發(fā)送的是文本消息,消息內(nèi)容是:".$data->Content);

text函數(shù)用來發(fā)送文本消息,這個(gè)將在后面介紹,如圖4-3所示。

圖4-3

4.3.2 圖片消息

圖片消息是多媒體消息,微信在收到這類消息時(shí)會(huì)將圖片存在微信服務(wù)器端,生成圖片的URL和媒體ID,圖片URL是可以公共訪問的,而公共賬號(hào)可以通過媒體ID獲取圖片文件。

     <xml>
      <ToUserName><![CDATA[toUser]]></ToUserName>
      <FromUserName><![CDATA[fromUser]]></FromUserName>
      <CreateTime>1348831860</CreateTime>
      <MsgType><![CDATA[image]]></MsgType>
      <PicUrl><![CDATA[this is a url]]></PicUrl>
      <MediaId><![CDATA[media_id]]></MediaId>
      <MsgId>1234567890123456</MsgId>
      </xml>

參數(shù)說明如表4-5所示。

表4-5 參數(shù)說明

     const MSG_TYPE_IMAGE='image';
     /**
          *判斷是否是圖片
          * @return boolean
          */
         public function isImageMsg(){
             return $this->_postData->MsgType == self::MSG_TYPE_IMAGE;
     }
     //發(fā)送消息
     $this->text("你發(fā)送的是圖片消息,圖片鏈接是: ".$data->PicUrl."\n媒體ID是: ".$data->MediaId);

運(yùn)行結(jié)果如圖4-4所示。

圖4-4

4.3.3 語音消息

語音消息同樣只發(fā)送媒體ID,還提供語音的格式。

     <xml>
     <ToUserName><![CDATA[toUser]]></ToUserName>
     <FromUserName><![CDATA[fromUser]]></FromUserName>
     <CreateTime>1357290913</CreateTime>
     <MsgType><![CDATA[voice]]></MsgType>
     <MediaId><![CDATA[media_id]]></MediaId>
     <Format><![CDATA[Format]]></Format>
     <MsgId>1234567890123456</MsgId>
     </xml>

參數(shù)說明如表4-6所示。

表4-6 參數(shù)說明

     const MSG_TYPE_VOICE = 'voice';
     /**
          *判斷是否是語音消息
          * @return boolean
          */
         public function isVoiceMsg(){
             return $this->_postData->MsgType == self::MSG_TYPE_VOICE;
         }
         //發(fā)送消息
     $this->text("你發(fā)送的是語音消息,媒體ID是: ".$data->MediaId."\n語音格式是: ".$data->Format);

運(yùn)行結(jié)果如圖4-5所示。

圖4-5

4.3.4 地理位置消息

在LBS和O2O的價(jià)值被極大發(fā)掘的今天,知道用戶的位置能提供很多針對性、個(gè)性化的服務(wù)。微信也提供了在輸入中發(fā)送當(dāng)前位置的功能,如圖4-6所示。

消息格式如下:

     <xml>
     <ToUserName><![CDATA[toUser]]></ToUserName>
     <FromUserName><![CDATA[fromUser]]></FromUserName>
     <CreateTime>1351776360</CreateTime>
     <MsgType><![CDATA[location]]></MsgType>
     <Location_X>23.134521</Location_X>
     <Location_Y>113.358803</Location_Y>
     <Scale>20</Scale>
     <Label><![CDATA[位置信息]]></Label>
     <MsgId>1234567890123456</MsgId>
     </xml>

圖4-6

參數(shù)說明如表4-7所示。

表4-7 參數(shù)說明

     const MSG_TYPE_LOCATION = 'location';
     /**
         *判斷是否是位置信息
         * @return boolean
         */
         public function isLocationMsg()
         {
            return $this->_postData->MsgType == self::MSG_TYPE_LOCATION;
    }
    //發(fā)送消息
    $this->text("你發(fā)送的是位置消息,維度為: ".$data->Location_X."\n經(jīng)度為: ".$data->Location_Y."\n縮放
級別為: ".$data->Scale."\n位置為: ".$data->Label);

運(yùn)行結(jié)果如圖4-7所示。

圖4-7

4.3.5 鏈接消息

圖4-8

這里的鏈接消息和URL不是相同的概念,微信公眾平臺(tái)將URL作為文本消息。那么怎么發(fā)送鏈接消息呢?打開已有的鏈接(朋友圈或者朋友發(fā)送的分享),單擊右上角的“分享”按鈕,選擇“發(fā)送給朋友”,就可以發(fā)送給微信朋友和微信群了。如果想分享一個(gè)網(wǎng)頁,就復(fù)制URL并粘貼到消息框,再發(fā)送給微信朋友。建議發(fā)送給公共賬號(hào),免得打擾別人。打開鏈接(默認(rèn)用微信瀏覽器打開),單擊右上角的“分享”按鈕就可以分享到朋友圈或發(fā)送給朋友。當(dāng)前微信并不支持發(fā)送鏈接消息給公共賬號(hào),如果想發(fā)送,那么可以先將鏈接收藏到收藏夾,然后在消息框添加“我的收藏”,如圖4-8所示。

鏈接消息的格式如下:

     <xml>
     <ToUserName><![CDATA[toUser]]></ToUserName>
     <FromUserName><![CDATA[fromUser]]></FromUserName>
     <CreateTime>1351776360</CreateTime>
     <MsgType><![CDATA[link]]></MsgType>
     <Title><![CDATA[公眾平臺(tái)官方網(wǎng)站鏈接]]></Title>
     <Description><![CDATA[公眾平臺(tái)官方網(wǎng)站鏈接]]></Description>
     <Url><![CDATA[url]]></Url>
     <MsgId>1234567890123456</MsgId>
     </xml>

參數(shù)說明如表4-8所示。

表4-8 參數(shù)說明

    const MSG_TYPE_LINK='link';
    /**
         *判斷是否是鏈接
         * @return boolean
         */
        public function isLinkMsg(){
            return $this->_postData->MsgType == self::MSG_TYPE_LINK;
    }
    //發(fā)送消息
    $this->text("你發(fā)送的是鏈接消息,標(biāo)題是: ".$data->Title."\n摘要是: ".$data->Description."\n鏈接是:
".$data->Url);

運(yùn)行結(jié)果如圖4-9所示。

圖4-9

視頻消息也是多媒體消息,與語音消息類似,格式如下:

     <xml>
     <ToUserName><![CDATA[toUser]]></ToUserName>
     <FromUserName><![CDATA[fromUser]]></FromUserName>
     <CreateTime>1357290913</CreateTime>
     <MsgType><![CDATA[video]]></MsgType>
     <MediaId><![CDATA[media_id]]></MediaId>
     <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
     <MsgId>1234567890123456</MsgId>
     </xml>

參數(shù)說明如表4-9所示。

表4-9 參數(shù)說明

    const MSG_TYPE_VIDEO = 'video';
    /**
         *判斷是否是視頻消息
         * @return boolean
         */
        public function isVideoMsg(){
            return $this->_postData->MsgType == self::MSG_TYPE_VIDEO;
    }
    //發(fā)送消息
    $this->text("你發(fā)送的是視頻消息,媒體ID是: ".$data->MediaId."\n縮略圖ID是: ".$data->
ThumbMediaId);

運(yùn)行結(jié)果如圖4-10所示。

圖4-10

4.3.6 公眾平臺(tái)消息體簽名及加、解密

2014年10月14日,公眾平臺(tái)消息體簽名及加密功能上線。該功能主要對公眾平臺(tái)推送給公眾賬號(hào)的基礎(chǔ)消息和公眾賬號(hào)回復(fù)的響應(yīng)消息進(jìn)行加密,以更好地保護(hù)用戶和公眾賬號(hào)的信息安全。

加解密的原理是AES對稱加密。開發(fā)者服務(wù)器和公眾平臺(tái)服務(wù)器在發(fā)送消息時(shí)用EncodingAESKey(加密所用的密鑰)將消息體加密成密文,再進(jìn)行傳輸。這樣在網(wǎng)絡(luò)上傳輸?shù)膬?nèi)容是加密的,即使被截獲也無法得知明文。公眾賬號(hào)用此密鑰對收到的密文消息體進(jìn)行解密,回復(fù)消息體也用此密鑰加密。

公眾平臺(tái)提供了3種加解密的模式供開發(fā)者選擇,即明文模式、兼容模式、安全模式(可在“開發(fā)者中心”選擇相應(yīng)模式)。選擇兼容模式和安全模式前,需在開發(fā)者中心填寫消息加解密密鑰EncodingAESKey,如圖4-11所示。

圖4-11

  • 明文模式:維持現(xiàn)有模式,沒有適配加解密新特性,消息體明文收發(fā),默認(rèn)設(shè)置為明文模式。
  • 兼容模式:公眾平臺(tái)發(fā)送消息內(nèi)容將同時(shí)包括明文和密文,消息包長度增加到原來的3倍左右。公眾號(hào)回復(fù)明文或密文均可,不影響現(xiàn)有消息收發(fā)。開發(fā)者可在此模式下進(jìn)行調(diào)試。
  • 安全模式(推薦):公眾平臺(tái)發(fā)送消息體的內(nèi)容只含有密文,公眾賬號(hào)回復(fù)的消息體也為密文,建議開發(fā)者在調(diào)試成功后使用此模式收發(fā)消息。

公眾平臺(tái)消息體簽名及加解密方案的示例代碼可參考下載資源中的代碼。

主站蜘蛛池模板: 门源| 龙门县| 金门县| 恭城| 越西县| 棋牌| 河津市| 南通市| 神池县| 娱乐| 鹰潭市| 乐业县| 金山区| 始兴县| 宁南县| 衡南县| 丽江市| 安宁市| 大方县| 石门县| 曲阜市| 嘉禾县| 三明市| 曲阳县| 长宁县| 衡阳县| 运城市| 梓潼县| 特克斯县| 高陵县| 柳江县| 三门峡市| 酉阳| 巴林左旗| 卢龙县| 长兴县| 桑植县| 大竹县| 万盛区| 壤塘县| 加查县|