用户扫描带场景值二维码时,可能推送以下两种事件:
如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。 如果用户已经关注公众号,则微信会将带场景值扫描事件推送给开发者。
用户未关注时,进行关注后的事件推送
推送XML数据包示例:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> <EventKey><![CDATA[qrscene_123123]]></EventKey> <Ticket><![CDATA[TICKET]]></Ticket> </xml>
用户已关注时的事件推送
推送XML数据包示例:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[SCAN]]></Event> <EventKey><![CDATA[SCENE_VALUE]]></EventKey> <Ticket><![CDATA[TICKET]]></Ticket> </xml>
在来看看不是通过扫码关注的推送事件
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> </xml>
通过对比扫码关注和非扫码关注的xml数据推送包可以发现,扫码和非扫码关注的区别在于,扫码关注多了一个 EventKey ,所以我们可以通过判断是否有 EventKey 来判断用户是通过扫码关注的公众号还是不是通过扫码关注的。
临外,对于已关注的用户,在扫码时,event 是 scan ,同时还携带了 EventKey,而通过 EventKey 可以识别出用户是通过扫码哪个二维码进来的。
下面来看看实现代码:
private $appid = 'xxx'; //测试账号appid
private $appsecret = 'xxx';//测试账号appsecret
public function index()
{
$timestamp = input('get.timestamp');
$nonce = input('get.nonce');
$token = 'xxx';//工作平台token
$signature = input('get.signature');
$array = array($timestamp, $nonce, $token);
sort($array);
$stmstr = implode('', $array);
$stmstr = sha1($stmstr);
$echostr = input('get.echostr');
if($stmstr == $signature && $echostr){
echo $echostr;
exit;
} else {
$this->rMsg();
}
}
//发送响应消息
private function rMsg()
{
$postArr = file_get_contents("php://input");
$postObj = simplexml_load_string($postArr);
$type = strtolower($postObj->MsgType);
$cnt = $this->GRCnt($postObj, $type);
$this->SRCnt($postObj, $cnt);
}
//获取回复内容
private function GRCnt($postObj, $type)
{
switch ($type) {
//关注事件回复内容
case 'event':
//判断是否已关注
if (strtolower($postObj->Event) == 'subscribe') {
//通过判断 EventKey 来判断用户是否通过扫描关注
if ($postObj->EventKey) {
$content = "欢迎扫码关注心月IT博客";
}else{
$content = '欢迎来到心月IT博客微信公众号
回复关键词可获取相关文章信息';
}
}elseif (strtolower($postObj->Event) == 'scan') {
//关注后的扫码事件
//通过判断 EventKey 来判断用户是从哪里来的
$sceneID = $postObj->EventKey;
switch ($sceneID) {
case '2000':
$content = "临时二维码入口进入";
break;
case '3000':
$content = "永久二维码入口进入";
break;
default:
break;
}
}
break;
default:
return;
}
if (!isset($content)) return;
return $content;
}
//回复消息
private function SRCnt($postObj,$cnt)
{
$content = $cnt;
$template = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Content><![CDATA[%s]]></Contnet>
</xml>";
$info = sprintf($template, $toUser, $fromUser, $time, $msgType, $content);
echo $info;
exit();
}效果预览:

如此一来,我们就可以根据用户从不同的入口进入/关注公众号 而推送不同的容,不必在对所有的用户都推送相同的内容了。
