微信公众号被动回复图文消息
回复文字消息
回复图文消息
输入任意文字,回复hello你好啊;输入图文消息,回复相应的消息;输入附近,根据用户的地理位置,调用高德地图的api
搜索附近5000m的超市,返回前3个结果,以图文的消息回复用户。
application\index\controller\Weixin.php
实例
<?php namespace app\index\controller; use think\Controller; use think\facade\Cache; class Weixin extends Controller { public function __construct(){ parent::__construct(); $this->model=model('Weixin'); } public function index() { $valid=$this->model->valid(); if(!$valid){ exit('signature error'); } $xmldata=file_get_contents("php://input"); /* $xmldata='<xml><ToUserName><![CDATA[gh_f10a1709655b]]></ToUserName> <FromUserName><![CDATA[o9i9i0TUiPy3hlFgcVk2lswL9T_U]]></FromUserName> <CreateTime>1527982562</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> <EventKey><![CDATA[]]></EventKey> </xml>'; */ // xml transfer object $postObj=simplexml_load_string($xmldata,'SimpleXMLElement',LIBXML_NOCDATA); $data=(array)$postObj; // file_put_contents('D://subs.txt',var_export($data,true)); // dump($data['FromUserName']); if(isset($data['MsgType']) && $data['MsgType'] == 'event'){ //subscribe if($data['Event'] == 'subscribe'){ $this->model->subscribe($data); } //unsubscribe if($data['Event'] == 'unsubscribe'){ $this->model->unsubscribe($data); return 'unsubscribe ok'; } if($data['Event'] == 'LOCATION'){ $this->model->location($data); // file_put_contents('d://locate.txt',var_export($data,true)); exit('success'); } } // file_put_contents('d://msg.txt',$data); // 回复文本消息 if(isset($data['MsgType']) && $data['MsgType'] == 'text'){ $this->robot($data); exit('success'); } // exit(input('get.echostr')); } public function get_access_token($iscache=true){ $cache_key='access_token'; if(!$iscache){ Cache::rm($cache_key); } $data=Cache::get($cache_key); if($data && $iscache){ return $data; } $appid=config('app.appid'); $appsecret=config('app.APPSECRET'); $url='https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appsecret; $res=http_Get($url); // dump($res); $res=json_decode($res,true); // dump($res); if(!isset($res[$cache_key])){ return false; } Cache::set($cache_key,$res['access_token'],($res['expires_in']-600)); return $res[$cache_key]; } public function custom_menu(){ $access_token=$this->get_access_token(); if(!$access_token){ exit('access_token get failed'); } $url='https://api.weixin.qq.com/cgi-bin/menu/create?access_token='.$access_token; $data = '{ "button":[ { "type":"view", "name":"Home", "url":"http://scottshen.top/" }, { "type":"view", "name":"视频教程", "url":"http://www.baidu.com" }, { "name":"用户info", "sub_button":[ { "type":"view", "name":"用户信息", "url":"http://881c65b6.ngrok.io/index.php/index/weixin/auth" }, { "type":"view", "name":"用户地理位置", "url":"http://881c65b6.ngrok.io/index.php/index/weixin/location" }] }] }'; $res=http_Post($url,$data); dump($res); } public function auth(){ // halt(config('app.APPID')); $appid=config('app.appid'); $redirect='http://881c65b6.ngrok.io/index.php/index/weixin/userinfo'; $url_code = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.urlEncode($redirect) .'&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect'; header('Location:'.$url_code); } public function userinfo(){ // dump(config('app.APPID')); $code=input('get.code'); // dump($code); $res=$this->model->auth_access_token($code); // dump($res); $auth_access_token=$res['access_token']; $openid=$res['openid']; // dump($auth_access_token); $userinfo=$this->model->get_userinfo($auth_access_token,$openid); dump($userinfo); } public function location(){ $data['appid']=config('app.appid'); $data['timestamp']=time(); $data['nonceStr']=md5(time().rand(1,999)); //生成签名 $access_token=$this->get_access_token(); $jsapi_ticket=$this->model->jsapi_ticket($access_token); //签名字符串 //noncestr s小写,查了好久这个问题,报invalid signature, //拼接字符串是noncestr $parmas['noncestr']=$data['nonceStr']; $parmas['jsapi_ticket']=$jsapi_ticket; $parmas['timestamp']=$data['timestamp']; $parmas['url']="http://881c65b6.ngrok.io/index.php/index/weixin/location"; ksort($parmas,SORT_STRING); // dump($parmas); $str=urldecode(http_build_query($parmas)); //生成签名 $data['signature']=sha1($str); // dump(sha1($str)); // dump($data['signature']); return $this->fetch('',$data); } private function robot($data){ if($data['Content'] == '图文消息'){ $response=$this->model->img_article_msg($data); exit($response); } if($data['Content'] == '附近'){ $response=$this->model->near_shops($data['FromUserName'],$data['ToUserName'],5000); // exit($response); exit($response); } //调用聊天机器人 $response=$this->model->robot($data); /* $response='<xml> <ToUserName>'.$data['FromUserName'] .'</ToUserName> <FromUserName>'.$data['ToUserName'] .'</FromUserName> <CreateTime>'.time().'</CreateTime> <MsgType>text</MsgType> <Content>hello</Content> </xml>'; */ exit($response); } public function tests(){ $params['appid'] = '10001'; $key = '4fa92702a0633127d26ba957d97680ab'; $params['timestamp'] = time(); $params['msg'] = input('get.msg'); ksort($params); $str = http_build_query($params); $sign = sha1($str.$key); dump($sign); $url = 'http://tests.php.cn/index.php/weixintest/robot?'.$str.'&sign='.$sign; $res = http_get($url); $res = json_decode($res,true); dump($res); } }
运行实例 »
点击 "运行实例" 按钮查看在线实例
application\index\model\Weixin.php
实例
<?php namespace app\index\model; use think\Model; use think\Db; use think\facade\Cache; class Weixin extends Model { public function valid() { $signature=input('get.signature'); // $signature='c5052967c11f8d7e59c3b4011407b94c697b1ceb'; // var_dump($signature); $timestamp=input('get.timestamp'); // $timestamp='1527896867'; $nonce=input('get.nonce'); // $nonce='3010175004'; $echostr=input('get.echostr'); // $echostr='9044276551450221539'; $token=config('app.token'); // file_put_contents('d://data.txt','signature='.$signature.' timestmp='.$timestamp.' nonce='.$nonce.' echostr='.$echostr); $tmpArr=array($timestamp,$nonce,$token); sort($tmpArr,SORT_STRING); // dump($tmpArr); $tmpStr=implode($tmpArr); // echo $tmpStr; // $tmpStr=sha1($tmpStr); // if(sha1($tmpStr) != $signature){ // exit('error'); return false; } // 首次接入成功需要输出$echostr // exit($echostr); return true; } //网页授权access_tonken public function auth_access_token($code){ $appid=config('app.appid'); $appsecret=config('app.APPSECRET'); $url='https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appid.'&secret='. $appsecret.'&code='.$code.'&grant_type=authorization_code'; $res=http_Get($url); $res=json_decode($res,true); if(!isset($res['access_token'])){ return false; } return $res; } public function get_userinfo($auth_access_token,$openid){ $url='https://api.weixin.qq.com/sns/userinfo?access_token='. $auth_access_token.'&openid='. $openid.'&lang=zh_CN'; $res=http_Get($url); $res=json_decode($res,true); return $res; } public function subscribe($data){ dump($data['FromUserName']); $user=Db::table('wechat') ->where('openid',$data['FromUserName']) ->find(); // halt($user); // 新关注用户 if(!$user){ $data=['openid'=>$data['FromUserName'], 'sub_status'=>1, 'add_time'=>time(), ]; Db::table('wechat') ->insertGetId($data); } else { Db::table('wechat') ->where('openid',$data['FromUserName']) ->update(['sub_status'=>1]); } } public function unsubscribe(){ Db:table('wechat') ->where('openid',$data['FromUserName']) ->update(['sub_status'=>0]); } // 获取jsai_ticket public function jsapi_ticket($access_token,$iscache=true){ $key='jsapi_ticket'; if(!$iscache){ Cache::rm($key); } $data=Cache::get($key); if($data && $iscache){ return $data; } $appid=config('app.appid'); $appsecret=config('app.APPSECRET'); $url='https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='. $access_token.'&type=jsapi'; $res=http_Get($url); $res=json_decode($res,true); if(!isset($res['ticket'])){ return false; } Cache::set($key,$res['ticket'],$res['expires_in']-100); return $res['ticket']; } public function robot($data){ /* $config=config('app.robot'); $params['appid']=$config['appid']; $key=$config['key']; $params['timestamp']=time(); $parmas['msg']=$data['Content']; ksort($parmas); $str=http_build_query($parmas); $sign=sha1($str.$key); $url = 'http://tests.php.cn/index.php/weixintest/robot?'.$str.'&sign='.$sign; $res=http_Get($url); $res=json_decode($res,true); $res['msg']=str_replace('{br}',"\n",$res['msg']); */ $response='<xml> <ToUserName>'.$data['FromUserName'] .'</ToUserName> <FromUserName>'.$data['ToUserName'] .'</FromUserName> <CreateTime>'.time(). '</CreateTime> <MsgType>text</MsgType> <Content>hello你好啊</Content> </xml>'; // file_put_contents('d:\\robot.txt',$response); return $response; } public function img_article_msg($data){ // file_put_contents('d://imgarticle.txt',$data); //读取图文消息 $articles=[ ['title'=>'宋大牛传送门', 'description'=>'芝麻开门', 'picurl'=>'http://img.lanrentuku.com/img/allimg/1805/15270368233208.jpg', 'url'=>'haimaer.cnblogs.com', ], ['title'=>'python', 'description'=>'python好用的语言', 'picurl'=>'http://img.lanrentuku.com/img/allimg/1804/15249056684370.jpg', 'url'=>'www.python.org', ], ]; $xml=$this->build_img_text_msg($data['FromUserName'],$data['ToUserName'],$articles); return $xml; } private function build_img_text_msg($from,$to,$data){ $str='<xml><ToUserName>'.$from .'</ToUserName><FromUserName>'.$to .'</FromUserName><CreateTime>'.time() .'</CreateTime><MsgType>news</MsgType><ArticleCount>'.count($data).'</ArticleCount><Articles>'; foreach ($data as $item){ $str.='<item><Title>'.$item['title'] .'</Title> <Description>'.$item['description'] .'</Description><PicUrl>'.$item['picurl'] .'</PicUrl><Url>'.$item['url'].'</Url></item>'; } $str.='</Articles></xml>'; // file_put_contents('d://build.txt',$str); return $str; } // 附近的店铺,默认5公里的超市,显示3条结果 /* *$from 微信用户 $to 开发者 */ public function near_shops($from,$to,$distance=5000){ $query=Db::table('wechat')->where('openid',$from) ->find(); $url='http://restapi.amap.com/v3/place/around?key='. config('app.amap').'&location='.$query['longitude'].','.$query['latitude'].'&keywords=超市&radius='.$distance.'&offset=3'; file_put_contents('d://url.txt',$url); $res=http_Get($url); file_put_contents('d://response.txt',$res); //xml to objcet $json=json_decode($res,true); file_put_contents('d://res.txt',var_export($json,true)); $market=$json['pois']; $shop_list=[]; if(!isset($market)){ $shop_list=[ 'title'=>'暂无数据', 'description'=>'你来到了火星', 'picurl'=>'', 'url'=>'', ]; $xml=$this->build_img_text_msg($from,$to,$shop_list); return $xml; } foreach($market as $item){ $inline_list=[ 'title'=>$item['name'], 'description'=>'地址:'.$item['address'] .' 距离(m):'.$item['distance'], 'picurl'=>'', 'url'=>'', ]; array_push($shop_list,$inline_list); } file_put_contents('d://market.txt',var_export($shop_list,true)); /* $shop_list=[ [ 'title'=>'123', 'description'=>'456', 'picurl'=>'', 'url'=>'http://www.baidu.com', ] ]; */ $xml=$this->build_img_text_msg($from,$to,$shop_list); file_put_contents('d://xml.txt',$xml); return $xml; } //少写了:: public function location($data){ Db::table('wechat')->where('openid',$data['FromUserName']) ->update(['longitude'=>$data['Longitude'],'latitude'=>$data['Latitude']]); } }
运行实例 »
点击 "运行实例" 按钮查看在线实例
效果