1、服务器配置
在“微信公众平台”上将“服务器配置”启用,填写“服务器地址”(即关注者输入消息后调用的回调接口,返回回复文本),“令牌”(在接口验证中要用到),
“消息加解密密钥”、加解密方式暂时设为明文模式,先简单入手。
2、配置接口
public function valid()
{$echoStr = $_GET["echostr"];if ($echoStr) {if ($this->checkSignature()) {echo $echoStr;exit;}}
}
当第一步启用的时候,必须先调用这个方法,收到"echostr"后再验证(checkSignature)是否是我们的微信公众号发来的,如果是则把"echostr"回传回去,这个时候第一步点击启用便会成功,否则启用会失败,这个可以用来测试我们这个接口是否写对了。只要第一步启用成功,那之后便不需要再进行验证了,只需直接拿到传过来的信息再进行分析处理。
其中checkSignature方法如下:
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;}
}
其中$token值便是第一步中设置的token值,记得替换下。
3、处理逻辑
public function responseMsg()
{$xml_str = file_get_contents('php://input');if (empty($xml_str)) {die('');}if (!empty($xml_str)) {// 解析该xml字符串,利用simpleXMLlibxml_disable_entity_loader(true);//禁止xml实体解析,防止xml注入$request_xml = simplexml_load_string($xml_str, 'SimpleXMLElement', LIBXML_NOCDATA);//判断该消息的类型,通过元素MsgTypeswitch ($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);}break;case 'text'://文本消息$this->_doText($request_xml);break;case 'image'://图片消息
// $this->_doImage($request_xml);$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, '这是一张图片');break;case 'voice'://语音消息
// $this->_doVoice($request_xml);$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, '这是一段语音');break;case 'video'://视频消息
// $this->_doVideo($request_xml);$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, '这是一段视频');break;case 'shortvideo'://短视频消息
// $this->_doShortvideo($request_xml);$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, '这是一段短视频');break;case 'location'://位置消息
// $this->_doLocation($request_xml);$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, '这是一个位置信息');break;case 'link'://链接消息
// $this->_doLink($request_xml);$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, '这是一个链接');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>',//某个新闻模板
);/*** 发送文本信息* @param [type] $to 目标用户ID* @param [type] $from 来源用户ID* @param [type] $content 内容*/
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);
}private function _doText($request_xml)
{$content = $request_xml->Content;$url = 'http://www.tuling123.com/openapi/api?key=xxxxxxxxxxxxxxx&info='.$content;$response_content = json_decode($this->_request('get', $url, array(), false));$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $response_content->text);
}//发送请求方法
/*** @param string $method 'get'|'post' 请求的方式* @param string $url URL* @param array|json $data post请求需要发送的数据* @param bool $ssl*/
public function _request($method='get',$url,$data=array(),$ssl=true){//curl完成,先开启curl模块//初始化一个curl资源$curl = curl_init();//设置curl选项curl_setopt($curl,CURLOPT_URL,$url);//url//请求的代理信息$user_agent = isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']: 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0 FirePHP/0.7.4';curl_setopt($curl,CURLOPT_USERAGENT,$user_agent);//referer头,请求来源curl_setopt($curl,CURLOPT_AUTOREFERER,true);curl_setopt($curl, CURLOPT_TIMEOUT, 30);//设置超时时间//SSL相关if($ssl){//禁用后,curl将终止从服务端进行验证;curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);//检查服务器SSL证书是否存在一个公用名curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,2);}//判断请求方式post还是getif(strtolower($method)=='post') {/**************处理post相关选项******************///是否为post请求 ,处理请求数据curl_setopt($curl,CURLOPT_POST,true);curl_setopt($curl,CURLOPT_POSTFIELDS,$data);}//是否处理响应头curl_setopt($curl,CURLOPT_HEADER,false);//是否返回响应结果curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);//发出请求$response = curl_exec($curl);if (false === $response) {echo '<br>', curl_error($curl), '<br>';return false;}//关闭curlcurl_close($curl);return $response;
}
其中为了实现自动回复的功能,我采用了图灵机器人的api去实现,大家也可以基于自己的喜好采用第三方或者自己实现,代码借鉴了网上大神的作品,但是做了些修改,注释也很清晰,也就没必要仔细描述了。
4、调用
只要发来消息,直接调用responseMsg()方法即可,这样便实现了一个自动回复的聊天机器人功能。