上一篇文章咱们知道怎么获取二维码,这样别人就能够扫描二维码来关注咱们,可是别人关注后,发送消息,咱们怎么进行相关处理?php
这里咱们就来学习下怎么处理处理这些消息,以及推送消息。git
学习以前首先你须要有一个域名和空间github
url:填写你但愿微信公众平台把用户的消息转发到哪里json
token:随便输入,用于微信公众平台和你的站点进行第一次通讯创建关联用api
/* 用于第一次验证咱们网站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; }
在你的站点写一个脚本,调用一下firstValid 就能够完成微信公众平台和你站点的关联。$this->_token,就是你上面写token。服务器
而后再提交,就能成功了。微信
一、关注后,欢迎语的设置网络
有人关注后,微信公众平台会给咱们发一个xml格式的数据,以下:app
而后咱们对这个信息进行获取,转化成咱们想要的格式,进行相关判断,返回数据,一样也须要组装成xml格式微信公众平台
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; } } }
咱们能够给用户回复文字,图片,视频,音乐,新闻等等,首先定义好相应的回复模块
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>',//某个新闻模板 );
%s就表明咱们须要填的参数,后面用spritf统一传入
首先咱们回复一句‘你好’;
/** * 发送文本信息 * @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); }
这样,用户一关注就会收到‘你好’。
二、发送图片
微信中的图片、语音、视频、缩略图统称素材,发送和接受都是以media_id进行的。
简单说:用给公众号一张图片,这张图片会上传到微信公众平台服务器,而后生成一个惟一的media_id,而后返回一个xml信息给咱们,其中就有media_id。而咱们要发给用户图片,也须要先把图片上传给公众平台,而后获取到media_id,根据这个media_id结合图片回复模板返回给平台
<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>
* 上传临时素材(永久素材也能够):图片,语音,视频,缩略图
* 储存到微信公众平台服务器,3天
* 可经过上传后返回的media_id再次去取得该图片
本身定义上传函数
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; }
本身调用该函数上传站点图片,经过返回结果得到该图片media_id
发送给用户:
//发送图片 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); }
这样用户就能够得到你的图片。
返回缩略图,语音、视频、短视频也是用一样的方法
若是咱们但愿用户发出‘图片’两个字时,返回给他一张图片,该怎么作?
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); } }
固然咱们这里把图片写死了,实际可根据具体业务逻辑进行改变,改变media_id就好了。
三、发送音乐
若是用户输入音乐,咱们发一首歌给他,音乐跟其余的几个素材不太同样
1 private function _doText($request_xml){ 2 //接受文本信息 3 $content = $request_xml->Content; 4 5 if('音乐' == $content){ 6 $music_url='音乐网络地址连接'; 7 $ha_music_url='音乐网络地址连接'; 8 $thumb_media_id='一张图片的media_id'; 9 $title = '音乐名称'; 10 $desc = '音乐描述'; 11 $this->_msgMusic($request_xml->FromUserName, $request_xml->ToUserName, $music_url, $hq_music_url, $thumb_media_id, $title, $desc); 12 } 13 } 14 //发送音乐 15 private function _msgMusic($to, $from, $music_url, $hq_music_url, $thumb_media_id, $title='', $desc='') { 16 $response = sprintf($this->_msg_template['music'], $to, $from, time(), $title, $desc, $music_url, $hq_music_url, $thumb_media_id); 17 die($response); 18 }
四、图灵机器人的接入
图灵官网注册申请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进行分类判断,字符组装,再回复给用户。
这样,你的公众号就变成了一个图灵机器人了。
五、发送图文(新闻)
我通常看到的微信公众号都是以图文信息进行推送消息,这个新闻类型怎么发送?
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); }
六、菜单建立删除
通常公众号底部都有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小时后生效
一、自定义菜单最多包括3个一级菜单,每一个一级菜单最多包含5个二级菜单。 二、一级菜单最多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