微信多图文群发接口调用(含预览接口)

前瞻

之前写了个通用的微信管理,领导说实用性太差,要加上群发管理,哎真是站着说话不腰疼,难为人,没办法,自己是打工的,干吧;不过个人觉得还是直接上微信后台方便的多。先看下我的目录


框架:tp3.2

思路

我这里是模拟的微信后台添加的方式,首先有个群发主题(一个栏目),然后在群发内容里在对应主题添加内容,一个主题可以对应着多个内容(多图文)。可以看下我的页面:



我的群发内容页面:



数据库字段:
  • 群发主题


  • 群发内容


实现群发功能需要以下几步:

  1. 上传群发内容的标题图到微信服务器,拿到media_id(即thumb_media_id),这是上传主题素材用的;调用接口地址http://mp.weixin.qq.com/wiki/10/78b15308b053286e2a66b33f0f0f5fb6.html (我也不知道微信公众平台有几个开发文档,我看到了3个不同版本,这个是我点击客户接口进去的)
  2. 上传群发内容编辑器所编辑内容所有图片,拿到对应服务器的url并替换;这个也是必须的,否则,微信不会显示图片;调用地址:http://mp.weixin.qq.com/wiki/14/0c53fac3bdec3906aaa36987b91d64ea.html
  3. 上传主题素材,拿到media_id,用于群发,这个和上面2的地址一样
  4. 利用素材的media_id,上传或者预览,地址也是2

代码:(因为我的是测试号,没权限好像是,但是我的预览接口成功了,预览和素材只是最后一步不一样)

namespace Admin\Controller;

class massController extends AuthController{

    protected $MassObj;
    protected $MassReturnObj;
    protected $conf;

    public function __construct(){
        parent::__construct();
        $this->MassObj = D('Mass');//主题表
        $this->MassReturnObj = D('MassReturn');//主题内容表
    }
/**
     * [delmass 发送群发主题]
     * @return [JSON] [返回成功与失败]
     */
    public function sendmass(){
      //这里我是异步post请求的,可以是get,看个人
        if( !empty( $_POST ) ){
            $id = I('post.id');
            $data = $this->MassReturnObj->order('mass_order')->where(array('mass_id'=>$id))->select();//拿到主题内容数据
            $access_token = $this->getWxAccessToken();//下面有函数
            //循环遍历每个图文
            foreach( $data as $k=>$v){
                //调用基础支持的上传多媒体文件,上传标题图
                $url="http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={$access_token}&type=image";
                $arr = array('media'=>'@'.$_SERVER['DOCUMENT_ROOT'].$v['pic_url'],'form-data'=>$v['pic_url']);
                $res = $this->http_curl($url,'post','',$arr);
                if( !$res ){
                    $this->ajaxReturn( array( 'code'=>1,'msg'=>'id为'.$v['id'].'的数据标题图图片上传失败!' ) );
                } 
                $v['media_id'] = $res['media_id'];//标题图的thumb_media_id
                $v['wxpic'] = $res['url'];
                $content = $v['content'];
                preg_match_all('/<img.*?src="(.*?)".*?>/is',$content,$arr);//提取编辑内容的所有img的src
                $url = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={$access_token}&type=image";
                //将内容里面的所有img图片上传到微信服务器,并替换新的图片地址
                foreach( $arr[1] as $k1=>$vo ){
                    $arr = array('media'=>'@'.$_SERVER['DOCUMENT_ROOT'].$vo,'form-data'=>$vo);
                    //调用图片上传到微信服务器接口
                    $res = $this->http_curl($url,'post','',$arr);
                    if( !$res['url'] ){
                        $this->ajaxReturn( array( 'code'=>1,'msg'=>'id为'.$v['id'].'的消息内容页面的第'.($k1+1).'张图片上传失败!' ) );
                    }
                    $content = str_replace($vo,$res['url'],$content);//替换新的图片地址
                }
                //拼接主题素材数组,这块汉字需要用urlencode转一下,转成json再用urldecode转回,否则消息页面是乱码
                $postArr['articles'][] = array(
                    "thumb_media_id"=>$v['media_id'],
                    "author"=>urlencode($v['author']),
                    "title"=>urlencode($v['title']),
                    "content_source_url"=>urlencode($v['url']),
                    "content"=>urlencode(htmlspecialchars(str_replace("\"","'",$content))),//需要str_replace将上引号换成单引号
                    "digest"=>urlencode($v['description']),
                    "show_cover_pic"=>"0"
                );
            }
            //将数组转为json
            $postArr = htmlspecialchars_decode(urldecode(json_encode($postArr)));
            //调用上传素材接口
            $url = 'https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token='.$access_token;
            //上传整个素材post
            $res = $this->http_curl($url,'post','json',$postArr);
            $media_id = $res['media_id'];//群发素材的media_id
            $url= "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=".$access_token;
            $postArr = array(
                "filter"=>[
                    "is_to_all"=>true,
                ],
                "mpnews"=>[
                    "media_id"=>$media_id
                ],
                "msgtype"=>"mpnews"
            );
            $postArr = json_encode( $postArr );
            $res = $this->http_curl($url,'post','json',$postArr);
            if( $res['errcode']==0 && $res['msg_data_id'] ){
                $this->MassObj->setField('put_time',time());
                $this->ajaxReturn( array( 'code'=>0,'msg'=>'发送成功!' ) );
            }else{
                $this->ajaxReturn( array( 'code'=>1,'msg'=>$res['errcode'].':'.$res['errmsg'] ) );
            }
        }else{
            $this->ajaxReturn( array( 'code'=>1,'msg'=>'无效操作' ) );
        }
    }
}

预览接口

public function send(){
        //Gl8DWQUSQHXlB7IBKXcyqF79PSS9Mm_rTvwJsIHx_rPs3oMgWR8tB6l5Z4CNStXo
        if( !empty( $_POST ) ){
            $id = I('post.id');
            $data = $this->MassReturnObj->order('mass_order')->where(array('mass_id'=>$id))->select();
            $access_token = $this->getWxAccessToken();
            foreach( $data as $k=>$v){
                //调用基础支持的上传多媒体文件
                $url="http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={$access_token}&type=image";
                $arr = array('media'=>'@'.$_SERVER['DOCUMENT_ROOT'].$v['pic_url'],'form-data'=>$v['pic_url']);
                $res = $this->http_curl($url,'post','',$arr);
                if( !$res ){
                    $this->ajaxReturn( array( 'code'=>1,'msg'=>'id为'.$v['id'].'的数据标题图图片上传失败!' ) );
                }
                echo "1111<br />";var_dump($res);echo "<br />";
                $v['media_id'] = $res['media_id'];//标题图的thumb_media_id
                $v['wxpic'] = $res['url'];
                $content = $v['content'];
                preg_match_all('/<img.*?src="(.*?)".*?>/is',$content,$arr);//提取所有img的src
                $url = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={$access_token}&type=image";
                //将内容里面的所有img图片上传到微信服务器,并替换新的图片地址
                foreach( $arr[1] as $k1=>$vo ){
                    $arr = array('media'=>'@'.$_SERVER['DOCUMENT_ROOT'].$vo,'form-data'=>$vo);
                    //调用图片上传到微信服务器接口
                    $res = $this->http_curl($url,'post','',$arr);
                    if( !$res['url'] ){
                        $this->ajaxReturn( array( 'code'=>1,'msg'=>'id为'.$v['id'].'的消息内容页面的第'.($k1+1).'张图片上传失败!' ) );
                    }
                    $content = str_replace($vo,$res['url'],$content);
                }
                //拼接数组
                $postArr['articles'][] = array(
                    "thumb_media_id"=>$v['media_id'],
                    "author"=>urlencode($v['author']),
                    "title"=>urlencode($v['title']),
                    "content_source_url"=>urlencode($v['url']),
                    "content"=>urlencode(htmlspecialchars(str_replace("\"","'",$content))),
                    "digest"=>urlencode($v['description']),
                    "show_cover_pic"=>"0"
                );
            }
            //将数组转为json
            $postArr = htmlspecialchars_decode(urldecode(json_encode($postArr)));
            //调用上传素材接口
            $url = 'https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token='.$access_token;
            //上传整个素材post
            $res = $this->http_curl($url,'post','json',$postArr);
            echo "1111<br />";var_dump($res);echo "<br />";
            $media_id = $res['media_id'];//群发素材的media_id
            $url= "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=".$access_token;
            $postArr = array(
                "touser"=>"oV3xFwbYr3X4sYFepGUgDNgn6cGg",
                "mpnews"=>[
                    "media_id"=>$media_id
                ],
                "msgtype"=>"mpnews"
            );
            $postArr = json_encode( $postArr );
            $res = $this->http_curl($url,'post','json',$postArr);
            echo "1111<br />";var_dump($res);
            if( $res['errcode']==0 && $res['errmsg'] ){
//                $this->MassObj->setField('is_send',1);
                $this->ajaxReturn( array( 'code'=>0,'msg'=>'发送成功!' ) );
            }else{
                $this->ajaxReturn( array( 'code'=>1,'msg'=>$res['errcode'].':'.$res['errmsg'] ) );
            }
        }else{
            $this->ajaxReturn( array( 'code'=>1,'msg'=>'无效操作' ) );
        }
    }

可以将上面的echo去掉,不去的话可以看返回值,调试用
用到的函数

/**
     *
     *获取全局access_token
     * @return $access_token string
     */
    function getWxAccessToken(){
        //将access_token存在session中
        if( $_SESSION['access_token'] && $_SESSION['expire_time']>time() ){
            return $_SESSION['access_token'];
        }else{
            $this->conf = M('Wechat')->find(1);
            //如果access_token不存在或者过期,重新获取
            $appid = $this->conf['appid'];//公众号的appid
            $appsecret =  $this->conf['appsecret'];//公众号的appsecret 
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$appsecret;
            $res = $this->http_curl($url);
            $access_token = $res['access_token'];
            //将获取到的access_token存到session
            $_SESSION['access_token'] = $access_token;
            $_SESSION['expire_time'] = time()+7000;//access_token过期时间为2小时,所以把session过期时间也修改过来
            return $access_token;
        }
    }
    /**
     *
     *$url 接口url string
     *$type 请求类型 string
     *$res 返回数据类型 string
     *$arr post请求参数 array
     *
     */
    public function http_curl($url,$type='get',$res='json',$arr=''){
        //1.初始化curl
        $ch = curl_init();
        //2.设置curl的参数
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        if($type == 'post'){
            curl_setopt($ch,CURLOPT_POST,1);
            curl_setopt($ch,CURLOPT_POSTFIELDS,$arr);
        }
        //3.采集
        $output = curl_exec($ch);
        //4.关闭
        curl_close($ch);
        if($res == 'json'){
            if( curl_error($ch) ){
                return curl_error($ch);//请求失败返回错误信息
            }else{
                return json_decode($output,true);//请求成功返回json
            }
        }else{
            if( curl_error($ch) ){
                return curl_error($ch);//请求失败返回错误信息
            }else{
                return json_decode($output,true);//请求成功返回json
            }
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容