$from, 'text' => $text, 'parse_mode' => 'HTML', ]); return; } // 只转发群消息 if (!in_array($chatType, ['group', 'supergroup'])) { return; } $objGroup = new GroupInfo(); $objSession = new Session(); // 处理升级为超级群的信息 if (isset($message['migrate_from_chat_id'])) { $srcId = $message['migrate_from_chat_id']; $groupId = self::getGroupByTG($srcId); self::setGroupByTG($chat_id, $groupId); self::delGroupByTG($srcId); $objGroup->objTable->updateObject(['tg_group_id' => $chat_id], ['tg_group_id' => $srcId]); return; } $groupId = self::getGroupByTG($chat_id); if (!$groupId) { // 判断是否拉进MeeChat机器人 $doGuide = false; if (isset($message['new_chat_members'])) { foreach ($message['new_chat_members'] as $member) { if ($member['id'] == BOT_ID) { $doGuide = true; break; } } } // 创建群的时候已拉入机器人 if (isset($message['group_chat_created']) && $message['group_chat_created']) { $doGuide = true; } // 开始引导同步操作 if ($doGuide) { $url = BOT_CHAT_URL . "?start=sync_{$chat_id}"; $text = "点击@meechatbot查看私聊信息,将该群与MeeChat群组进行关联同步 To sync up this chat with MeeChat group, take a look to private message from @meechatbot"; self::apiRequest('sendMessage', [ 'chat_id' => $chat_id, 'text' => $text, 'parse_mode' => 'HTML', ]); } return; } $userId = self::getUserByTG($from); !$userId && $userId = TG_BOT_ID; $extInfo = [ 'is_tg' => 1, ]; if ($userId == TG_BOT_ID) { $name = $message['from']['first_name']; $message['from']['last_name'] && $name .= "_{$message['from']['last_name']}"; $extInfo['tg_nick'] = $name; } $msgType = Session::MSG_TYPE_TEXT; if (isset($message['text'])) { // 文本消息 $text = $message['text']; // 不处理command if ($text[0] == '/') { return; } } else { // 图片视频音频 $mineType = ''; $fileId = ''; foreach (self::$messageTypes as $messageType) { if (isset($message[$messageType])) { $entity = $message[$messageType]; if ($messageType == 'photo') { // 图片会有多个尺寸,取原图 $entity = array_pop($entity); } $fileId = $entity['file_id']; $mineType = $message[$messageType]['mime_type'] ?: ''; break; } } if (!$fileId) { return; } // 标题 if ($message['caption']) { $caption = $message['caption']; $caption = Utils::encodeRC4($caption); $objSession->sendGroupMsg($userId, $groupId, Session::MSG_TYPE_TEXT, $caption, false, true, $extInfo); } list($url, $mineType, $coverUrl) = self::getURLFromFileId($fileId, $mineType); $msgType = FileUrl::getType($mineType); $text = $url; $coverUrl && $extInfo['cover_url'] = $coverUrl; } $text = Utils::encodeRC4($text); $objSession->sendGroupMsg($userId, $groupId, $msgType, $text, false, true, $extInfo); } /** * 转存文件 * @author solu * @param $fileId * @param string $mineType * @throws Exception * @return array */ public static function getURLFromFileId($fileId, $mineType = '') { $tgFilePath = self::getFilePath($fileId); $url = TELEGRAM_FILE_URL . $tgFilePath; list($path, $filename, $_, $_) = Bs2UploadHelper::saveFileFromUrl($url); if (!$mineType) { $mineType = mime_content_type($path); } $objFile = new FileUrl(); $url = $objFile->getFileUrl($path, $filename, $mineType); $url = awsReplaceImg($url); // 处理视频封面 $coverUrl = ''; if (strpos($mineType, 'video') !== false) { $coverUrl = $objFile->getVideoCover($path, $filename); $coverUrl = awsReplaceImg($coverUrl); } unlink($path); return [$url, $mineType, $coverUrl]; } /** * 获取文件路径 * @param $fileId * @return mixed * @throws Exception */ private static function getFilePath($fileId) { $url = TELEGRAM_API_URL . 'getFile?file_id=' . $fileId; $objHttp = new dwHttp(); $resp = $objHttp->get2($url); $data = json_decode($resp, true); if (!$data || !$data['ok']) { $msg = $data['description'] ?: 'get file info error'; throw new Exception($msg, CODE_PARAM_ERROR); } return $data['result']['file_path']; } /** * @param $method * @param $parameters * @return bool|mixed * @throws Exception * @return mixed */ public static function apiRequestJson($method, $parameters) { if (!is_string($method)) { throw new Exception("Method name must be a string\n"); } if (!$parameters) { $parameters = array(); } else if (!is_array($parameters)) { throw new Exception("Parameters must be an array\n"); } $parameters["method"] = $method; $handle = curl_init(TELEGRAM_API_URL); curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($handle, CURLOPT_TIMEOUT, 60); curl_setopt($handle, CURLOPT_POST, true); curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($parameters)); curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: application/json")); return self::exec_curl_request($handle); } /** * @param $method * @param $parameters * @return mixed * @throws Exception */ public static function apiRequest($method, $parameters) { if (!is_string($method)) { throw new Exception("Method name must be a string\n"); } if (!$parameters) { $parameters = array(); } else if (!is_array($parameters)) { throw new Exception("Parameters must be an array\n"); } foreach ($parameters as $key => &$val) { // encoding to JSON array parameters, for example reply_markup if (!is_numeric($val) && !is_string($val)) { $val = json_encode($val); } } $url = TELEGRAM_API_URL.$method.'?'.http_build_query($parameters); $handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($handle, CURLOPT_TIMEOUT, 60); return self::exec_curl_request($handle); } /** * @param $handle * @return bool|mixed * @throws Exception * @return mixed */ public static function exec_curl_request($handle) { $response = curl_exec($handle); if ($response === false) { $errno = curl_errno($handle); $error = curl_error($handle); curl_close($handle); throw new Exception("Curl returned error $errno: $error\n"); } $http_code = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE)); curl_close($handle); if ($http_code >= 500) { // do not wat to DDOS server if something goes wrong sleep(10); return false; } else if ($http_code != 200) { $response = json_decode($response, true); throw new Exception("Request has failed with error {$response['error_code']}: {$response['description']}\n"); } else { $response = json_decode($response, true); if (isset($response['description'])) { throw new Exception("Request was successful: {$response['description']}\n"); } $response = $response['result']; } // file_put_contents('/tmp/telegram_message.log', $response, FILE_APPEND); return $response; } private static function getCSRFKey($token) { return self::REDIS_PREFIX_TG_CSRF . $token; } public static function initCSRF($token) { $objRedis = dwRedis::init(); $key = self::getCSRFKey($token); $objRedis->setex($key, self::REDIS_TG_CSRF_TTL, 0); } /** * 获取状态 * @author solu * @param $token * @return int */ public static function getCSRFStatus($token) { $objRedis = dwRedis::init(); $key = self::getCSRFKey($token); $status = $objRedis->get($key); return false !== $status ? intval($status) : -1; } public static function setCSRFStatus($token, $id) { $objRedis = dwRedis::init(); $key = self::getCSRFKey($token); $objRedis->setex($key, self::REDIS_TG_CSRF_TTL, $id); } public static function setGroupByTG($tgGroup, $group) { $objRedis = dwRedis::init(); $objRedis->hSet(self::REDIS_TG_GROUP_TO_GROUP_HASH, $tgGroup, $group); } public static function getGroupByTG($tgGroup) { $objRedis = dwRedis::init(); return $objRedis->hGet(self::REDIS_TG_GROUP_TO_GROUP_HASH, $tgGroup); } public static function delGroupByTG($tgGroup) { $objRedis = dwRedis::init(); return $objRedis->hDel(self::REDIS_TG_GROUP_TO_GROUP_HASH, $tgGroup); } public static function setUserByTG($tgUser, $user) { $objRedis = dwRedis::init(); $objRedis->hSet(self::REDIS_TG_USER_TO_USER_HASH, $tgUser, $user); } public static function getUserByTG($tgUser) { $objRedis = dwRedis::init(); return $objRedis->hGet(self::REDIS_TG_USER_TO_USER_HASH, $tgUser); } public static function delUserByTG($tgUser) { $objRedis = dwRedis::init(); $objRedis->hDel(self::REDIS_TG_USER_TO_USER_HASH, $tgUser); } public static function pushMessageList($msg) { if (is_array($msg)) { $msg = json_encode($msg); } $objRedis = dwRedis::init(); $objRedis->lPush(self::REDIS_TG_MESSAGE_LIST, $msg); } public static function popMessageList($objRedis = null) { !$objRedis && $objRedis = dwRedis::init(); $ret = $objRedis->brPop([self::REDIS_TG_MESSAGE_LIST], 30); return $ret[1]; } private static function buildSyncText($from, $chat_id) { $url = 'https://' . $_SERVER['HTTP_HOST'] . '/#/relateGroup?'; $params = [ 'admin_id' => $from, 'group_id' => $chat_id, 'auth_date' => time(), ]; $params['hash'] = ThirdApi::genTelegramHash($params); $url .= http_build_query($params); return "点击选择你需要同步的MeeChat群组 Click to choose your MeeChat group to sync up"; } }