微信公众号回复图文消息——2018年6月6日

2018年06月07日 22:00:06阅读数:2914博客 / 沈斌的博客 / php

微信公众号被动回复图文消息

  1. 回复文字消息

  2. 回复图文消息


输入任意文字,回复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']]);
    }
}

运行实例 »

点击 "运行实例" 按钮查看在线实例

效果

tw.png

loca.png

批改状态:合格

老师批语:

版权申明:本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!

全部评论

文明上网理性发言,请遵守新闻评论服务协议

条评论
  • 博主信息
    沈斌的博客
    博文
    56
    粉丝
    3
    评论
    1
    访问量
    29045
    积分:0
    P豆:417