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


上一篇文章我們知道怎么獲取二維碼,這樣別人就可以掃描二維碼來關注我們,但是別人關注后,發送消息,我們怎么進行相關處理?

這里我們就來學習下怎么處理處理這些消息,以及推送消息。

學習之前首先你需要有一個域名和空間

url:填寫你希望微信公眾平台把用戶的消息轉發到哪里

token:隨便輸入,用於微信公眾平台和你的站點進行第一次通信建立關聯用

/*
    用於第一次驗證我們網站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。

然后再提交,就能成功了。

1、關注后,歡迎語的設置

有人關注后,微信公眾平台會給我們發一個xml格式的數據,如下:

 

然后我們對這個信息進行獲取,轉化成我們想要的格式,進行相關判斷,返回數據,同樣也需要組裝成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);
    }

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

2、發送圖片

 

微信中的圖片、語音、視頻、縮略圖統稱素材,發送和接受都是以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就行了。

3、發送音樂

如果用戶輸入音樂,我們發一首歌給他,音樂跟其他的幾個素材不太一樣

 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     }

4、圖靈機器人的接入

圖靈官網注冊申請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進行分類判斷,字符組裝,再回復給用戶。

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

5、發送圖文(新聞)

我一般看到的微信公眾號都是以圖文信息進行推送消息,這個新聞類型怎么發送?

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);
    }

6、菜單創建刪除

一般公眾號底部都有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小時后生效

1、自定義菜單最多包括3個一級菜單,每個一級菜單最多包含5個二級菜單。 2、一級菜單最多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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM