微信開發中的訊息驗證與訊息回覆

somehow1002發表於2017-08-08

微信開發中的訊息驗證與訊息回覆

處理邏輯

  1. 判斷微信伺服器傳來的資料是否含有名為echostr的GET引數
  2. 有則進行伺服器訊息驗證(valid)
  3. 沒有則微信推送過來的是一條訊息,需要我們處理。
    訊息型別分為
    1)事件型別:使用者關注/取消關注事件、掃描二維碼事件……
    2)被動回覆型別:使用者傳送過來一條文字、圖片、語音……
    然後根據需求回覆相應的文字、圖片、圖文….

程式碼示例

<?php
define("TOKEN","###your token###");
require_once 'response.class.php';

$res=new response();
if(!isset($_GET['echostr'])){
    responseMsg();
}else{
    valid();
}

function valid(){
    /* @微信伺服器訊息驗證
     *
     * 1)將token、timestamp、nonce三個引數進行字典序排序
     * 2)將三個引數字串拼接成一個字串進行sha1加密
     * 3)開發者獲得加密後的字串可與signature對比,標識該請求來源於微信
     *
     * */
    $echoStr=$_GET['echostr'];
    $signature=$_GET['signature'];
    $timestamp=$_GET['timestamp'];
    $nonce=$_GET['nonce'];
    $token=TOKEN;
    $tmpArr=array($token,$timestamp,$nonce);
    sort($tmpArr,SORT_STRING);
    $tmpStr=implode($tmpArr);
    $tmpStr=sha1($tmpStr);
    if($tmpStr==$signature){
        echo $echoStr;
        exit();
    }
}

function responseMsg(){
    /* @獲取微信推送過來的post資料(xml)
     * 
     * 以下舊的提取方式,php高版本已經廢棄了
     * $postStr=$GLOBALS['HTTP_RAW_POST_DATA'];
     * 
     * */
    $postStr=file_get_contents("php://input");

    /* @將xml資料轉化為obj
     * 
     * */
    $postObj=simplexml_load_string($postStr,'SimpleXMLElement',LIBXML_NOCDATA);

    /* @根據接收到的不同訊息,進行相應回覆
     * 1.使用者關注事件
     * 2.使用者傳送訊息被動回覆
     * 
     * */
    if(strtolower($postObj->MsgType)=='event'){
        if(strtolower($postObj->Event)=='subscribe'){//使用者關注事件
            $content="歡迎關注XXXX";
            responseText($postObj, $content);
        }
    }else if(strtolower($postObj->MsgType)=='text'){
        switch(trim($postObj->Content)){
            /*被動回覆文字資訊*/
            case 'test':
                $content="this is test!";
                responseText($postObj, $content);
                break;
            case 'time':
                $content="現在是北京時間:".date("Y-m-d H:i:s",time());
                responseText($postObj, $content);
                break;
            case 'website':
                $content="<a href='http://www.hewie.cn'>乘風破浪</a>";
                responseText($postObj, $content);
                break;
            /*被動回覆圖文資訊*/
            case 'news':
                $arr=array(
                    array(
                    'title'=>'我的csdn部落格',
                    'description'=>'歡迎訪問我的csdn部落格',
                    'picUrl'=>'http://avatar.csdn.net/9/5/4/1_somehow1002.jpg',
                    'url'=>'http://blog.csdn.net/somehow1002',
                    ),
                    array(
                    'title'=>'開源中國',
                    'description'=>'。。。。。',
                    'picUrl'=>'https://www.oschina.net/img/ie/logo_osc.png','',
                    'url'=>'https://www.oschina.net/',
                    ),
                );
                responseNews($postObj, $arr);
                break;
            default:
                $content="sorry, I don't understand!";
                $res->responseText($postObj, $content);
                break;
        }
    }
}

function responseText($postObj,$content){
    /* @文字訊息回覆格式
     * 
     * <xml>
     * <ToUserName><![CDATA[toUser]]></ToUserName>
     * <FromUserName><![CDATA[fromUser]]></FromUserName>
     * <CreateTime>12345678</CreateTime>
     * <MsgType><![CDATA[text]]></MsgType>
     * <Content><![CDATA[你好]]></Content>
     * </xml>
     * 
     * */
    $fromUserName=$postObj->ToUserName;
    $toUserName=$postObj->FromUserName;
    $time=time();
    $msgType='text';
    $template="<xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[%s]]></MsgType>
                    <Content><![CDATA[%s]]></Content>
                    </xml>";
    echo sprintf($template,$toUserName,$fromUserName,$time,$msgType,$content);
}

function responseNews($postObj,$arr){
    /* @圖文訊息回覆格式
     * #一個item一則圖文訊息
     * 
     * <xml>
     * <ToUserName><![CDATA[toUser]]></ToUserName>
     * <FromUserName><![CDATA[fromUser]]></FromUserName>
     * <CreateTime>12345678</CreateTime>
     * <MsgType><![CDATA[news]]></MsgType>
     * <ArticleCount>2</ArticleCount>
     * <Articles>
     * <item>
     * <Title><![CDATA[title1]]></Title>
     * <Description><![CDATA[description1]]></Description>
     * <PicUrl><![CDATA[picurl]]></PicUrl>
     * <Url><![CDATA[url]]></Url>
     * </item>
     * <item>
     * <Title><![CDATA[title]]></Title>
     * <Description><![CDATA[description]]></Description>
     * <PicUrl><![CDATA[picurl]]></PicUrl>
     * <Url><![CDATA[url]]></Url>
     * </item>
     * </Articles>
     * </xml>
     * 
     * */
    $fromUserName=$postObj->ToUserName;
    $toUserName=$postObj->FromUserName;
    $time=time();
    $msgType='text';
    $template="<xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[news]]></MsgType>
                    <ArticleCount>".count($arr)."</ArticleCount>
                    <Articles>";
    foreach($arr as $v){
        $template.="
                    <item>
                    <Title><![CDATA[".$v[title]."]]></Title>
                    <Description><![CDATA[".$v[description]."]]></Description>
                    <PicUrl><![CDATA[".$v['picUrl']."]]></PicUrl>
                    <Url><![CDATA[".$v[url]."]]></Url>
                    </item>";
    }
    $template.="
                    </Articles>
                    </xml>";
    echo sprintf($template,$toUserName,$fromUserName,time());
}

參考微信開發手冊
原文地址:http://blog.csdn.net/somehow1002/article/details/76919270
個人見解,如有錯誤之處,歡迎指正。

相關文章