PHP開發微信公衆號(二)消息接受與推送

上一篇文章咱們知道怎麼獲取二維碼,這樣別人就能夠掃描二維碼來關注咱們,可是別人關注後,發送消息,咱們怎麼進行相關處理?php

這裏咱們就來學習下怎麼處理處理這些消息,以及推送消息。git

學習以前首先你須要有一個域名和空間github

url:填寫你但願微信公衆平臺把用戶的消息轉發到哪裏json

token:隨便輸入,用於微信公衆平臺和你的站點進行第一次通訊創建關聯用api

/*
    用於第一次驗證咱們網站url合法性
     */
    public function firstValid(){
        //檢驗簽名的合法性
        if($this->_checkSignature()){
            //簽名合法,告知微信公衆平臺服務器
            echo $_GET['echostr'];
        }
    }
/**
     * 驗證簽名
     * @return bool 
     */
    private function _checkSignature(){
        //得到由微信公衆平臺請求的驗證數據
        $signature = $_GET['signature'];
        $timestamp = $_GET['timestamp'];
        $nonce = $_GET['nonce'];
        //將時間戳,隨機字符串,token按照字母順序排序,病並鏈接
        $tmp_arr = array($this->_token,$timestamp,$nonce);
        sort($tmp_arr,SORT_STRING);//字典順序
        $tmp_str = implode($tmp_arr);//鏈接
        $tmp_str = sha1($tmp_str);//sha1加密
        if($signature==$tmp_str){
            return true;
        }else{
            return false;
        }
    

在你的站點寫一個腳本,調用一下firstValid 就能夠完成微信公衆平臺和你站點的關聯。$this->_token,就是你上面寫token。服務器

而後再提交,就能成功了。微信

一、關注後,歡迎語的設置網絡

有人關注後,微信公衆平臺會給咱們發一個xml格式的數據,以下:app

 

而後咱們對這個信息進行獲取,轉化成咱們想要的格式,進行相關判斷,返回數據,一樣也須要組裝成xml格式微信公衆平臺

public function responseMsg(){
        /*
        得到請求時POST:XML字符串
        不能用$_POST獲取,由於沒有key
         */
        $xml_str = $GLOBALS['HTTP_RAW_POST_DATA'];
        if(empty($xml_str)){
            die('');
        }
        if(!empty($xml_str)){
            // 解析該xml字符串,利用simpleXML
            libxml_disable_entity_loader(true);
            //禁止xml實體解析,防止xml注入
              $request_xml = simplexml_load_string($xml_str, 'SimpleXMLElement', LIBXML_NOCDATA);
            //判斷該消息的類型,經過元素MsgType
            switch ($request_xml->MsgType){
                case 'event':
                    //判斷具體的時間類型(關注、取消、點擊)
                    $event = $request_xml->Event;
                      if ($event=='subscribe') { // 關注事件
                          $this->_doSubscribe($request_xml);
                      }elseif ($event=='CLICK') {//菜單點擊事件
                          $this->_doClick($request_xml);
                      }elseif ($event=='VIEW') {//鏈接跳轉事件
                          $this->_doView($request_xml);
                      }else{

                      }
                    break;
                case 'text'://文本消息
                    $this->_doText($request_xml);
                    break;
                case 'image'://圖片消息
                    $this->_doImage($request_xml);
                    break;
                case 'voice'://語音消息
                    $this->_doVoice($request_xml);
                    break;
                case 'video'://視頻消息
                    $this->_doVideo($request_xml);
                    break;
                case 'shortvideo'://短視頻消息
                    $this->_doShortvideo($request_xml);
                    break;
                case 'location'://位置消息
                    $this->_doLocation($request_xml);
                    break;
                case 'link'://連接消息
                    $this->_doLink($request_xml);
                    break;
            }        
        }        
    }

咱們能夠給用戶回覆文字,圖片,視頻,音樂,新聞等等,首先定義好相應的回覆模塊

private $_msg_template = array(
        'text' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>',//文本回復XML模板
        'image' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[%s]]></MediaId></Image></xml>',//圖片回覆XML模板
        'music' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[music]]></MsgType><Music><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><MusicUrl><![CDATA[%s]]></MusicUrl><HQMusicUrl><![CDATA[%s]]></HQMusicUrl><ThumbMediaId><![CDATA[%s]]></ThumbMediaId></Music></xml>',//音樂模板
        'news' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[news]]></MsgType><ArticleCount>%s</ArticleCount><Articles>%s</Articles></xml>',// 新聞主體
        'news_item' => '<item><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><PicUrl><![CDATA[%s]]></PicUrl><Url><![CDATA[%s]]></Url></item>',//某個新聞模板
    );

%s就表明咱們須要填的參數,後面用spritf統一傳入

首先咱們回覆一句‘你好’;

/**
     * 發送文本信息
     * @param  [type] $to      目標用戶ID
     * @param  [type] $from    來源用戶ID
     * @param  [type] $content 內容
     * @return [type]          [description]
     */
    private function _msgText($to, $from, $content) {
        $response = sprintf($this->_msg_template['text'], $to, $from, time(), $content);
        die($response);
    }
//關注後作的事件
private function _doSubscribe($request_xml){
        //處理該關注事件,向用戶發送關注信息
        $content = '你好';
        $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $content);
    }

這樣,用戶一關注就會收到‘你好’。

二、發送圖片

 

微信中的圖片、語音、視頻、縮略圖統稱素材,發送和接受都是以media_id進行的。

簡單說:用給公衆號一張圖片,這張圖片會上傳到微信公衆平臺服務器,而後生成一個惟一的media_id,而後返回一個xml信息給咱們,其中就有media_id。而咱們要發給用戶圖片,也須要先把圖片上傳給公衆平臺,而後獲取到media_id,根據這個media_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>

* 上傳臨時素材(永久素材也能夠):圖片,語音,視頻,縮略圖
* 儲存到微信公衆平臺服務器,3天
* 可經過上傳後返回的media_id再次去取得該圖片
本身定義上傳函數

public function uplodeTmp($file,$type){
        $url='https://api.weixin.qq.com/cgi-bin/media/upload?access_token='.$this->getAccessToken().'&type='.$type;
        $data = array(
            'media' => '@'.$file,
            );
        $result = $this->_request('post',$url,$data);
        $result_obj = json_decode($result);
        return $result_obj;
    }

本身調用該函數上傳站點圖片,經過返回結果得到該圖片media_id

發送給用戶:

//發送圖片
    private function _msgImage($to,$from,$file,$is_id=false){
        //判斷是否是media_id
        if($is_id){
            $media_id=$file;
        }else{
            // 上傳圖片到微信公衆服務器,獲取mediaID
            $result_obj = $this->uploadTmp($file, 'image');
            $media_id = $result_obj->media_id;
        }
            //拼湊xml圖片發給微信平臺,而後平臺返回圖片給用戶
            $response = sprintf($this->_msg_template['image'],$to,$from,time(),$media_id);
            die($response);
    }

這樣用戶就能夠得到你的圖片。

返回縮略圖,語音、視頻、短視頻也是用一樣的方法

若是咱們但願用戶發出‘圖片’兩個字時,返回給他一張圖片,該怎麼作?

private function _doText($request_xml){
    //接受文本信息
    $content = $request_xml->Content;
    if('圖片' == $content){
            $imgMediaId = 'UD-4n5YeK6NXhPCOYT_eV4YxYNZqCILemIZuZR3GYmj_AtrqhnHiIUUOQHSi71Ew';
            $this->_msgImage($request_xml->FromUserName, $request_xml->ToUserName,$imgMediaId,true);
        }

    }

固然咱們這裏把圖片寫死了,實際可根據具體業務邏輯進行改變,改變media_id就好了。

三、發送音樂

若是用戶輸入音樂,咱們發一首歌給他,音樂跟其餘的幾個素材不太同樣

 1 private function _doText($request_xml){
 2         //接受文本信息
 3         $content = $request_xml->Content;
 4         
 5         if('音樂' == $content){
 6             $music_url='音樂網絡地址連接';
 7             $ha_music_url='音樂網絡地址連接';
 8             $thumb_media_id='一張圖片的media_id';
 9             $title = '音樂名稱';
10             $desc = '音樂描述';
11             $this->_msgMusic($request_xml->FromUserName, $request_xml->ToUserName, $music_url, $hq_music_url, $thumb_media_id, $title, $desc);
12         }
13 }
14 //發送音樂
15     private function _msgMusic($to, $from, $music_url, $hq_music_url, $thumb_media_id, $title='', $desc='') {
16         $response = sprintf($this->_msg_template['music'], $to, $from, time(), $title, $desc, $music_url, $hq_music_url, $thumb_media_id);
17         die($response);
18     }

四、圖靈機器人的接入

圖靈官網註冊申請appkey

 //圖靈機器人接入         

 $content = $request_xml->Content;
$url = 'http://www.tuling123.com/openapi/api?key='.$this->_appkey.'&info='.$content.'&userid='.$request_xml->FromUserName;
            // $data['key'] = $this->_appkey;//
            // $data['info'] = $content;//用戶輸入的內容
            // $data['userid'] = $request_xml->FromUserName;
            $response_content = json_decode($this->_request('get',$url,array(),false));
            //$response_content->code決定返回的是什麼
            //100000  文本 text
            //200000 連接  text+url
            //302000   新聞 text +list(新聞列表,裏面有:article,source,icon,detailurl)分別是標題、來源、圖片、詳情地址
            //308000   菜譜  text+name+info+detailurl+icon
            $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $response_content->text);

能夠自行根據圖靈官網反回的code進行分類判斷,字符組裝,再回復給用戶。

這樣,你的公衆號就變成了一個圖靈機器人了。

五、發送圖文(新聞)

我通常看到的微信公衆號都是以圖文信息進行推送消息,這個新聞類型怎麼發送?

if('新聞' == $content){
            $item_list = array(
                array('title'=>'標題','desc'=>'描述','picurl'=>'圖片地址','url'=>'該文章的地址'),
                array('title'=>'標題','desc'=>'描述','picurl'=>'圖片地址','url'=>'該文章的地址')        
                );
            $this->_msgNews($request_xml->FromUserName,$request_xml->ToUserName,$item_list);
        }


//發送新聞
    private function _msgNews($to,$from,$item_list=array()){
        //拼湊文章部分
        $item_str = '';
        foreach ($item_list as $item) {
            $item_str .= sprintf($this->_msg_template['news_item'],$item['title'],$item['desc'],$item['picurl'],$item['url']);
        }
        //拼湊主體部分
        $response = sprintf($this->_msg_template['news'], $to, $from, time(), count($item_list), $item_str);
        die($response);
    }

六、菜單建立刪除

通常公衆號底部都有1-3個菜單選項,選項裏可能還有子菜單,這個如何經過php代碼進行建立?

菜單建立和刪除都是針對全部的,不能單獨操做某一個菜單

//菜單刪除
    public function menuDelete(){
        $url ='https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=' . $this->getAccessToken();
        $result = $this->_request('get',$url);
        $result_obj = json_decode($result);
        if($result_obj->errcode == 0){
            return true;
        }else{
            return false;
        }
    }

刪除很簡單,調用這個函數就刪除全部菜單了,不過已關注的用戶須要24小時後纔會生效。

//建立菜單
    public function menuSet($menu) {
        $url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=' . $this->getAccessToken();
        $data = $menu;
        $result_obj = json_decode($this->_request('post',$url, $data));
        if ($result_obj->errcode == 0) {
            return true;
        } else {
            echo $result_obj->errmsg, '<br>';
            return false;
        }
    }

建立菜單須要咱們傳一個json格式參數,同同樣已關注的用戶也會24小時後生效

一、自定義菜單最多包括3個一級菜單,每一個一級菜單最多包含5個二級菜單。 二、一級菜單最多4個漢字,二級菜單最多7個漢字,多出來的部分將會以「...」代替。
各參數的類型,以及做用,請到開發者文檔查看:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013

json數據格式以下:建立了3個主菜單,以及對應的子菜單。

$menu = <<<JSON
{
    "button": [
        {
            "name": "掃碼",
            "sub_button": [
                {
                    "type": "scancode_waitmsg",
                    "name": "掃碼帶提示",
                    "key": "scancode_waitmsg",
                    "sub_button": [ ]
                },
                {
                    "type": "scancode_push",
                    "name": "掃碼推事件",
                    "key": "scancode_push",
                    "sub_button": [ ]
                }
            ]
        },
        {
            "name": "發圖",
            "sub_button": [
                {
                    "type": "pic_sysphoto",
                    "name": "系統拍照發圖",
                    "key": "pic_sysphoto",
                   "sub_button": [ ]
                 },
                {
                    "type": "pic_photo_or_album",
                    "name": "拍照或者相冊發圖",
                    "key": "pic_photo_or_album",
                    "sub_button": [ ]
                },
                {
                    "type": "pic_weixin",
                    "name": "微信相冊發圖",
                    "key": "pic_weixin",
                    "sub_button": [ ]
                }
            ]
        },
        {
            "name": "快捷操做",
            "sub_button" : [
                {
                    "name": "地理位置",
                    "type": "location_select",
                    "key": "location_select"
                },
                {
                    "name": "普通點擊",
                    "type": "click",
                    "key": "click"
                },
                {
                    "name": "查看URL",
                    "type": "view",
                    "url" : "http://www.soso.com/"
                },
            ]
        },
    ]
}
JSON;

源碼下載:https://github.com/Ivanlovening/wechat
相關文章
相關標籤/搜索