微信公众号接口开发–回复消息
作为一个微信公众号,与用户的交互能力是十分重要的,比如根据用户发送的消息和推送事件被动的回复用户消息(文字,图片,视频,图文等等),现在我就测试了几个接口来实现这些功能:
1. 验证开发者和获取用户消息
<?php
/**
* wechat php test
*/
//define your token
define("TOKEN", "wechat");
$wechatObj = new wechatCallbackapiTest();
$wechatObj->valid();
$wechatObj->responseMsg();
class wechatCallbackapiTest
{
public function valid()
{
$echoStr = $_GET["echostr"];
//valid signature , option
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
public function responseMsg()
{
//get post data, May be due to the different environments
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
//extract post data
if (!empty($postStr)){
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$time = time();
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
if(!empty( $keyword ))
{
$msgType = "text";
$contentStr = "Welcome to wechat world!";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}else{
echo "Input something...";
}
}else {
echo "";
exit;
}
}
private function checkSignature()
{
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
// header('content-type:text');
return true;
}else{
return false;
}
}
}
?>
在此解释一下这里面两个方法的作用:
-
checkSignature():验证请求信息是否来自微信服务器。
开发者在接口配置里填写了url信息,那么在开发者提交信息后,微信服务器会发送get请求到该url上,get请求携带了4个参数(signature,timestamp,nonce,echostr),checkSignature方法对请求参数进行加密校验,流程如下:
1)将token、timestamp、nonce三个参数进行字典序排序
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)开发者获得加密后的字符串可与signature对比,相等就证明该请求来源于微信服务器,原样返回echostr参数内容,成为开发者成功,否者接入失败。 -
responseMsg():接收用户发送的消息或事件推送,并解析包含的数据,自定义回复消息。
通过全局变量$GLOBALS[“HTTP_RAW_POST_DATA”]获取post请求的内容(XML字符串),接着使用simplexml_load_string将其转换为对象,可获取fromUsername ,toUsername ,Content,Event等属性值,通过判断event类型和筛选消息内容进行回复。将回复消息的数据使用sprintf封装到回复消息的XML字符串里,返回给微信服务器,由微信服务器解析展示到客户端。
注意:验证方法只有在验证开发者的时候需要调用,一旦验证成功后不再需要,请注释掉!!!
2. 首次关注回复
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$ev=$postObj->Event;//获取事件类型
$keyword = trim($postObj->Content);
$time = time();
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
if($ev=='subscribe'){
// 用户首次关注,自动回复欢迎语
$msgType="text";
$contentStr="欢迎您的关注,只为给您更好的服务";
$resultStr=sprintf($textTpl,$fromUsername,$toUsername,$time,$contentStr);
echo $resultStr;
}
3. 点击菜单拉取消息时的事件推送
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$ev=$postObj->Event;//获取事件类型
$keyword = trim($postObj->Content);
$time = time();
if($ev=='CLICK'){
$evKey=$postObj->EventKey;
if($evKey=='send_text'){//事件KEY值,与自定义菜单接口中KEY值对应
$msgType="text";
$contentStr="你点击了Click类型的菜单";
$resultStr=sprintf($textTpl,$fromUsername,$toUsername,$time,$contentStr);
echo $resultStr;
}
}
3. 关键字回复
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$time = time();
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
if (!empty($keyword)) {
$pattern = '/.*(随机)|(random).*/';
preg_match($pattern,$keyword,$match);
if($match){
$msgType = "text";
$contentStr = mt_rand(0,100);
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $contentStr);
echo $resultStr;
}
我这里是使用正则匹配是否含有关键字,$match被填充为搜索结果。 $matches[0]将包含完整模式匹配到的文本, $matches[1] 将包含第一个捕获子组匹配到的文本,以此类推。没匹配到则为空数组。
还有其他类型的消息回复,大致流程是差不多的,只是消息的XML模板有一点区别,在这里就不演示了。希望初学者能从中有所收获!!!

1028

被折叠的 条评论
为什么被折叠?



