这几天遇到的问题,直教人,生不如死。
公众号开发(公众号:iSoftFine),“自定义被动回复用户消息”这一步,对应的文档是https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543。
按照正常的开发步骤,登录公众号以后,左侧菜单,“开发-->基本配置-->服务器地址(URL)”中设置了这个链接“http://123.206.xx.xx/wx”,然后在我的公众号中发消息留言,然后得到了非常快非常快的回复“该公众号提供的服务出现故障,请稍后再试”,而不是官方文档所描述的尝试5秒的请求。
服务器上的页面代码如下:
<?php require("visitorinfor.php"); //$ToUserName = $_GET["ToUserName"]; $a = new visitorInfo(); $b = $a->getIp(); #echo $b; logger($b); logger("==日志开始=="); # echo "success " . date('Y-m-d H:i:s',time()); echo "success"; //定义 token define("TOKEN", "sabre"); //实例化对象 $wechatObj = new wechatCallbackapiTest(); //调用函数 if (isset($_GET['echostr'])) { $wechatObj->valid(); }else{ $wechatObj->responseMsg(); logger("wechatObj:"); }; function logger($msg){ $file = "messager.txt"; file_put_contents($file, $msg . date('Y-m-d H:i:s',time()) . PHP_EOL, FILE_APPEND); }; class wechatCallbackapiTest { public function valid() { $echoStr = $_GET["echostr"]; if($this->checkSignature()){ ob_clean(); echo $echoStr; exit; }else{ write_log('认证失败'); exit; } } public function responseMsg() { //$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //$postStr = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input"); if(isset($GLOBALS['HTTP_RAW_POST_DATA'])){ $postStr = $GLOBALS['HTTP_RAW_POST_DATA']; #echo "GLOBALS['HTTP_RAW_POST_DATA']"; logger("GLOBALS['HTTP_RAW_POST_DATA']不空"); } else{ $postStr = file_get_contents('php://input'); //echo "file_get_contents:".$postStr->FromUserName; logger("GLOBALS['HTTP_RAW_POST_DATA']为空");//.gettype($postStr)); } if (!empty($postStr)){ //libxml_disable_entity_loader(true);//安全防护 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $createTime = $postObj->CreateTime; $msgType = $postObj->MsgType; $content = $postObj->Content; $msgId = $postObj->MsgId; if($msgType == 'text'){ $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>0</FuncFlag> </xml>"; $time = time(); $contentStr = "您发的是消息包含以下信息: 发信人OpenID:".$fromUsername." 收信人微信号:".$toUsername." 发信时间:".$createTime." 消息类型:".$msgType." 消息内容:".$content." 消息ID:".$msgId; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $contentStr); ob_clean(); echo $resultStr; }else{ $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>0</FuncFlag> </xml>"; $time = time(); $contentStr = "您发的消息类型不是文本。而是".$msgType; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $contentStr); ob_clean(); echo $resultStr; } } } private function checkSignature() { if (!defined("TOKEN")) { throw new Exception('TOKEN is not defined!'); } $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr, SORT_STRING); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ return true; }else{ return false; } } } logger("==日志结束==") ?>
根据现象来看,一定是哪里报错了。
- 按照最低要求,只回复了一个success,不行。
- 把页面上所有的echo输出都删除,不行。
- 使用ob_clean();清除其它输出,不行。
- 更换页面,尝试网上的各种解决方案,不行。
- 设置第三方授权,不行。
- 开启微信开发的警报,“开发-->运维中心-->接口告警”,把下面的阈值设置为1次/5分钟。事实证明,正是这个告警帮我解决了问题。但是这个告警不怎么灵,最初的时候,我连续发了41个消息的时候,自动成立的群中,出现了一条告警消息。后来不确定次数会发一个选区消息。再后来,第三、四天以后,无论怎样发消息,也不再告警了,不知原因。
告警中回复的消息如下:
Appid: *** 昵称: *** 时间: 2018-03-29 02:04:41 内容: 微信服务器向公众号推送消息或事件后,得到的回应不合法 次数: 5分钟 17次 错误样例: [OpenID=***][Stamp=1522260281][3rdUrl=http://123.206.xx.xx/wx][Msg=Text][ip=123.206.xx.xx}[response_length=367][response_content=<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>301 Moved Permanently</title> </head><body> <h1>Moved Permanently</h1> <p>The document has moved < a href="http://123.206.xx.xx/wx/?signature=604fbc39b06d70eef96776f18f723ec8ebe75bdd&timestamp=1522260281&nonce=416143100&openid=o8Cfj1VZELLnqs0uBNvxBVZOa6jY">here</ a>.</p> </body></html>] 报警排查指引,请见: http://url.cn/ab0jnP
是个301重定向的错误。
足足困扰了两天,决定要放弃了。
但是没有放弃,心里一直惦记着这个事儿。
今天,偶然又翻了一下这个告警消息,发现了一点端倪。
回复的消息中<p>The document has moved < a href="http://123.206.xx.xx/wx/?signature=604fbc39b06d70eef96776f18f723ec8ebe75bdd为什么wx后面会有个斜杠?我设置的网址中似乎没有斜杠。灵光乍现,赶紧回去看了一下,果然没有斜杠,加上,测试,通过。
这就是暗时间的力量,念念不忘,必有回响。
同时建议微信开发团队,加上一个URL的示例,会节约不少社会生产力。你们的一言一行,都涉及广大人民群众。