上一篇文章我们知道怎么获取二维码,这样别人就可以扫描二维码来关注我们,但是别人关注后,发送消息,我们怎么进行相关处理?

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

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

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

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

/*
用于第一次验证我们网站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。

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

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

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

然后我们对这个信息进行获取,转化成我们想要的格式,进行相关判断,返回数据,同样也需要组装成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);
}

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

2、发送图片

微信中的图片、语音、视频、缩略图统称素材,发送和接受都是以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就行了。

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

PHP开发微信公众号(二)消息接受与推送的更多相关文章

  1. Java开发微信公众号模板消息【同步|异步】

    第一步:申请模板消息功能并添加模板 在微信公众平台找到你需要的模板,并添加上即可: 第二步:添加功能模块后开始开发 功能中使用的类及代码: 发送数据主实体类: Template.java packag ...

  2. Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理

    在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...

  3. Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装

    在前面几篇文章我们讲了微信公众号环境的配置 和微信公众号服务的接入,接下来我们来说一下微信服务器请求消息,响应消息以及事件消息的相关内容,首先我们来分析一下消息类型和返回xml格式及实体类的封装. ( ...

  4. Java开发微信公众号(二)---开启开发者模式,接入微信公众平台开发

    接入微信公众平台开发,开发者需要按照如下步骤完成: 1.填写服务器配置 2.验证服务器地址的有效性 3.依据接口文档实现业务逻辑 资料准备: 1.一个可以访问的外网,即80的访问端口,因为微信公众号接 ...

  5. spring-boot-route(二十三)开发微信公众号

    在讲微信公众号开发之前,先来大概了解一下微信公众号.微信公众号大体上可以分为服务号和订阅号,订阅号和服务号的区别如下: 服务号可以申请微信支付功能. 服务号只能由企业申请,订阅号可以有企业或个人申请. ...

  6. PHP开发微信公众号(一)二维码的获取

    要开发微信公众号,首先进行需要注册一个,然后认证.这就不用多说了. 当然如果没有,也可以去申请一个测试号来使用,地址:https://mp.weixin.qq.com/debug/cgi-bin/sa ...

  7. 2014-07-24 .NET实现微信公众号的消息回复与自定义菜单

    今天是在吾索实习的第12天.我们在这一天中,基本实现了微信公众号的消息回复与自定义菜单的创建. 首先,是实现消息回复,其关键点如下: 读取POST来的数据流:Stream 数据流变量 = HttpCo ...

  8. 使用vue开发微信公众号下SPA站点的填坑之旅

    原文发表于本人博客,点击进入使用vue开发微信公众号下SPA站点的填坑之旅 本文为我创业过程中,开发项目的填坑之旅.作为一个技术宅男,我的项目是做一个微信公众号,前后端全部自己搞定,不浪费国家一分钱^ ...

  9. Java开发微信公众号(五)---微信开发中如何获取access_token以及缓存access_token

    获取access_token是微信api最重要的一个部分,因为调用其他api很多都需要用到access_token.比如自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等在请求的时候 ...

  10. Java开发微信公众号(一)---初识微信公众号以及环境搭建

    ps:1.开发语言使用Java springMvc+Mybaits+spring maven实现 2.使用微信接口测试账号进行本地测试 https://mp.weixin.qq.com/debug/c ...

随机推荐

  1. selenium3 下载、配置

    s1-s3发展历程  : http://www.cnblogs.com/hhudaqiang/p/6550135.html 官网地址:http://www.seleniumhq.org/文档:http ...

  2. Web内容回顾

    -----------------siwuxie095 Java EE 三层结构 1.Web 层:Struts2 框架 2.Service 层:Spring 框架 3.DAO 层:Hibernate ...

  3. rtx 二次开发,查找所有部门

    1>rtx二次开发操作类 using System; using System.Collections.Generic; using System.Linq; using System.Text ...

  4. CTE 中字符串拼接

    1>cte语法 1.1>基础语句和递归语句中必须有字段 1.2>最后只能跟一条查询语句 1.3>字符串拼接,要将拼接的字段转成字符串类型,cast(fieldName as n ...

  5. [c++] final override keyword

    the two keyword are aimed at virtual function final final function must be a virtual funtion , final ...

  6. Mysql中结果集(mysql_result)与Traversable

    对于MySQL应该也不是很陌生吧,我常常爱犯的以错误就是执行mysli_qurey()后就使用数据,忘记返回的是结果集了.而对于lSELECT,.SHOW, DESCRIBE . EXPLAINmys ...

  7. Python 2.6 安装wxPython后提示"64.....32"错误解决办法

    ImportError: /usr/local/lib/wxPython-unicode-2.8.10.1/lib/python2.6/site-packages/wx-2.8-mac-unicode ...

  8. python操作mysql数据库系列-操作MySql数据库(二)

    接口测试框架层级目录结构示意图: page目录下面的mysqlTest.py:存放的是mysql的操作代码 utils目录下面的helper.py:存放的是公共的配置方法 log目录log.md:存放 ...

  9. Firefox 43无法安装xpi的问题

    Firefox 43无法安装xpi的问题 说明:Firefox 42将默认禁止安装未签名扩展   强制禁用这个首选项(高级用户): 你可以在 Firefox 配置编辑页面 (about:config ...

  10. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(9):通过XML装配Bean

    一.通过XML装配Bean 装配简易值 装配集合 命名空间装配(暂不测试) 二.测试例子 创建一个用户类:UserBean.java package com.xfwl.spring.assem; /* ...