欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PHP微信公众号——消息接受与推送

程序员文章站 2023-12-24 10:45:57
...

这里我们就来学习下怎么处理处理这些消息,以及推送消息。

学习之前首先你需要有一个域名和空间

PHP微信公众号——消息接受与推送

url:填写你希望微信公众平台把用户的消息转发到哪里

token:随便输入,用于微信公众平台和你的站点进行第一次通信建立关联用

PHP微信公众号——消息接受与推送

/*
    用于第一次验证我们网站url合法性
     */
    public function firstValid(){
        //检验签名的合法性
        if($this->_checkSignature()){
            //签名合法,告知微信公众平台服务器
            echo $_GET['echostr'];
        }
    }
/**
     * 验证签名
     * @return bool 
     */
    private function _checkSignature(){
        //获得由微信公众平台请求的验证数据
        $signature = $_GET['signature'];
        $timestamp = $_GET['timestamp'];
        $nonce = $_GET['nonce'];
        //将时间戳,随机字符串,token按照字母顺序排序,病并连接
        $tmp_arr = array($this->_token,$timestamp,$nonce);
        sort($tmp_arr,SORT_STRING);//字典顺序
        $tmp_str = implode($tmp_arr);//连接
        $tmp_str = sha1($tmp_str);//sha1加密
        if($signature==$tmp_str){
            return true;
        }else{
            return false;
        }
    

PHP微信公众号——消息接受与推送

在你的站点写一个脚本,调用一下firstValid 就可以完成微信公众平台和你站点的关联。$this->_token,就是你上面写token。

然后再提交,就能成功了。

1、关注后,欢迎语的设置

有人关注后,微信公众平台会给我们发一个xml格式的数据,如下:

 PHP微信公众号——消息接受与推送

然后我们对这个信息进行获取,转化成我们想要的格式,进行相关判断,返回数据,同样也需要组装成xml格式

PHP微信公众号——消息接受与推送

public function responseMsg(){
        /*
        获得请求时POST:XML字符串
        不能用$_POST获取,因为没有key
         */
        $xml_str = $GLOBALS['HTTP_RAW_POST_DATA'];
        if(empty($xml_str)){
            die('');
        }
        if(!empty($xml_str)){
            // 解析该xml字符串,利用simpleXML
            libxml_disable_entity_loader(true);
            //禁止xml实体解析,防止xml注入
              $request_xml = simplexml_load_string($xml_str, 'SimpleXMLElement', LIBXML_NOCDATA);
            //判断该消息的类型,通过元素MsgType
            switch ($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);
                      }else{

                      }
                    break;
                case 'text'://文本消息
                    $this->_doText($request_xml);
                    break;
                case 'image'://图片消息
                    $this->_doImage($request_xml);
                    break;
                case 'voice'://语音消息
                    $this->_doVoice($request_xml);
                    break;
                case 'video'://视频消息
                    $this->_doVideo($request_xml);
                    break;
                case 'shortvideo'://短视频消息
                    $this->_doShortvideo($request_xml);
                    break;
                case 'location'://位置消息
                    $this->_doLocation($request_xml);
                    break;
                case 'link'://链接消息
                    $this->_doLink($request_xml);
                    break;
            }        
        }        
    }

PHP微信公众号——消息接受与推送

我们可以给用户回复文字,图片,视频,音乐,新闻等等,首先定义好相应的回复模块

PHP微信公众号——消息接受与推送

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>',//某个新闻模板
    );

PHP微信公众号——消息接受与推送

%s就代表我们需要填的参数,后面用spritf统一传入

首先我们回复一句‘你好’;

PHP微信公众号——消息接受与推送

/**
     * 发送文本信息
     * @param  [type] $to      目标用户ID
     * @param  [type] $from    来源用户ID
     * @param  [type] $content 内容
     * @return [type]          [description]
     */
    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);
    }

PHP微信公众号——消息接受与推送

这样,用户一关注就会收到‘你好’。

2、发送图片

 

微信中的图片、语音、视频、缩略图统称素材,发送和接受都是以media_id进行的。

简单说:用给公众号一张图片,这张图片会上传到微信公众平台服务器,然后生成一个唯一的media_id,然后返回一个xml信息给我们,其中就有media_id。而我们要发给用户图片,也需要先把图片上传给公众平台,然后获取到media_id,根据这个media_id结合图片回复模板返回给平台

PHP微信公众号——消息接受与推送

<xml>
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName>
 <CreateTime>1348831860</CreateTime>
 <MsgType><![CDATA[image]]></MsgType>
 <PicUrl><![CDATA[this is a url]]></PicUrl>
 <MediaId><![CDATA[media_id]]></MediaId>
 <MsgId>1234567890123456</MsgId>
 </xml>

PHP微信公众号——消息接受与推送

* 上传临时素材(永久素材也可以):图片,语音,视频,缩略图
* 储存到微信公众平台服务器,3天
* 可通过上传后返回的media_id再次去取得该图片
自己定义上传函数

PHP微信公众号——消息接受与推送

public function uplodeTmp($file,$type){
        $url='https://api.weixin.qq.com/cgi-bin/media/upload?access_token='.$this->getAccessToken().'&type='.$type;
        $data = array(
            'media' => '@'.$file,
            );
        $result = $this->_request('post',$url,$data);
        $result_obj = json_decode($result);
        return $result_obj;
    }

PHP微信公众号——消息接受与推送

自己调用该函数上传站点图片,通过返回结果获得该图片media_id

发送给用户:

PHP微信公众号——消息接受与推送

//发送图片
    private function _msgImage($to,$from,$file,$is_id=false){
        //判断是不是media_id
        if($is_id){
            $media_id=$file;
        }else{
            // 上传图片到微信公众服务器,获取mediaID
            $result_obj = $this->uploadTmp($file, 'image');
            $media_id = $result_obj->media_id;
        }
            //拼凑xml图片发给微信平台,然后平台返回图片给用户
            $response = sprintf($this->_msg_template['image'],$to,$from,time(),$media_id);
            die($response);
    }

PHP微信公众号——消息接受与推送

这样用户就可以获得你的图片。

返回缩略图,语音、视频、短视频也是用同样的方法

如果我们希望用户发出‘图片’两个字时,返回给他一张图片,该怎么做?

PHP微信公众号——消息接受与推送

private function _doText($request_xml){
    //接受文本信息
    $content = $request_xml->Content;
    if('图片' == $content){
            $imgMediaId = 'UD-4n5YeK6NXhPCOYT_eV4YxYNZqCILemIZuZR3GYmj_AtrqhnHiIUUOQHSi71Ew';
            $this->_msgImage($request_xml->FromUserName, $request_xml->ToUserName,$imgMediaId,true);
        }

    }

PHP微信公众号——消息接受与推送

当然我们这里把图片写死了,实际可根据具体业务逻辑进行改变,改变media_id就行了。

3、发送音乐

如果用户输入音乐,我们发一首歌给他,音乐跟其他的几个素材不太一样

 

   private function _doText($request_xml){
          //接受文本信息
          $content = $request_xml->Content;
          
           if('音乐' == $content){
               $music_url='音乐网络地址链接';
              $ha_music_url='音乐网络地址链接';
             $thumb_media_id='一张图片的media_id';
              $title = '音乐名称';
              $desc = '音乐描述';
              $this->_msgMusic($request_xml->FromUserName, $request_xml->ToUserName, $music_url, $hq_music_url, $thumb_media_id, $title, $desc);
          }
  }
  //发送音乐
      private function _msgMusic($to, $from, $music_url, $hq_music_url, $thumb_media_id, $title='', $desc='') {
          $response = sprintf($this->_msg_template['music'], $to, $from, time(), $title, $desc, $music_url, $hq_music_url, $thumb_media_id);
          die($response);
      }

4、图灵机器人的接入

图灵官网注册申请appkey

 

 //图灵机器人接入         
          

            
 $content = $request_xml->Content;
$url = 'http://www.tuling123.com/openapi/api?key='.$this->_appkey.'&info='.$content.'&userid='.$request_xml->FromUserName;
            // $data['key'] = $this->_appkey;//
            // $data['info'] = $content;//用户输入的内容
            // $data['userid'] = $request_xml->FromUserName;
            $response_content = json_decode($this->_request('get',$url,array(),false));
            //$response_content->code决定返回的是什么
            //100000  文本 text
            //200000 链接  text+url
            //302000   新闻 text +list(新闻列表,里面有:article,source,icon,detailurl)分别是标题、来源、图片、详情地址
            //308000   菜谱  text+name+info+detailurl+icon
            $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $response_content->text);

可以自行根据图灵官网反回的code进行分类判断,字符组装,再回复给用户。

这样,你的公众号就变成了一个图灵机器人了。

5、发送图文(新闻)

我一般看到的微信公众号都是以图文信息进行推送消息,这个新闻类型怎么发送?

 

if('新闻' == $content){
            $item_list = array(
                array('title'=>'标题','desc'=>'描述','picurl'=>'图片地址','url'=>'该文章的地址'),
                array('title'=>'标题','desc'=>'描述','picurl'=>'图片地址','url'=>'该文章的地址')        
                );
            $this->_msgNews($request_xml->FromUserName,$request_xml->ToUserName,$item_list);
        }


//发送新闻
    private function _msgNews($to,$from,$item_list=array()){
        //拼凑文章部分
        $item_str = '';
        foreach ($item_list as $item) {
            $item_str .= sprintf($this->_msg_template['news_item'],$item['title'],$item['desc'],$item['picurl'],$item['url']);
        }
        //拼凑主体部分
        $response = sprintf($this->_msg_template['news'], $to, $from, time(), count($item_list), $item_str);
        die($response);
    }

6、菜单创建删除

一般公众号底部都有1-3个菜单选项,选项里可能还有子菜单,这个如何通过php代码进行创建?

菜单创建和删除都是针对所有的,不能单独操作某一个菜单

 

//菜单删除
    public function menuDelete(){
        $url ='https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=' . $this->getAccessToken();
        $result = $this->_request('get',$url);
        $result_obj = json_decode($result);
        if($result_obj->errcode == 0){
            return true;
        }else{
            return false;
        }
    }

删除很简单,调用这个函数就删除所有菜单了,不过已关注的用户需要24小时后才会生效。

 

//创建菜单
    public function menuSet($menu) {
        $url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=' . $this->getAccessToken();
        $data = $menu;
        $result_obj = json_decode($this->_request('post',$url, $data));
        if ($result_obj->errcode == 0) {
            return true;
        } else {
            echo $result_obj->errmsg, '<br>';
            return false;
        }
    }

创建菜单需要我们传一个json格式参数,同一样已关注的用户也会24小时后生效

1、自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。
2、一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。
各参数的类型,以及作用,请到开发者文档查看:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013

json数据格式如下:创建了3个主菜单,以及对应的子菜单。

 

$menu = <<<JSON
{
    "button": [
        {
            "name": "扫码",
            "sub_button": [
                {
                    "type": "scancode_waitmsg",
                    "name": "扫码带提示",
                    "key": "scancode_waitmsg",
                    "sub_button": [ ]
                },
                {
                    "type": "scancode_push",
                    "name": "扫码推事件",
                    "key": "scancode_push",
                    "sub_button": [ ]
                }
            ]
        },
        {
            "name": "发图",
            "sub_button": [
                {
                    "type": "pic_sysphoto",
                    "name": "系统拍照发图",
                    "key": "pic_sysphoto",
                   "sub_button": [ ]
                 },
                {
                    "type": "pic_photo_or_album",
                    "name": "拍照或者相册发图",
                    "key": "pic_photo_or_album",
                    "sub_button": [ ]
                },
                {
                    "type": "pic_weixin",
                    "name": "微信相册发图",
                    "key": "pic_weixin",
                    "sub_button": [ ]
                }
            ]
        },
        {
            "name": "快捷操作",
            "sub_button" : [
                {
                    "name": "地理位置",
                    "type": "location_select",
                    "key": "location_select"
                },
                {
                    "name": "普通点击",
                    "type": "click",
                    "key": "click"
                },
                {
                    "name": "查看URL",
                    "type": "view",
                    "url" : "http://www.soso.com/"
                },
            ]
        },
    ]
}
JSON;

源码下载:https://github.com/Ivanlovening/wechat
相关标签: 微信公众号

上一篇:

下一篇: