PHP微信定製開發-服務器被動回覆消息之文本消息

在上一篇分享的博客中,php程序已經可以區分各種消息,並把識別到的消息類型回覆給用戶,這次會加入第三方接口的調用回覆消息給用戶

一  準備工作

百度車聯網天氣接口(官方文檔找不到入口了,因爲百度api經常調整,已經無力吐槽了)

獲取天氣信息的接口工具類代碼

<?php
namespace  util;
define("AK","你的百度api AK祕鑰");



class WeatherServiceUtil{
    function getWeatherInfo($city="昆明"){
        $ak=AK;
       
        //初始化
        $curl = curl_init();
        
        //設置抓取的url
        curl_setopt($curl, CURLOPT_URL, "http://api.map.baidu.com/telematics/v3/weather?location=".$city."&output=json&ak=".$ak);
        
        //設置獲取的信息以文件流的形式返回,而不是直接輸出。
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        //執行命令
        $data = curl_exec($curl);
        //關閉URL請求
        curl_close($curl);
        
        $result=json_decode($data,true);
        
        $error=$result["error"];
        $resStr="";
        if($error==0){
            $result=$result["results"][0]["weather_data"][0];
            $resStr=$result["weather"].";".$result["wind"].";".$result["temperature"];
        }else{
            $resStr="天氣預報獲取出錯,請重試或聯繫管理員";
        }
        
       
        return  $resStr;
        
       
    }
   
}


?>

上面的代碼可以再簡化,可使用之前博客寫的http或https工具類,進行再次優化

 

二  把天氣預報整合到消息處理類

$postStr = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input");

 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
 //發送方賬號(openId)
 $fromUsername = $postObj->FromUserName;
 //開發者微信號
 $toUsername = $postObj->ToUserName;
 //消息類型
 $MsgType = strtolower($postObj->MsgType);
 //消息內容
 $keyword = trim($postObj->Content);

需要注意獲取微信服務器返回給我們的數據,不同php版本獲取的方法有差異,本人使用的是php7.3版本,使用的是file_get_contents("php://input")

下面是主要的業務邏輯

if(strpos($keyword, "天氣")!==false){
                    
         //字符串替換獲取城市
         $city=str_replace("天氣", "", $keyword);
                    
         $weatherUtil=new \util\WeatherServiceUtil();
         $result=$weatherUtil->getWeatherInfo($city);
                    
         $typeResult=$result;
                    
 }else{
         $typeResult="你發送的是文本消息";
}

最後來看下全部的代碼

<?php
namespace handler;

include_once __DIR__.DIRECTORY_SEPARATOR."util".DIRECTORY_SEPARATOR."MessageUtil.php";
include_once __DIR__.DIRECTORY_SEPARATOR."util".DIRECTORY_SEPARATOR."WeatherServiceUtil.php";


define("TOKEN", "weixinCourse");

// 1 判斷請求方法,get請求一般爲消息驗證,post爲其他消息交互
// 2 驗證signature是否正確(消息來自微信服務器)
$handler = new \handler\WeixinHandler();
$reqMethod = strtolower($_SERVER["REQUEST_METHOD"]);
if ("get" == $reqMethod && !empty($_GET["echostr"])) {
    if ($handler->isValid()) {
        $echostr = $_GET["echostr"];
        echo $echostr;
        exit();
    }
} else {
    //判斷消息類型,返回"你發送的是xxx消息"
    $handler->responseMessage();
}

class WeixinHandler
{

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

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

        if ($tmpStr) {
            return $tmpStr;
        } else {
            return "";
        }
    }

    function isValid()
    {
        $signature = $_GET["signature"];
        if ($signature == $this->checkSignature()) {
            return true;
        } else {
            return false;
        }
    }
    function responseMessage(){
        $msgUtil = new \util\MessageUtil();
        $defaultMsgType="text";
        //從請求數據獲取FromUserName和ToUserName以及消息類型
        $postStr = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input");
        
        if(!empty($postStr)){
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            //發送方賬號(openId)
            $fromUsername = $postObj->FromUserName;
            //開發者微信號
            $toUsername = $postObj->ToUserName;
            //消息類型
            $MsgType = strtolower($postObj->MsgType);
            //消息內容
            $keyword = trim($postObj->Content);
          
            
            $msgUtil = new \util\MessageUtil();
            $typeResult="";
            $resultStr="";
           
            if("text"==$MsgType){
                if(strpos($keyword, "天氣")!==false){
                    
                    //字符串替換獲取城市
                    $city=str_replace("天氣", "", $keyword);
                    
                    $weatherUtil=new \util\WeatherServiceUtil();
                    $result=$weatherUtil->getWeatherInfo($city);
                    
                    $typeResult=$result;
                    
                }else{
                    $typeResult="你發送的是文本消息";
                }
              
            }else if("image"==$MsgType){
                $typeResult="你發送的是圖片消息";
            }else if("voice"==$MsgType){
                $typeResult="你發送的是語音消息";
            }else if("video"==$MsgType){
                $typeResult="你發送的是視頻消息";
            }else if("shortvideo"==$MsgType){
                $typeResult="你發送的是短視頻消息";
            }else if("location"==$MsgType){
                $typeResult="你發送的是地理位置消息";
            }else if("link"==$MsgType){
                $typeResult="你發送的是鏈接消息";
            }else if("event"==$MsgType){
                //事件推送處理
                $typeResult="事件推送消息";
            }else{
                $typeResult="你發送的是其他類型的消息";
            }
            
            if("text"==$defaultMsgType){
                $resultStr=$msgUtil->textMessageToXml($fromUsername, $toUsername,$typeResult);
            }
           
            echo $resultStr;
           
        }else{
           echo "";
           exit;
       }
    
    }
}

?>

看下運行效果

到這裏爲止功能就實現了,需要注意的是第三方接口的調用要注意返回值的處理,防止報錯、異常等,如用戶輸入的城市不存在查不到數據,也要響應錯誤提示給用戶。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章