微信公眾平臺配置伺服器之後實現自動回覆
參考微信公眾平臺開發者文件
- 下載示例程式碼
- 將示例程式碼通過FTP傳至自己的伺服器
- 配置域名和Token(我這裡是dandan)
- 隨機生成EncodingAESKey
- 驗證
新定義一個方法
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>
文字訊息
圖片訊息
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[media_id]]></MediaId>
</Image>
</xml>
圖片訊息
語音訊息
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<Voice>
<MediaId><![CDATA[media_id]]></MediaId>
</Voice>
</xml>
語音訊息
可以發現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 語句判斷訊息型別做出相應的回覆。
- 使用者傳送文字訊息回覆給使用者 文字訊息+'使用者傳送的文字'。
- 使用者傳送圖片訊息回覆給使用者同一張圖片。
- 使用者傳送語音訊息回覆給使用者同樣的語音訊息。
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;
}
}
}
?>