1. 程式人生 > >微信公眾平臺配置伺服器之後實現自動回覆

微信公眾平臺配置伺服器之後實現自動回覆

參考微信公眾平臺開發者文件

  1. 下載示例程式碼
  2. 將示例程式碼通過FTP傳至自己的伺服器
  3. 配置域名和Token(我這裡是dandan)
  4. 隨機生成EncodingAESKey
  5. 驗證

新定義一個方法

public function index(){
if (isset($_GET['echostr'])){
$this->valid();
} else {
$this->responseMsg();
}

註釋掉

//$wechatObj->valid();

新加一行

$wechatObj->index();

開發者文件->訊息管理->被動回覆訊息

微信的示例程式碼裡面自帶了一個回覆文字訊息的XML資料包

if(!empty( $keyword ))
{
$msgType = "text";
$contentStr = "Welcome to wechat world!";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}else{
echo "Input something...";
}

示例程式碼改到這一步的話,你傳送任意一個字元給公眾號,他都會回覆你

Welcome to wechat world!

對比一下文字訊息、圖片訊息,語音訊息的資料包結構

文字訊息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>

1240
文字訊息

圖片訊息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[media_id]]></MediaId>
</Image>
</xml>

1240
圖片訊息

語音訊息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<Voice>
<MediaId><![CDATA[media_id]]></MediaId>
</Voice>
</xml>

1240
語音訊息

可以發現MsgType代表的就是訊息型別,語音訊息和圖片訊息都有一個MediaID。
圖片、語音、音樂、還有視訊。這些都屬於媒體,上傳到微信伺服器後都會生成一個MediaID,相當於每個檔案的"身份證"。

微信的示例程式碼中沒有回覆圖片訊息和語音訊息的資料包,所以需要匯入。

            $imgTpl = "<xml>
                         <ToUserName><![CDATA[%s]]></ToUserName>
                         <FromUserName><![CDATA[%s]]></FromUserName>
                         <CreateTime>%s</CreateTime>
                         <MsgType><![CDATA[%s]]></MsgType>
                         <Image>
                         <MediaId><![CDATA[%s]]></MediaId>
                         </Image>
                         </xml>";
            $voiceTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[%s]]></MsgType>
                        <Voice>
                        <MediaId><![CDATA[%s]]></MediaId>
                        </Voice>
                        </xml>";

還有一個就是預設的示例程式碼中沒有訊息型別,所以需要新增一個變數。

$type = $postObj->MsgType;

然後用If 語句判斷訊息型別做出相應的回覆。

  1. 使用者傳送文字訊息回覆給使用者 文字訊息+'使用者傳送的文字'。
  2. 使用者傳送圖片訊息回覆給使用者同一張圖片。
  3. 使用者傳送語音訊息回覆給使用者同樣的語音訊息。
            if($type == 'text') {
                $str = '文字訊息' . $keyword; 
                 $MsgType = 'text';
            $echo = sprintf($textTpl,$fromUsername,$toUsername,$time,$MsgType,$str);
            }else if ($type == 'image'){
                $MsgType = 'image';
                $echo = sprintf($imgTpl,$fromUsername,$toUsername,$time,$MsgType,$postObj->MediaId);

            }else if ($type =='voice'){
                $MsgType = 'voice';
                $echo = sprintf($voiceTpl,$fromUsername,$toUsername,$time,$MsgType,$postObj->MediaId);
            }

這裡要注意的是sprintf()裡面需要交換fromUsername和toUsername的順序,其他的變數順序不能顛倒,如果顛倒則公眾號無法正常回復。因為fromUsername既代表使用者發給你,也代表你傳送給使用者,toUsername同理,微信裡面還有很多東西可以去嘗試比如語音識別介面等等。

完整程式碼如下

<?php
/**
  * wechat php test
  */

//define your token
define("TOKEN", "dandan");
$wechatObj = new wechatCallbackapiTest();
//$wechatObj->valid();
$wechatObj->index();

class wechatCallbackapiTest
{
    public function index(){
        if (isset($_GET['echostr'])){
            $this->valid();
        } else {
            $this->responseMsg();
        }
    }
    public function valid()
    {
        $echoStr = $_GET["echostr"];

        //valid signature , option
        if($this->checkSignature()){
            echo $echoStr;
            exit;
        }
    }

    public function responseMsg()
    {
        //get post data, May be due to the different environments
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

          //extract post data
        if (!empty($postStr)){

                  $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
                $fromUsername = $postObj->FromUserName;
                $toUsername = $postObj->ToUserName;
                $keyword = trim($postObj->Content);
                $type = $postObj->MsgType;
                $time = time();
                $textTpl = "<xml>
                            <ToUserName><![CDATA[%s]]></ToUserName>
                            <FromUserName><![CDATA[%s]]></FromUserName>
                            <CreateTime>%s</CreateTime>
                            <MsgType><![CDATA[%s]]></MsgType>
                            <Content><![CDATA[%s]]></Content>
                            <FuncFlag>0</FuncFlag>
                            </xml>";

                $imgTpl = "<xml>
                             <ToUserName><![CDATA[%s]]></ToUserName>
                             <FromUserName><![CDATA[%s]]></FromUserName>
                             <CreateTime>%s</CreateTime>
                             <MsgType><![CDATA[%s]]></MsgType>
                             <Image>
                             <MediaId><![CDATA[%s]]></MediaId>
                             </Image>
                             </xml>";
                $voiceTpl = "<xml>
                            <ToUserName><![CDATA[%s]]></ToUserName>
                            <FromUserName><![CDATA[%s]]></FromUserName>
                            <CreateTime>%s</CreateTime>
                            <MsgType><![CDATA[%s]]></MsgType>
                            <Voice>
                            <MediaId><![CDATA[%s]]></MediaId>
                            </Voice>
                            </xml>";
                if($type == 'text') {
                    $str = '文字訊息' . $keyword; 
                     $MsgType = 'text';
                $echo = sprintf($textTpl,$fromUsername,$toUsername,$time,$MsgType,$str);
                }else if ($type == 'image'){
                    $MsgType = 'image';
                    $echo = sprintf($imgTpl,$fromUsername,$toUsername,$time,$MsgType,$postObj->MediaId);

                }else if ($type =='voice'){
                    $MsgType = 'voice';
                    $echo = sprintf($voiceTpl,$fromUsername,$toUsername,$time,$MsgType,$postObj->MediaId);
                }


                    echo $echo;

        }else {
            echo "";
            exit;
        }
    }

    private function checkSignature()
    {
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];    

        $token = TOKEN;
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr);
        $tmpStr = implode( $tmpArr );
        $tmpStr = sha1( $tmpStr );

        if( $tmpStr == $signature ){
            return true;
        }else{
            return false;
        }
    }
}

?>