微信公众号接口开发--回复消息

微信公众号接口开发–回复消息

作为一个微信公众号,与用户的交互能力是十分重要的,比如根据用户发送的消息和推送事件被动的回复用户消息(文字,图片,视频,图文等等),现在我就测试了几个接口来实现这些功能:

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;
		}
	}
}
?>

在此解释一下这里面两个方法的作用:

  1. checkSignature():验证请求信息是否来自微信服务器。
    开发者在接口配置里填写了url信息,那么在开发者提交信息后,微信服务器会发送get请求到该url上,get请求携带了4个参数(signature,timestamp,nonce,echostr),checkSignature方法对请求参数进行加密校验,流程如下:
    1)将token、timestamp、nonce三个参数进行字典序排序
    2)将三个参数字符串拼接成一个字符串进行sha1加密
    3)开发者获得加密后的字符串可与signature对比,相等就证明该请求来源于微信服务器,原样返回echostr参数内容,成为开发者成功,否者接入失败。

  2. 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模板有一点区别,在这里就不演示了。希望初学者能从中有所收获!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值