微信公众平台API分析
大家都知道微信哈,但是不一定所有的人都玩过微信公众平台,因为公司在弄的原因,我最近两个月也在兼做这一个项目。
公司希望有一个微信公众账户,能对自己产品做到一定的推广作用。可是腾讯自己提供了官方的规则编辑很不好用并且还有限制,不如规则只能小于等于50条这样的。所以市场部门那边请我帮忙他们写一个后台将公众平台切换到开发模式中,今后只与我做的后台做交互;
进入到开发模式中可以阅读到官方文档http://mp.weixin.qq.com/wiki/index.php
懒得研究又想快速了解的可以听我大概总结一下:
普通微信用户发送一条消息背后产生的流程
1、一个普通用户输入消息可以有很多种类型(文本消息、图文消息、地理位置消息、链接消息、事件消息),消息经过您的手机到达移动联通电信的服务器然后转到腾讯的服务器上。
2、腾讯服务器接收到你的消息后,从他的服务器中发现你发送的消息是应该送给微信公众平台上,并且这个公众平台还是调到了开发模式上。腾讯服务器就从他的database中去获得你填入的 接口配置信息的URL 去request post一串数字到你自己在公网上架设的一台server上,比如像这样:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[this is a test]]></Content> <MsgId>1234567890123456</MsgId> </xml>
Content是你发送的正文内容、MsgType是(文本消息、图文消息、地理位置消息、链接消息、事件消息)的任何一种。
3、你架设的那台server上接收到这个request之后,这里以php为后台开发语言
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; $postObj = simplexml_load_string($postStr); $MsgType = $postObj->MsgType; if($MsgType == "text") //文本消息 { //do something } else if($MsgType == "image") //圖片消息 { } else if($MsgType == "location") //地理位置消息 { } else if($MsgType == "link") //链接消息 { } else if($MsgType == "event") //事件推送 { }
具体针对什么类型的消息分别做不同的处理即可,只需带入参数$postObj用->访问内部的元素。
4、然后你自己的server上需要一个database,相应有什么关键字、来源是什么类型、是否精确匹配、回复什么内容 这几个栏位即可,从中抓到内容之后回复腾讯服务器上(5秒钟内如果不回复它的话本次消息就会失效,跟公众平台发消息将收不到任何消息),回复文本消息会是长得这样:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[content]]></Content> <FuncFlag>0</FuncFlag> </xml>
注意:这里的ToUserName 和FromUserName 与第2步中的是刚好相反的,CreateTime也是$CreateTime = time();获得到,FunFlag的意思是,标记此消息,一般会在没有找到回复规则的时候标记起来此条消息,这样人工登陆微信公众平台网站人工回复内容的时候就会很容易的看到它。
$ToUserName = $request->FromUserName; $FromUserName = $request->ToUserName; $CreateTime = time(); $MsgType = "text"; $Content = "你刚刚是不是说:\"" . $request->Content."\"?"; $responseXMLString=<<<STR <xml> <ToUserName><![CDATA[{$ToUserName}]]></ToUserName> <FromUserName><![CDATA[{$FromUserName}]]></FromUserName> <CreateTime>{$CreateTime}</CreateTime> <MsgType><![CDATA[{$MsgType}]]></MsgType> <Content><![CDATA[{$Content}]]></Content> <FuncFlag>0</FuncFlag> </xml> STR; //$responseXMLString 就是你回复给腾讯服务器的消息
5、腾讯服务器收到你的消息之后,它就知道你回复给用户的是text文本消息,并且内容是 : 你刚刚是不是说: (你说的原话)?
它就会在准确及时的会给发送微信的用户。一次消息就完成。
图文消息也很简单:只是生成回复给腾讯的xml字串的时候要注意item只能有10条之内,并且最顶上最大的图是第一条记录。
说到这里还忘了一个必须要重视的东西:验证,因为腾讯需要确认这台服务器是不是当初你设置的这个地址,这样做的原意是 万一你的server被攻击了,或者域名被挟持了,它能够及时发现,不予以处理。
验证的规则有:
参数 | 描述 |
---|---|
signature | 微信加密签名 |
timestamp | 时间戳 |
nonce | 随机数 |
echostr | 随机字符串 |
下面附上经过我改过的php验证代码:
if($echoStr != false) //valid weixin { $this->valid($this->input->get(NULL,false)); return; } private function valid($request) { if($this->checkSignature($request)) { $this->output->set_output($request["echostr"]); } } private function checkSignature($request) { $signature = $request["signature"]; $timestamp = $request["timestamp"]; $nonce = $request["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ) { return true; } else { return false; } }