Blogger Information
Blog 71
fans 1
comment 1
visits 86859
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
605-微信公众平台开发:消息推送和附近店辅推送
小威的博客
Original
1098 people have browsed it
  • 微信公众平台开发:消息推送

先分析一下回复消息的逻辑流程:用户发送消息给公众号,微信服务器接收的消息,立即对消息进行编码,并以一个xml格式发给开发者的服务器,开发者的服务器就响应一个编辑好的消息,也以xml格式发回给微信服务器,之后微信服务器解析xml发回给微信服务器。(现支持回复文本、图片、图文、语音、视频、音乐)。

消息推送也是在控制器中-index-方法中写的:

由于消息推送同关注和定位一样以xml数据包推送的,故此也要先对xml解析处理

// 微信推送事件
    public function index(){
        //获取xml数据包,并对数据包解析处理
        $xmldata = file_get_contents("php://input");、
        $postObj = simplexml_load_string($xmldata, 'SimpleXMLElement', LIBXML_NOCDATA);
        $data = (array)$postObj;
        
        if(isset($data['MsgType']) && $data['MsgType'] == 'text'){
            $this->robot($data);
            exit('success');
        }        
        exit(input('get.echostr'));
    }

当服务器判断用户的信息为text文本格式时,就调用机器人接口进行回复

// 机器人接口
    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['ToUserName'],$data['FromUserName']);
            exit($response);
        }
        // 调用器机人智能聊天
        $response = $this->model->robot($data);
        exit($response);
    }

机器人接口也会对消息内容进行判断,如果消息中包含了设定好的关键字,就会回复相应图文信息,如果没有包含的关键,就开启智能聊天功能:调用模型中的机器人robot方法:

  • 消息推送:机器人自动回复  

  • 调用php中文网写好的机器人API,先配置APPID和KEY

return [
    //微信配置
    'token'                  => 'aMCikdpelconEk1omMjK4',
    'appid'                  => 'wxc68d8ac1d6fe2201',
    'appsecret'              => 'ca719e7b9270e24afa511ef0858f0516',
	
    // 机器人API
    'robot'                  => [
        'appid' => '10001',
        'key'   => '4fa92702a0633127d26ba957d97680ab',
    ],
];

由于对接微信平台也有个APPID  所以我们需要在机器人API配置中,包个robot配置,在模型中调用方法如下:

// 机器人聊天
    public function robot($data){
        //1. 调用机器人配置参数
        $config = config('app.robot');
        $params['appid'] = $config['appid'];
        $key = $config['key'];
        //2. 生成签名和消息内容处理
        $params['timestamp'] = time();//生成时间戳
        $params['msg'] = $data['Content'];//用户发送的消息
        ksort($params);//排序数组
        $str = http_build_query($params);//拼接数组
        $sign = sha1($str.$key);//加密生成签名
        //3. 请求机器人智能回复服务
        $url = 'http://www.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']);//替换掉特殊字符串和强制换行
        //4. 打包成xml数据包 返回给微信服务器
        $response = '<xml> <ToUserName>'.$data['FromUserName'].'</ToUserName> <FromUserName>'.$data['ToUserName'].'</FromUserName> <CreateTime>'.time().'</CreateTime> <MsgType>text</MsgType> <Content>'.$res['msg'].'</Content> </xml>';
        return $response;
    }

当微信服务器接收机器人回复的消息,就原样返回给微信客户端,效果如下:1.png

  • 消息推送:图文信息

图文消息推送比较简单的,当用户发送的消息中包含了设定好的关键字,就会回复已编辑好的图文信息给用户浏览即可:

控制器判断和调用模型中的 img_article_msg 方法:关键词content可以自定义

private function robot($data){
        if($data['Content'] == '图文消息'){
            $response = $this->model->img_article_msg($data);
            exit($response);
        }

我们先看看官方的示例和各项参数:

<xml>
<ToUserName>< ![CDATA[toUser]接收方帐号(收到的OpenID) ]></ToUserName>
<FromUserName>< ![CDATA[fromUser]开发者微信号     ]></FromUserName>
<CreateTime>12345678 消息创建时间 (整型)</CreateTime>
<MsgType>< ![CDATA[news] ]>消息类型:新闻/活动</MsgType>
<ArticleCount>2  图文消息个数,限制为8条以内</ArticleCount>
<Articles 多条图文消息信息,注意,如果图文数超过8,则将会无响应>
<item 默认第一个item为大图,>
<Title>< ![CDATA[title1]图文消息标题 ]></Title> 
<Description>< ![CDATA[description1] 图文消息描述]></Description> 类似于新闻简介
<PicUrl>< ![CDATA[picurl]  图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200 ]></PicUrl>
<Url>< ![CDATA[url] 点击图文消息跳转链接    ]></Url>
</item>
<item>
<Title>< ![CDATA[title] ]></Title>
<Description>< ![CDATA[description] ]></Description>
<PicUrl>< ![CDATA[picurl] ]></PicUrl>
<Url>< ![CDATA[url] ]></Url>
</item>
</Articles>
</xml>

这里我们需要注意一下:每一个图文消息都由2个标签包住1.Articles,类似于div或ul标签 >2. item标签类似于li标签

而图文消息有三步形成:

1.编辑好图文消息内容:用数组方法包含节点方式读取图文消息

// 被动回复用户图文消息
    public function img_article_msg($data){
        // 真实环境下是由后台编辑内容,再从数据库读取图文消息,此处我们直接拉取PHP中文网的新闻链接
        $articles = array(
            array('title'=>'从php招聘要求看php程序员应该会什么?','description'=>'目前在国内有很多知名公司都采用PHP 作为主要的开发 Web 开发语言,php中文网小编就从专业的IT招聘网站拉钩网挑选几条php招聘要','picurl'=>'https://img.php.cn/upload/article/000/000/164/58a56f51f0d4c979.jpg','url'=>'http://www.php.cn/toutiao-352287.html'),
            array('title'=>'全球php开发框架排行榜','description'=>'在PHP开发中,选择合适的框架有助于加快软件开发,节约宝贵的项目时间,让开发者专注于功能的实现上。由于流行的框架经过了大量项','picurl'=>'https://img.php.cn/upload/article/000/000/002/82ff85191adbac932aec043cbf901727.jpg','url'=>'http://www.php.cn/toutiao-380795.html'),
        );

读取数据库的图文消息:

public function img_article_msg($data){
        // 数据库读取图文消息
        $res = \think\Db::name('news')->field('id,title,newsmi,img,url')->select();
        foreach ($res as $key => $value){
            $articles[] = array('title'=>$value['title'],'description'=>$value['newsmi'],'picurl'=>$value['img'],'url'=>$value['url']);
        }
}

2. 用一个构造方法 【build_img_text_msg 】对图文消息进行重组成 xml数据包

//构造图文消息
    private function build_img_text_msg($from,$to,$data){
        $str = '<xml><ToUserName>'.$from.'</ToUserName><FromUserName>'.$from.'</FromUserName><CreateTime>'.time().'</CreateTime><MsgType>news</MsgType><ArticleCount>2</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>';
        return $str;
    }

构造图文消息需要几个参数:1. $from 谁发的  2. $to 发给谁的   $data:发送的数据

  • 由于图文消息可以有几段,所以我们对图文消息进行拼接组装:

先将头部标签参数写出来:count($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>';

最后把尾部标签拼接上,最后 return $str;

$str .= '</Articles></xml>';
return $str;

3. 回复图文消息 xml 数据包给微信服务器

$xml = $this->build_img_text_msg($data['FromUserName'],$data['ToUserName'],$articles);
return $xml;

这样一段图文消息就能成功推送出来了  效果如下:

2.png

  • 消息推送:推送附近店铺  根据记录用户的经纬度坐标进行推荐附近店铺,增强营销。。

推送附近店铺跟推送图文消息方法一样,只是推送的内容参数不一样,下面我们看看实现的步骤:

  • 1. 先对用户发送的信息进行判断,是否包含关键字,附近,有就在控制器中调用near_shops的方法:

private function robot($data){
   if($data['Content'] == '附近'){
     $response = $this->model->near_shops($data['ToUserName'],$data['FromUserName']);
     exit($response);
}
  • 2. 设定需推送的店铺经纬度坐标位置:

先创建店铺数据库表shop,创建六个字段:id  title 店铺名称 address 地址 img 店铺图片 lat 经度  lng纬度

可以利用百度地图的拾取坐标系统,或高德地图的高德云图功能来获取地图的经纬度坐标参数,创建店铺数据

QQ截图20180608153034.png

创建好店铺数据后,就可以在模型中写方法:

public function near_shops($from,$to,$distance = 10){
        //先用openid值查找到用户信息
        $user = Db::name('user')->where(array('openid'=>$to))->find();
        //取出经纬度值
        $lat = $user['lat'];
        $lng = $user['lng'];
        //查询计算排序用户群的经纬度
        $res = \think\Db::name('shop')->field('id,title,address,(6371*acos(cos(radians('.$lat.'))*cos(radians(lat))*cos(radians(lng)-radians('.$lng.'))+sin(radians('.$lat.'))*sin(radians(lat)))) AS distance')->having('distance < '.$distance)->order('distance')->select();
        $shop_list = [];
        //循环读取数组的值
        foreach ($res as $key => $value) {
            $shop_list[] = array('title'=>$value['title'],'description'=>$value['address'].'  距离:'.$value['distance'].'公里','picurl'=>$value['img'],'url'=>'/');
        }

这里需要注意几个参数 $lat 经度 $lng 纬度   $distance 距离  HAVING  对由sum或其它集合函数运算结果的输出进行限制。

        // 回复图文消息
        $xml = $this->build_img_text_msg($to,$from,$shop_list);
        return $xml;

看看效果:

QQ图片20180608195957.png



Correction status:qualified

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post