用户关注公众号回调
参考资料
基本信息
- AppID:开发者ID,微信公众号的唯一标识
- AppSecret:开发者密码,操作微信公众号的验证
- IP白名单:获取access_token时,需要IP白名单才可以获取
- OpenID:微信用户在当前公众号的唯一标识
- UnionID:微信用户在当前开放平台账号的所有公众号和应用情景下的唯一标识
- 服务器配置:
(1)地址:配置以后,用户对公众号的操作(关注、发消息),微信会转到该链接
(2)令牌:用作生成签名
(3)密钥:消息加密
官方文档教程
7.验证服务器地址,6(1) 配置时要在链接下,原样输出微信发送GET请求的参数echostr,验证成功过后,才能配置完成。
公众号关注后的推送
- 在上一步的服务器地址中,加入以下代码
(1) 接口加密,官方PHP-DEMO
include_once "wxBizMsgCrypt.php";
// 第三方发送消息给公众平台
$encodingAesKey = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG";
$token = "pamtest";
$timeStamp = "1409304348";
$nonce = "xxxxxx";
$appId = "wxb11529c136998cb6";
$text = "<xml><ToUserName><![CDATA[oia2Tj我是中文jewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo]]></Title><Description><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>";
$pc = new WXBizMsgCrypt($token, $encodingAesKey, $appId);
$encryptMsg = '';
$errCode = $pc->encryptMsg($text, $timeStamp, $nonce, $encryptMsg);
if ($errCode == 0) {
print("加密后: " . $encryptMsg . "\n");
} else {
print($errCode . "\n");
}
$xml_tree = new DOMDocument();
$xml_tree->loadXML($encryptMsg);
$array_e = $xml_tree->getElementsByTagName('Encrypt');
$array_s = $xml_tree->getElementsByTagName('MsgSignature');
$encrypt = $array_e->item(0)->nodeValue;
$msg_sign = $array_s->item(0)->nodeValue;
$format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>";
$from_xml = sprintf($format, $encrypt);
// 第三方收到公众号平台发送的消息
$msg = '';
$errCode = $pc->decryptMsg($msg_sign, $timeStamp, $nonce, $from_xml, $msg);
if ($errCode == 0) {
print("解密后: " . $msg . "\n");
} else {
print($errCode . "\n");
}
(2) 关注、发送消息的推送 官方文档
$xmlStr = $GLOBALS['HTTP_RAW_POST_DATA'];
if(!empty($xmlStr )){
// 解析该xml字符串,利用simpleXML
libxml_disable_entity_loader(true);
//禁止xml实体解析,防止xml注入
$requestXml = simplexml_load_string($xmlStr , 'SimpleXMLElement', LIBXML_NOCDATA);
//判断该消息的类型,通过元素MsgType
switch ($requestXml ->MsgType){
case 'event':
//判断具体的时间类型(关注、取消、点击)
$event = $requestXml->Event;
if ($event=='subscribe') { // 关注事件
//查看用户是否首次关注
$content = '欢迎关注!';
if(isset($requestXml->EventKey)) {
// 扫特定二维码关注会携带相对应的参数,具体见下一篇
}
}elseif ($event=='CLICK') {//菜单点击事件
}elseif ($event=='VIEW') {//连接跳转事件
}
break;
case 'text'://文本消息
break;
case 'image'://图片消息
break;
case 'voice'://语音消息
break;
case 'video'://视频消息
break;
case 'shortvideo'://短视频消息
break;
case 'location'://位置消息
break;
case 'link'://链接消息
break;
}
}
(3)接受关注的数据格式
(4) 回复消息
//基本消息模板
private $mMsgTemplate = [
'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>',//某个新闻模板
];
//回复
echo sprintf($this->mMsgTemplate ['text'], $requestXml->FromUserName, $requestXml ->ToUserName, time(), $msgContent);