MingGyGy-Castle

使用客服消息实现发送多条图文消息

第一步、首先找到微擎关键字触发发送消息的PHP文件在framework->builtin->core->processor.php文件里面

二、修改respond方法

1 public function respond() {
2         $result = $this->msg_respond();
3         return $this->respText($result);
4 }

三、写入我们自己实现发送图文的方法

msg_respond()方法

 1 private function msg_respond() {
 2         $rids = !is_array($this->rule) ? explode(\',\', $this->rule) : $this->rule;
 3         //数据库中获取发送文字的信息
 4         $reply = table(\'basic_reply\')->where(array(\'rid IN\' => $rids))->orderby(\'id\')->getAll();
 5         //图片
 6         $img_reply = table(\'images_reply\')->where(array(\'rid IN\' => $rids))->orderby(\'id\')->getAll();
 7         //图文
 8         //$news_reply = table(\'news_reply\')->where(array(\'rid IN\' => $rids,\'parent_id ==\' => -1))->orderby(\'id\')->getAll();
 9         $news_reply = table(\'news_reply\')->where(array(\'rid IN\' => $rids))->orderby(\'id\')->getAll();
10         //音乐
11         $music_reply = table(\'music_reply\')->where(array(\'rid IN\' => $rids))->orderby(\'id\')->getAll();
12         //语音
13         $voice_reply = table(\'voice_reply\')->where(array(\'rid IN\' => $rids))->orderby(\'id\')->getAll();
14         //视频
15         $video_reply = table(\'video_reply\')->where(array(\'rid IN\' => $rids))->orderby(\'id\')->getAll();
16 //父级找子级
17         /*foreach ($news_reply as &$value){
18             //if ($value[\'parent\'] != -1) {
19                 $value[\'parent_data\'] = table(\'news_reply\')->where([\'parent_id\' => $value[\'id\']])->orderby(\'id\')->getAll();
20             //}
21         }*/
22 
23         //判断是否为空,如果都为空返回false
24         if (empty($reply)&&empty($img_reply)&&empty($news_reply)&&empty($music_reply)&&empty($voice_reply)&&empty($video_reply)) {
25             return false;
26         }
27         $access_token=$this->getToken();
28         $postStr=file_get_contents(\'php://input\');
29         $postObj = simplexml_load_string($postStr, \'SimpleXMLElement\', LIBXML_NOCDATA);
30         if (count($reply)+count($img_reply)+count($news_reply)+count($music_reply)+count($voice_reply)+count($video_reply)==1){
31             if($reply!=null){
32                 $reply[0][\'content\'] = htmlspecialchars_decode($reply[0][\'content\']);
33                 $reply[0][\'content\'] = str_replace(array(\'<br>\', \'&nbsp;\'), array("\n", \' \'), $reply[0][\'content\']);
34                 $reply[0][\'content\'] = strip_tags($reply[0][\'content\'], \'<a>\');
35                 return $reply[0][\'content\'];
36             }elseif ($img_reply!=null){
37                 for ($y=0;$y<count($img_reply);$y++){
38                     $this->imageReply($postObj->FromUserName,$access_token,$img_reply[$y][\'mediaid\']);
39                 }
40             }elseif ($news_reply!=null){
41                 //$this->judgeType(\'news\');
42                 for ($j=0;$j<count($news_reply);$j++){
43 
44                     //$this->newsReply($postObj->FromUserName,$access_token,$news_reply[$j][\'url\'],$news_reply[$j][\'thumb\'],$news_reply[$j][\'title\'],$news_reply[$j][\'description\'],$news_reply[$j][\'parent_data\']);
45                     $this->newsReply($postObj->FromUserName,$access_token,$news_reply[$j][\'url\'],$news_reply[$j][\'thumb\'],$news_reply[$j][\'title\'],$news_reply[$j][\'description\'],$news_reply[$j][\'media_id\']);
46                 }
47             }elseif ($music_reply!=null){
48                 $result = $this->music_respond();
49                 return $this->respMusic(array(
50                     \'Title\' => $result[\'title\'],
51                     \'Description\' => $result[\'description\'],
52                     \'MusicUrl\' => $result[\'url\'],
53                     \'HQMusicUrl\' => $result[\'hqurl\'],
54                 ));
55             }elseif ($voice_reply!=null){
56                 for ($s=0;$s<count($voice_reply);$s++){
57                     $this->voiceReply($postObj->FromUserName,$access_token,$voice_reply[$s][\'mediaid\']);
58                 }
59             }elseif ($video_reply!=null){
60                 for ($d=0;$d<count($video_reply);$d++){
61                     $this->videoReply($postObj->FromUserName,$access_token,$video_reply[$d][\'mediaid\'],$video_reply[$d][\'title\'],$video_reply[$d][\'description\']);
62                 }
63             }else{
64                 return "数据错误!!!";
65             }
66         }else{
67             //循环发送图片
68             for ($y=0;$y<count($img_reply);$y++){
69                 $this->imageReply($postObj->FromUserName,$access_token,$img_reply[$y][\'mediaid\']);
70             }
71             //循环发送图文
72             for ($j=0;$j<count($news_reply);$j++){
73                 $this->newsReply($postObj->FromUserName,$access_token,$news_reply[$j][\'url\'],$news_reply[$j][\'thumb\'],$news_reply[$j][\'title\'],$news_reply[$j][\'description\'],$news_reply[$j][\'media_id\']);
74             }
75             //视频
76             for ($d=0;$d<count($video_reply);$d++){
77                 $this->videoReply($postObj->FromUserName,$access_token,$video_reply[$d][\'mediaid\'],$video_reply[$d][\'title\'],$video_reply[$d][\'description\']);
78             }
79             //语音
80             for ($s=0;$s<count($voice_reply);$s++){
81                 $this->voiceReply($postObj->FromUserName,$access_token,$voice_reply[$s][\'mediaid\']);
82             }
83             //循环发送文字
84             for($i=0;$i<count($reply);$i++){
85                 if($i==count($reply)-1){
86                     return $reply[$i][\'content\'];
87                 }else{
88                     $this->replymsg($postObj->FromUserName,$access_token,trim($reply[$i][\'content\']));
89                 }
90             }
91         }
92         return 0;
93     }

四、获取access token信息

我们自己写一个getToken()方法,需要修改$appid和$secret参数,修改为你自己公众号上的appid和secret

 1 private    function getToken(){
 2         $appid = "你自己的appid";
 3         $secret = "你自己的secret";
 4         $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret;
 5         $ch = curl_init();//初始化
 6         curl_setopt($ch, CURLOPT_URL, $url);//与url建立对话
 7         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); //进行配置
 8         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //进行配置
 9         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//进行配置
10         $output = curl_exec($ch);//获取Access Token
11         curl_close($ch);//关闭会话
12         $jsoninfo = json_decode($output, true);
13         $access_token =$jsoninfo["access_token"];
14         echo $access_token;
15         return $access_token;
16     }

五、写发送的方法

  1 //发送文字的方法
  2     private function replymsg($fromUsername,$access_token,$content){
  3 
  4         $data = \'{
  5             "touser":"\'.$fromUsername.\'",
  6             "msgtype":"text",
  7             "text":
  8             {
  9                  "content":"\'.$content.\'"
 10             }
 11         }\';
 12 
 13         $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$access_token;
 14         //$this->https_post($url,$data);
 15         $result = $this->https_post($url,$data);
 16         $final = json_decode($result);
 17         return $final;
 18     }
 19     //发送图片的方法
 20     private function imageReply($fromUsername,$access_token,$mediaId){
 21         $data=\'{
 22             "touser":"\'.$fromUsername.\'",
 23             "msgtype":"image",
 24             "image":
 25                 {
 26                     "media_id":"\'.$mediaId.\'"
 27                 }
 28         }\';
 29         $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$access_token;
 30         //$this->https_post($url,$data);
 31         $result = $this->https_post($url,$data);
 32         $final = json_decode($result);
 33         return $final;
 34     }
 35     //发送图文的方法
 36     private function newsReply($fromUsername,$access_token,$url,$picUrl,$title,$description,$mediaid){
 37         $data = \'{
 38             "touser":"\'.$fromUsername.\'",
 39             "msgtype":"mpnews",
 40             "mpnews":{
 41                 "media_id":"\'.$mediaid.\'"
 42             }
 43         }\';
 44         $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$access_token;
 45         //$this->https_post($url,$data);
 46         $result = $this->https_post($url,$data);
 47         $final = json_decode($result);
 48         return $final;
 49     }
 50     //发送音乐的方法
 51     private function musicReply($fromUsername,$access_token,$title,$description,$url,$hqurl){
 52         $data = \'{
 53             "touser":"\'.$fromUsername.\'",
 54             "msgtype":"music",
 55             "music":
 56              {
 57                 "title":"\'.$title.\'",
 58                 "description":"\'.$description.\'",
 59                 "musicurl":"\'.$url.\'",
 60                 "hqmusicurl":"\'.$hqurl.\'"
 61              }
 62         }\';
 63         $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$access_token;
 64         //$this->https_post($url,$data);
 65         $result = $this->https_post($url,$data);
 66         $final = json_decode($result);
 67         return $final;
 68     }
 69     //语音
 70     private function voiceReply($fromUsername,$access_token,$mediaid){
 71         $data=\'
 72             {
 73     "touser":"\'.$fromUsername.\'",
 74     "msgtype":"voice",
 75     "voice":
 76     {
 77       "media_id":"\'.$mediaid.\'"
 78     }
 79 }
 80         \';
 81         $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$access_token;
 82         //$this->https_post($url,$data);
 83         $result = $this->https_post($url,$data);
 84         $final = json_decode($result);
 85         return $final;
 86     }
 87     //视频
 88     private function videoReply($fromUsername,$access_token,$mediaid,$title,$description){
 89         $data = \'
 90             {
 91     "touser":"\'.$fromUsername.\'",
 92     "msgtype":"video",
 93     "video":
 94     {
 95       "media_id":"\'.$mediaid.\'",
 96       "title":"\'.$title.\'",
 97       "description":"\'.$description.\'"
 98     }
 99 }
100         \';
101         $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$access_token;
102         //$this->https_post($url,$data);
103         $result = $this->https_post($url,$data);
104         $final = json_decode($result);
105         return $final;
106     }

六、https_post方法

 1 private function https_post($url,$data)
 2     {
 3         $curl = curl_init();
 4         curl_setopt($curl, CURLOPT_URL, $url);
 5         curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
 6         curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
 7         curl_setopt($curl, CURLOPT_POST, 1);
 8         curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
 9         curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
10         $result = curl_exec($curl);
11         if (curl_errno($curl)) {
12             return \'Errno\'.curl_error($curl);
13         }
14         curl_close($curl);
15         return $result;
16     }

7、展示一下效果吧

八、觉得本文章对你有帮助的麻烦动下手指点个赞呗

 

2020-10-29:附上优化后的全部代码。

<?php
/**
 * [WeEngine System] Copyright (c) 2014 WE7.CC
 * WeEngine is NOT a free software, it under the license terms, visited http://www.we7.cc/ for more details.
 */
defined(\'IN_IA\') or exit(\'Access Denied\');

class CoreModuleProcessor extends WeModuleProcessor {

    private $data = [];               //用于存入数据库获取的数据
    private $newsAll=[];              //用于存入图文数据

    public function weixinAccount()
    {
        static $weixinAccount;
        if(empty($weixinAccount))$weixinAccount = WeAccount::create($this->uniacid);
        return $weixinAccount;
    }

    public function respond() {
        $this->type_sort();               //  给$this->reply_type排序,把值为news的放在数组最后
        $this->getReplyData();            //  获取数据库中的数据
        if(count($this->data)==1){
            return $this->oldRespond();   //按原来的方式处理
        }else{
            return $this->msg_respond();  //多条数据处理方法
        }
    }

    public function oldRespond() {
        $reply_type = $this->reply_type;
        $key = array_rand($reply_type);
        $type = $reply_type[$key];
        switch($type) {
            case \'basic\':
                $result = $this->basic_respond();
                return $this->respText($result);
                break;
            case \'images\':
                $result = $this->image_respond();
                return $this->respImage($result);
                break;
            case \'music\':
                $result = $this->music_respond();
                return $this->respMusic(array(
                        \'Title\'    => $result[\'title\'],
                        \'Description\' => $result[\'description\'],
                        \'MusicUrl\' => $result[\'url\'],
                        \'HQMusicUrl\' => $result[\'hqurl\'],
                    ));
                break;
            case \'news\':
                $result = $this->news_respond();
                return $this->respNews($result);
                break;
            case \'voice\':
                $result = $this->voice_respond();
                return $this->respVoice($result);
                break;
            case \'video\':
                $result = $this->video_respond();
                return $this->respVideo(array(
                        \'MediaId\' => $result[\'mediaid\'],
                        \'Title\' => $result[\'title\'],
                        \'Description\' => $result[\'description\']
                    ));
                break;
        }
    }

    private function basic_respond() {
        $sql = "SELECT * FROM " . tablename(\'basic_reply\') . " WHERE `rid` IN ({$this->rule})  ORDER BY RAND() LIMIT 1";
        $reply = pdo_fetch($sql);
        if (empty($reply)) {
            return false;
        }
        $reply[\'content\'] = htmlspecialchars_decode($reply[\'content\']);
                $reply[\'content\'] = str_replace(array(\'<br>\', \'&nbsp;\'), array("\n", \' \'), $reply[\'content\']);
        $reply[\'content\'] = strip_tags($reply[\'content\'], \'<a>\');
        return $reply[\'content\'];
    }

    private function image_respond() {
        global $_W;
        $rid = $this->rule;
        $sql = "SELECT `mediaid` FROM " . tablename(\'images_reply\') . " WHERE `rid`=:rid ORDER BY RAND()";
        $mediaid = pdo_fetchcolumn($sql, array(\':rid\' => $rid));
        if (empty($mediaid)) {
            return false;
        }
        return $mediaid;
    }

    private function music_respond() {
        global $_W;
        $rid = $this->rule;
        $sql = "SELECT * FROM " . tablename(\'music_reply\') . " WHERE `rid`=:rid ORDER BY RAND()";
        $item = pdo_fetch($sql, array(\':rid\' => $rid));
        if (empty($item[\'id\'])) {
            return false;
        }
        return $item;
    }

    private function news_respond() {
        global $_W;
        load()->model(\'material\');
        $rid = $this->rule;
        $sql = "SELECT * FROM " . tablename(\'news_reply\') . " WHERE rid = :id AND parent_id = -1 ORDER BY displayorder DESC, id ASC LIMIT 8";
        $commends = pdo_fetchall($sql, array(\':id\' => $rid));
        if (empty($commends)) {
                        $sql = "SELECT * FROM " . tablename(\'news_reply\') . " WHERE rid = :id AND parent_id = 0 ORDER BY RAND()";
            $main = pdo_fetch($sql, array(\':id\' => $rid));
            if(empty($main[\'id\'])) {
                return false;
            }
            $sql = "SELECT * FROM " . tablename(\'news_reply\') . " WHERE id = :id OR parent_id = :parent_id ORDER BY displayorder ASC, id ASC LIMIT 8";
            $commends = pdo_fetchall($sql, array(\':id\'=>$main[\'id\'], \':parent_id\'=>$main[\'id\']));
        }
        if(empty($commends)) {
            return false;
        }
        $news = array();
        if (!empty($commends[0][\'media_id\'])) {
            $news = material_build_reply($commends[0][\'media_id\']);
        }
        foreach($commends as $key => $commend) {
            $row = array();
            if (!empty($commend[\'media_id\'])) {
                if (empty($news[$key][\'url\'])) {
                    $news[$key][\'url\'] = $this->createMobileUrl(\'detail\', array(\'id\' => $commend[\'id\']));
                }
            } else {
                $row[\'title\'] = $commend[\'title\'];
                $row[\'description\'] = $commend[\'description\'];
                !empty($commend[\'thumb\']) && $row[\'picurl\'] = tomedia($commend[\'thumb\']);
                $row[\'url\'] = empty($commend[\'url\']) ? $this->createMobileUrl(\'detail\', array(\'id\' => $commend[\'id\'])) : $commend[\'url\'];
                $news[] = $row;
            }
        }
        return $news;
    }

    private function voice_respond() {
        global $_W;
        $rid = $this->rule;
        $sql = "SELECT `mediaid` FROM " . tablename(\'voice_reply\') . " WHERE `rid`=:rid ORDER BY RAND()";
        $mediaid = pdo_fetchcolumn($sql, array(\':rid\' => $rid));
        if (empty($mediaid)) {
            return false;
        }
        return $mediaid;
    }

    private function video_respond() {
        global $_W;
        $rid = $this->rule;
        $sql = "SELECT * FROM " . tablename(\'video_reply\') . " WHERE `rid`=:rid ORDER BY RAND()";
        $item = pdo_fetch($sql, array(\':rid\' => $rid));
        if (empty($item)) {
            return false;
        }
        return $item;
    }


    /***************************************************微擎二次开发代码************************************************************/

    /**
     * 多条消息发送方法
     * @return int
     */
    private function msg_respond() {
        $data = $this->data;
        if (empty($data)) return false;
        $open_id = $this->message[\'fromusername\'];       //获取openid
        foreach ($this->reply_type as $type){
            if ($type == "news") {
                for ($j = 0; $j < count($data); $j++) {
                    $this->newsAll = $this->data[\'news\'];  //直接从数据中获取
                }
                //对id字段进行排序
                $this->newsAll = iarray_sort($this->newsAll, \'id\');
                if ($this->newsAll) {//发送
                    //组成xml
                    $newsXml = "<xml>
                          <ToUserName><![CDATA[{$open_id}]]></ToUserName>
                          <FromUserName><![CDATA[{$this->message[\'tousername\']}]]></FromUserName>
                          <CreateTime>" . time() . "</CreateTime>
                          <MsgType><![CDATA[news]]></MsgType>
                          <ArticleCount>" . count($this->newsAll) . "</ArticleCount>
                          <Articles>";
                    foreach ($this->newsAll as $value) {
                        $newsXml .= "<item>
                              <Title><![CDATA[{$value[\'title\']}]]></Title>
                              <Description><![CDATA[{$value[\'description\']}]]></Description>
                              <PicUrl><![CDATA[{$value[\'thumb\']}]]></PicUrl>
                              <Url><![CDATA[{$value[\'url\']}]]></Url>
                            </item>";
                    }
                    unset($this->newsAll);
                    $newsXml .= "</Articles>
                        </xml>";
//                    exit($newsXml);
                    /*加密*/
                    $encryptMsg = $this->weixinAccount()->encryptMsg($newsXml);
                    $encryptMsg = $this->weixinAccount()->xmlDetract($encryptMsg);
                    exit($encryptMsg);
                }
            }else{
                $this->Reply($type,$data[$type]);
            }
        }
        return 0;
    }

    /**
     * 获取数据库中的数据,并存入data中
     */
    private function getReplyData(){
        foreach ($this->reply_type as $value) {
            $table_name = $value . "_reply";
            $sql = "SELECT * FROM " . tablename($table_name) . " WHERE `rid` IN ({$this->rule})";
            $this->data[$value] = pdo_fetchall($sql);
        }
        unset($sql);
    }

    /**
     * 功能:微信公众号构造消息发送数据方法
     * 开发者:MingGyGy
     * 时间:2020年1月3日
     * @param $type string
     * @param $param array
     * @return array
     */
    private function typeToData($type,$param){
        $data = [
            "touser"=>$this->message[\'from\'],
        ];
        switch($type) {
            case \'basic\':
                $data["msgtype"] = \'text\';
                $data[\'text\'] = [
                    \'content\'=>urlencode($param[\'content\'])
                ];
                break;
            case \'news\':
                $data["msgtype"] = \'link\';
                $data["mpnews"] = [
                    \'title\'=>$param[\'title\'],
                    \'description\' => $param[\'description\'],
                    \'url\' => $param[\'url\'],
                    \'thumb\' => $param[\'thumb\']
                ];
                break;
            case \'images\':
                $data["msgtype"] = \'image\';
                $data["image"] = [
                    \'media_id\'=>$param[\'media_id\']
                ];
                break;
            case \'music\':
                $data["msgtype"] = \'music\';
                $data["music"] = [
                    \'title\'=>$param[\'title\'],
                    \'description\'=>$param[\'description\'],
                    \'musicurl\'=>$param[\'musicurl\'],
                    \'hqmusicurl\'=>$param[\'hqmusicurl\']
                ];
                break;
            case \'voice\':
                $data["msgtype"] = \'voice\';
                $data = ["voice"=>[
                    \'media_id\'=>$param[\'media_id\']
                ]];
                break;
            case \'video\':
                $data["msgtype"] = \'video\';
                $data["video"] = [
                    \'media_id\'=>$param[\'media_id\'],
                    \'title\'=>$param[\'title\'],
                    \'description\'=>$param[\'description\']
                ];
                break;
        }
        return $data;
    }

    /**
     * 功能:封装发送方法
     * 开发者:MingGyGy
     * 时间:2020年1月3日
     * @param $type
     */
    private function Reply($type,$datas)
    {
        foreach($datas as $value) {
            $param = [];
            switch ($type) {
                case \'basic\':
                    $param["content"] = $value["content"];
                    break;
                case \'images\':
                case \'voice\':
                $param[\'media_id\'] = $value["mediaid"];
                break;
                case \'video\':
                    $param[\'media_id\'] = $value["media_id"];
                    $param[\'title\'] = $value[\'title\'];
                    $param[\'description\'] = $value[\'description\'];
                    break;
                case \'news\':
                    $param[\'title\'] = $value[\'title\'];
                    $param[\'description\'] = $value[\'description\'];
                    $param[\'url\'] = $value[\'url\'];
                    $param[\'thumb\'] = $value[\'thumb\'];
            }
            $data = $this->typeToData($type, $param);
            $this->weixinAccount()->sendCustomNotice($data);
        }
    }

    /**
     * 功能:对$this->reply_type进行排序,把值为news放数组最后
     * 开发者:MingGyGy
     * 时间:2020年1月3日
     */
    private function type_sort()
    {
        if(in_array(\'news\',$this->reply_type)){
            $key = array_search(\'news\',$this->reply_type);
            unset($this->reply_type[$key]);
            $this->reply_type[] = \'news\';
        }
    }
}

 

分类:

技术点:

相关文章: