diff --git a/app/index/controller/WechatController.php b/app/index/controller/WechatController.php new file mode 100644 index 0000000..0739a88 --- /dev/null +++ b/app/index/controller/WechatController.php @@ -0,0 +1,165 @@ +checkSignature(); + } elseif (Request::method() == 'POST') { + // 接收消息并回复 + $response = $this->receiveMessage(); + // 直接输出回复的XML字符串 + echo $response; + exit; + } + } + + // 验证签名 + protected function checkSignature() + { + $signature = Request::get('signature'); + $timestamp = Request::get('timestamp'); + $nonce = Request::get('nonce'); + $echostr = Request::get('echostr'); + $token = "token2024"; + $tmpArr = array($token, $timestamp, $nonce); + sort($tmpArr, SORT_STRING); + $tmpStr = implode($tmpArr); + $tmpStr = sha1($tmpStr); + + if ($tmpStr == $signature) { + echo $echostr; + exit; + } + } + + // 接收消息 + protected function receiveMessage() + { + $postStr = file_get_contents("php://input"); + if (empty($postStr)) { + return ''; + } + + libxml_disable_entity_loader(true); + $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); + Log::write($postObj); + // 检查消息类型 + $msgType = strtolower((string) $postObj->MsgType); + if ($msgType == 'text') { + // 提取消息内容 + $fromUsername = (string) $postObj->FromUserName; // 微信用户openid + $toUsername = (string) $postObj->ToUserName; // 公众号id + $keyword = trim((string) $postObj->Content); + + // 构造自动回复的文本消息 + $time = time(); + $textTpl = " + + + %s + + + 0 + "; + + + $responseContent = "消息标题"; + $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $responseContent); + // 假设已经确定要发送小程序卡片消息 + $this->sendMiniProgramCard((string) $postObj->FromUserName); + + return $resultStr; + } + // 如果需要处理其他类型的消息,可以在这里添加相应的逻辑 + + // 如果不是文本消息,可以返回一个空字符串或错误消息 + return ''; + } + + // 发送小程序卡片消息的方法 + private function sendMiniProgramCard($openid) + { + + $accessToken = $this->getGZHAccessToken(); + if (!$accessToken) { + // 处理获取access_token失败的情况 + return; + } + $postData = json_encode([ + 'touser' => $openid, // 接收者(用户)的openid + 'msgtype' => 'miniprogrampage', + 'miniprogrampage' => [ + 'title' => '小程序标题', + 'appid' => '小程序appid', + 'pagepath' => '小程序路径', + 'thumb_media_id' => '你的thumb_media_id' + ] + ], JSON_UNESCAPED_UNICODE); + $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$accessToken}"; + $result = json_decode(file_get_contents($url, false, stream_context_create([ + 'http' => [ + 'method' => 'POST', + 'header' => "Content-type: application/json\r\n", + 'content' => $postData, + 'timeout' => 60 // 超时时间(单位:s) + ] + ])), true); + // 处理返回结果 + if ($result['errcode'] == 0) { + // 发送成功 + } else { + // 发送失败 + } + } + + // 获取公众号Access token + public function getGZHAccessToken() + { + $access_token = Cache::get('gzh_access_token'); + if (!$access_token) { + $config = [ + 'appid' => 'appid', + 'secret' => 'secret', + 'grant_type' => 'client_credential' + ]; + $response = $this->curlPost('https://api.weixin.qq.com/cgi-bin/token', $config); + $data = json_decode($response, true); + $access_token = $data["access_token"]; + Cache::set('gzh_access_token', $access_token, $data["expires_in"] - 200); + } + return $access_token; + } + + // 发送请求 + public function curlPost($url = '', $postData = '', $options = array()) + { + if (is_array($postData)) { + $postData = http_build_query($postData); + } + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数 + if (!empty($options)) { + curl_setopt_array($ch, $options); + } + //https请求 不验证证书和host + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + $data = curl_exec($ch); + curl_close($ch); + + return $data; + } +} \ No newline at end of file