按照25课的套路在改下index.php即可实现,代码如下所示:
<?php /** * wechat php test */ //define your token require_once "common.php"; //这里是引入curl发送函数的类 require_once 'WeChat.class.php'; define("TOKEN", "twgdh"); //这里让这个类继承了curl发送参数的类 class wechatCallbackapiTest extends WeChat { 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)){ /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection, the best way is to check the validity of xml by yourself */ // 使用simplexml技术对xml进行解析 // libxml_disable_entity_loader(true), 是从安全性考虑,为了防止xml外部注入, //只对xml内部实体内容进行解析 libxml_disable_entity_loader(true); //加载 postStr 字符串 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); file_put_contents('abc.log', " ". $postStr, FILE_APPEND); $fromUsername = $postObj->FromUserName; file_put_contents('abc.log', " ". $fromUsername, FILE_APPEND); $toUsername = $postObj->ToUserName; file_put_contents('abc.log', " ". $toUsername, FILE_APPEND); $keyword = trim($postObj->Content); $time = time(); global $tmp_arr; //根据接收到的消息类型,来进行分支处理(switch) switch($postObj->MsgType) { case 'event': if($postObj->Event == 'subscribe') { $contentStr = "欢迎关注leigood微信测试号噢"; $resultStr = sprintf($tmp_arr['text'], $fromUsername, $toUsername, $time, $contentStr); echo $resultStr; } //响应用户的点击事件 if($postObj->Event == 'CLICK'){ if($postObj->EventKey == 'V1001_TODAY_MUSIC'){ //自定义菜单里面有很多个,这里key是自定义的 //这里主要写自己想要的业务逻辑 $contentStr = "夺命雷公狗欢迎您来到编程世界"; $resultStr = sprintf($tmp_arr['text'], $fromUsername, $toUsername, $time, $contentStr); echo $resultStr; } } break; case 'text': //回复文本模块 //这里开始测试客服消息接口了 if($keyword == '文本'){ //获取token require 'get_token.php'; $contentStr = '这是客服接口的回复,我们可以帮助您什么?'; //对发送的内容进行urlencode编码,防止中文乱码 $contentStr = urlencode($contentStr); //到时候我们我发送的内容我们放到一个数组里面去了 $content_arr = array('content'=>"{$contentStr}"); //这里的意思是将来我要发送消息给这个用户 $reply_arr = array('touser'=>"{$fromUsername}",'msgtype'=>'text','text'=>$content_arr); //下一步就是将编码转成规定的json格式 $post = json_encode($reply_arr); //url解码,如果不解码他将会发来一段二进制代码 $post = urldecode($post); $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$access_token}"; //这里我们来使用类的继承机制,来简化代码 $this -> http_request($url,$post); //这里是可以回复多条消息的,只需要在执行下这个函数即可 //$this -> http_request($url,$post); }else if($keyword == '图片'){ //这里的media_id以后是从数据库里面进行查询出来的 $media_id = 'e9-vVDge44mS0gRN2SbE_oOtY64JVozQBSdkV4SIJnPnJjgRDZTBxrS-YGbd72Z3'; $content_arr = array('media_id'=>"{$media_id}"); $reply_arr = array('touser'=>"{$fromUsername}",'msgtype'=>'image','image'=>$content_arr); $post = json_encode($reply_arr); //引入token值 $access_token = $this -> get_token(); $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$access_token}"; //CURL发送 $this -> http_request($url,$post); }else if($keyword == '歌曲'){ //这里的media_id以后是从数据库里面进行查询出来的 $media_id = 'y-a1TVDFOrdarZSLI-BYXLWaa-KvKYxO4errfsrPrF-CgNHSUm0tmICsAw1oFkcz'; $content_arr = array('media_id'=>"{$media_id}"); $reply_arr = array('touser'=>"{$fromUsername}",'msgtype'=>'voice','voice'=>$content_arr); //让他进行json格式编码 $post = json_encode($reply_arr); //引入token值 $access_token = $this -> get_token(); $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$access_token}"; //CURL发送 $this -> http_request($url,$post); //让他推送多一段语音 $this -> http_request($url,$post); }else if($keyword == '视频'){ //这里的media_id以后是从数据库里面进行查询出来的 $media_id = '5tkUzLBkiD_wDwEVS05CWp7yXQCHKcHKIWcZUV7Q8pnvwN-WSPBJKRNzgLkaBwLG'; $title = '人狗请未了'; $title = urlencode($title); //必须处理,否则将来是乱码 $description = '描述人狗请未了之熟女也喜欢'; $description = urlencode($description);//必须处理,否则将来是乱码 $content_arr = array('media_id'=>"{$media_id}",'title'=>"{$title}",'description'=>"{$description}"); //手册上还有一个thumb_media_id(缩略图)这个可以不填写,没有大不了就是不显示 $reply_arr = array('touser'=>"{$fromUsername}",'msgtype'=>'video','video'=>$content_arr); //让他进行json格式编码 $post = json_encode($reply_arr); //url解码 $post = urldecode($post); //引入token值 $access_token = $this -> get_token(); $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$access_token}"; //CURL发送 $this -> http_request($url,$post); //让他推送多两段视频 $this -> http_request($url,$post); $this -> http_request($url,$post); }else if($keyword == '图文'){ //以后这些数据都是从数据库里面提取的 //构造第一个图文 //温馨提示:如果是单条图文描述才会有用,多图文没用 //picurl是压缩图,大小为:200*200 大图的是360*200 $content_arr1 = array( 'title'=>urlencode('第一条图文百度'), 'description'=>urlencode('描述第一条图文'), 'url'=>'http://www.baidu.com', 'picurl'=>'http://weixin.showtp.com/images/a1.png' ); $content_arr2 = array( 'title'=>urlencode('第二条图文谷歌'), 'description'=>urlencode('描述第二条图文'), 'url'=>'http://www.google.com.hk', 'picurl'=>'http://weixin.showtp.com/images/a2.png' ); $content_arr = array($content_arr1,$content_arr2); $content_arr = array('articles'=>$content_arr); $reply_arr = array('touser'=>"{$fromUsername}",'msgtype'=>'news','news'=>$content_arr); //让他进行json格式编码 $post = json_encode($reply_arr); //url解码 $post = urldecode($post); //引入token值 $access_token = $this -> get_token(); $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$access_token}"; //CURL发送 $this -> http_request($url,$post); }else{ $contentStr = '您输入的格式有误'; $resultStr = sprintf($tmp_arr['text'], $fromUsername, $toUsername, $time, $contentStr); echo $resultStr; } break; case 'image': //处理用户上传图片 $media_id = $postObj -> MediaId; //获取到用户上传的图片的mediaid $resultStr = sprintf($tmp_arr['image'], $fromUsername, $toUsername, $time, $media_id); echo $resultStr; //将图片保存到本地服务器的文件系统 //1.先给图片创建一个名字 $image_file_name = time().'.jpg'; //2.获取该图片的内容 $image_file = file_get_contents($postObj->PicUrl); //3.保存到本地服务器的文件系统 //提醒:一定要保证您创建的文件夹是www用户可读可写,否则无法保存该图片到文件夹下 file_put_contents("./uploadimage/".$image_file_name,$image_file); //将图片的路径和相关信息入库 //1.创建一张表 //2.链接mysql数据库,并且添加图片信息 $connect = mysql_connect('localhost','root','root'); mysql_select_db('wxdb',$connect); mysql_query('set names utf8'); $media_path = "./uploadimage/".$image_file_name; //路径 $sql = "insert into keep_image_uploads (id,openid,media_id,media_path) values(NULL,'{$fromUsername}','{$media_id}','{$media_path}')"; mysql_query($sql,$connect); break; case 'voice': //处理用户上传语言的业务逻辑 $media_id = $postObj -> MediaId; //获取media_id的id号 $resultStr = sprintf($tmp_arr['voice'], $fromUsername, $toUsername, $time, $media_id); echo $resultStr; break; case 'location': //处理用户上传的地理位置信息 $Location_X = $postObj -> Location_X; //获取上传地理位置的纬度 $Location_Y = $postObj -> Location_Y; //获取上传地地理位置经度 $contentStr = "您上报的地理位置是: 经度是:{$Location_Y} 纬度是: {$Location_X}"; $resultStr = sprintf($tmp_arr['text'], $fromUsername, $toUsername, $time, $contentStr); echo $resultStr; break; case 'link': //接收并回复链接信息 //获取到用户上传的链接信息 $Title = $postObj -> Title; $Url = $postObj -> Url; $contentStr = "<a href='{$Url}'>{$Title}</a>"; $resultStr = sprintf($tmp_arr['text'], $fromUsername, $toUsername, $time, $contentStr); echo $resultStr; break; } }else { echo ""; exit; } } private function checkSignature() { // you must define TOKEN by yourself if (!defined("TOKEN")) { throw new Exception('TOKEN is not defined!'); } $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); // use SORT_STRING rule sort($tmpArr, SORT_STRING); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ return true; }else{ return false; } } } //如果这段代码放在上面,那程序将会报错,因为继承的问题,会显示类没有找到 $wechatObj = new wechatCallbackapiTest(); //当接入成功后,请注销这句话,否则,会反复验证。 //$wechatObj->valid(); //添加响应请求的语句 $wechatObj->responseMsg(); ?>
核心代码如下所示:
在开发发送客服消息接口注意以下3点细节即可
1.程序开发时,可以使用网页调试工具先上传视频、声音等多媒体文件
2.客服接口发送消息格式为json格式,因此需要对发送消息的格式进行json编码处理
3.为防止出现中文乱码,需要进行urlencode编码,在使用curl函数post数据时,需要进行urldecode解码,切记