sApiToken = Config::obtain('telegram_token'); $this->sApiChatId = Config::obtain('telegram_chatid'); $sUpdate = file_get_contents("php://input"); $aUpdate = json_decode($sUpdate, true); @file_put_contents('/www/_tg/bot_log.txt', json_encode($aUpdate, JSON_PRETTY_PRINT)); $aData['chatId'] = $aUpdate["message"]["chat"]["id"]; $aData['fromId'] = $aUpdate["message"]["from"]["id"]; if (!isset($aUpdate["message"]["text"])) { http_response_code(200); echo "not have text"; exit; } $sText = $aUpdate["message"]["text"]; // 先检查step if (strpos($sText, "/s ") === 0 && $oTgStep->fromIdHit($aData['fromId'])) { $sText = ltrim($sText, '/s'); $sText = trim($sText); $aTgStepFirst = $oTgStep->find($aData["fromId"]); if ($aTgStepFirst["cmd"] == "reply") { if ($aTgStepFirst['step'] == 1) { $oHttp = new Http(); $oHttp->sMethod = "put"; $oHttp->sToUrl = $_ENV['baseUrl']."/api/tg/ticket/".$aTgStepFirst['cache']['ticketId']; $oHttp->bIsJson = true; $aData['comment'] = $sText; $aData['admin_name'] = $aUpdate["message"]["from"]["first_name"]; $oHttp->aData = $aData; $r = @json_decode($oHttp->send(), true); // 不论失败成功都清除step $oTgStep->clearByFromId($aUpdate["message"]["from"]["id"]); if ($r["ret"] == 1) { $sMessage = "成功"; } else { $sMessage = "失败"; Http::response(500, json_encode($aData)); } $this->sendMessage($sMessage); Http::response(200, 'ok'); } } } // 打断 if ($sText === "/break") { $oTgStep->clearByFromId($aData["fromId"]); $this->sendMessage("ok"); http_response_code(200);exit; } // 流量报告 // /reportWidth if (strpos($sText, '/reportWidth') === 0 || strpos($sText, '\/reportWidth') === 0) { $jobs = new \App\Services\Cron(); $jobs->reportBandWidth(); Http::response(200, 'ok'); } // 查找用户 if (strpos($sText, '/userFind') === 0 || strpos($sText, '\/userFind') === 0) { list(, $iUserId) = explode(" ", $sText, 2); $oUser = User::find($iUserId); if ($oUser) { $aUser = $oUser->toArray(); unset($aUser['pass']); unset($aUser['passwd']); unset($aUser['uuid']); unset($aUser['method']); unset($aUser['is_admin']); unset($aUser['theme']); unset($aUser['ga_token']); unset($aUser['ga_enable']); unset($aUser['api_token']); unset($aUser['is_dark_mode']); unset($aUser['locale']); } else { $aUser = ["not have id" => $iUserId]; } $this->sendMessage(json_encode($aUser, JSON_PRETTY_PRINT)); Http::response(200, 'ok'); } // 查找订单 if (strpos($sText, '/orderFindByUser') === 0 || strpos($sText, '\/orderFindByUser') === 0) { list(, $iUserId) = explode(" ", $sText, 2); $aOrder = Order::where("user_id", $iUserId)->get()->toArray(); if ($aOrder) { $aOrderNew = []; foreach ($aOrder as $k => $v) { $v['create_time'] = date("Y-m-d H:i:m", $v['create_time']); $v['update_time'] = date("Y-m-d H:i:m", $v['update_time']); $v['product_content'] = json_decode($v['product_content']); $aOrderNew[] = $v; } } else { $aOrderNew = ["not have id" => $iUserId]; } $this->sendMessage(json_encode($aOrderNew, JSON_PRETTY_PRINT)); Http::response(200, 'ok'); } // 回复工单 if (strpos($sText, '/reply') === 0) { // 先清除一遍,只进行一个进程 $oTgStep->clearByFromId($aData["fromId"]); $iTicketId = str_replace('/reply', '', $sText); $iTicketId = (int) trim($iTicketId); $oTgStep->add($aData['fromId'], 'reply', 1, ["ticketId" => $iTicketId]); $sMessage = "将回复工单【".$iTicketId."】,请输入回复内容。"; $this->sendMessage($sMessage); Http::response(200, 'ok'); } // 快捷回复工单 if (strpos($sText, '/ry') === 0) { $sText = $this->trimText($sText, '/ry'); list($iTicketId, $sText) = explode(" ", $sText, 2); $oHttp = new Http(); $oHttp->sMethod = "put"; $oHttp->sToUrl = $_ENV['baseUrl']."/api/tg/ticket/".$iTicketId; $oHttp->bIsJson = true; $aData['comment'] = $sText; $aData['admin_name'] = $aUpdate["message"]["from"]["first_name"]; $oHttp->aData = $aData; $r = @json_decode($oHttp->send(), true); // 不论失败成功都清除step $oTgStep->clearByFromId($aUpdate["message"]["from"]["id"]); if ($r["ret"] == 1) { $sMessage = "成功"; } else { $sMessage = "失败"; Http::response(500, json_encode($aData)); } $this->sendMessage($sMessage); Http::response(200, 'ok'); } // 用户报表 if (strpos($sText, '/reportUser_') === 0) { @list(, $sOption1, $sOption2, $sOption3) = explode("_", $sText, 4); if ($sOption1 == 'day') { $sMsg = (new ServiceTgReportUser())->ByDay($sOption2); } if ($sOption1 == 'date') { $sMsg = (new ServiceTgReportUser())->ByDate($sOption2, $sOption3); } $this->sendMessage($sMsg); Http::response(200, 'ok'); } // 添加duck // /duckAdd jp01 if (strpos($sText, '/duckAdd') === 0 || strpos($sText, '\/duckAdd') === 0) { list($sCmd, $sCode) = explode(" ", $sText, 2); try { $oDucks = new Ducks(); $oDucks->code = $sCode; if ($oDucks->save()) { $sMsg = "成功"; } else { $sMsg = "失败"; } } catch (\Exception $e) { $sMsg = json_encode($e->getMessage()); } $this->sendMessage($sMsg); Http::response(200, 'ok'); } // 查找duck // /duckFind jp01 if (strpos($sText, '/duckFind') === 0 || strpos($sText, '\/duckFind') === 0) { list($sCmd, $sCode) = explode(" ", $sText, 2); $aData = Ducks::where('code', $sCode)->first()->toArray(); $aData['use_width'] = Tools::flowToGB($aData['use_width']).'g'; $aData['max_width'] = Tools::flowToGB($aData['max_width']).'g'; $aData['today_width'] = Tools::flowToGB($aData['today_width']).'g'; $this->sendMessage(json_encode($aData, JSON_PRETTY_PRINT)); Http::response(200, 'ok'); } // 添加zhuanfa // /zhuanfaAdd jp01 if (strpos($sText, '/zhuanfaAdd') === 0 || strpos($sText, '\/zhuanfaAdd') === 0) { list($sCmd, $sCode) = explode(" ", $sText, 2); try { $oZhuanfas = new Zhuanfas(); $oZhuanfas->code = $sCode; if ($oZhuanfas->save()) { $sMsg = "成功"; } else { $sMsg = "失败"; } } catch (\Exception $e) { $sMsg = json_encode($e->getMessage()); } $this->sendMessage($sMsg); Http::response(200, 'ok'); } // 删除duck // /duckDel jp01 if (strpos($sText, '/duckDel') === 0 || strpos($sText, '\/duckDel') === 0) { list($sCmd, $sCode) = explode(" ", $sText, 2); try { $oDucks = Ducks::where("code", $sCode)->first(); if ($oDucks) { // 尝试删除记录 $deleted = $oDucks->delete(); if ($deleted) { // 删除成功 $sMsg = "成功"; } else { // 删除失败 $sMsg = "失败"; } } else { // 找不到记录 $sMsg = "找不到记录"; } } catch (\Exception $e) { // 捕获异常并返回错误信息 $sMsg = json_encode($e->getMessage()); } $this->sendMessage($sMsg); Http::response(200, 'ok'); } // 删除zhuanfa // /zhuanfaDel jp01 if (strpos($sText, '/zhuanfaDel') === 0 || strpos($sText, '\/zhuanfaDel') === 0) { list($sCmd, $sCode) = explode(" ", $sText, 2); try { $oZhuanfas = Zhuanfas::where("code", $sCode)->first(); if ($oZhuanfas) { // 尝试删除记录 $deleted = $oZhuanfas->delete(); if ($deleted) { // 删除成功 $sMsg = "成功"; } else { // 删除失败 $sMsg = "失败"; } } else { // 找不到记录 $sMsg = "找不到记录"; } } catch (\Exception $e) { // 捕获异常并返回错误信息 $sMsg = json_encode($e->getMessage()); } $this->sendMessage($sMsg); Http::response(200, 'ok'); } // 修改duck // /duckOption-end_date-jp01 2025_02_02 // /duckOption-max_width-jp01 1.66#tb if (strpos($sText, '/duckOption') === 0 || strpos($sText, '\/duckOption') === 0) { list($sCmd, $sSet) = explode(" ", $sText, 2); list(, $sField, $sCode) = explode("-", $sCmd, 3); @list($iWidth, $sWidthType) = explode("#", $sSet, 2); if ($sWidthType == 'tb') { $sSet = Tools::tomTbToB($iWidth); } if ($sWidthType == 'gb') { $sSet = Tools::tomGbToB($iWidth); } $sMsg = '?'; try { $oDuck = Ducks::where('code', $sCode)->first(); if (!$oDuck) { $sMsg = "没有这个code"; } else { $oDuck->$sField = $sSet; if ($oDuck->save()) { $sMsg = "成功"; // 保存成功 } else { $sMsg = "失败"; // 保存失败 } } } catch (\Illuminate\Database\QueryException $e) { $sMsg = json_encode($e->getMessage()); } $this->sendMessage($sMsg); Http::response(200, 'ok'); } // 修改zhuanfa // /zhuanfaOption-end_date-jp01 2025_02_02 // /zhuanfaOption-max_width-jp01 1.66#tb if (strpos($sText, '/zhuanfaOption') === 0 || strpos($sText, '\/zhuanfaOption') === 0) { list($sCmd, $sSet) = explode(" ", $sText, 2); list(, $sField, $sCode) = explode("-", $sCmd, 3); @list($iWidth, $sWidthType) = explode("#", $sSet, 2); if ($sWidthType == 'tb') { $sSet = Tools::tomTbToB($iWidth); } if ($sWidthType == 'gb') { $sSet = Tools::tomGbToB($iWidth); } $sMsg = '?'; try { $oZhuanfas = Zhuanfas::where('code', $sCode)->first(); if (!$oZhuanfas) { $sMsg = "没有这个code"; } else { $oZhuanfas->$sField = $sSet; if ($oZhuanfas->save()) { $sMsg = "成功"; // 保存成功 } else { $sMsg = "失败"; // 保存失败 } } } catch (\Illuminate\Database\QueryException $e) { $sMsg = json_encode($e->getMessage()); } $this->sendMessage($sMsg); Http::response(200, 'ok'); } // 转发重置 // /zhuanfaReset-youshi 2025-02-02 if (strpos($sText, '/zhuanfaReset') === 0 || strpos($sText, '\/zhuanfaReset') === 0) { list($sCmd, $sDate) = explode(" ", $sText, 2); list(, $sCode) = explode("-", $sCmd, 2); $sMsg = '?'; try { $oZhuanfas = Zhuanfas::where('code', $sCode)->first(); if (!$oZhuanfas) { $sMsg = "没有这个code"; } else { $oZhuanfas->use_width = 0; $oZhuanfas->end_date = $sDate; if ($oZhuanfas->save()) { $sMsg = "成功"; // 保存成功 } else { $sMsg = "失败"; // 保存失败 } } } catch (\Illuminate\Database\QueryException $e) { $sMsg = json_encode($e->getMessage()); } $this->sendMessage($sMsg); Http::response(200, 'ok'); } // duck list // /duckList if (strpos($sText, '/duckList') === 0 || strpos($sText, '\/duckList') === 0) { $aDuckList = Ducks::orderBy('code')->get()->toArray(); $aMsgData = []; foreach ($aDuckList as $k => $v) { $v['use_width'] = Tools::flowToGB($v['use_width']).'g'; $v['max_width'] = Tools::flowToGB($v['max_width']).'g'; $v['today_width'] = Tools::flowToGB($v['today_width']).'g'; $aMsgData[] = $v; } $this->sendMessage(json_encode($aMsgData, JSON_PRETTY_PRINT)); Http::response(200, 'ok'); } // zhuanfa list // /zhuanfaList if (strpos($sText, '/zhuanfaList') === 0 || strpos($sText, '\/zhuanfaList') === 0) { $aDuckList = Ducks::orderBy('code')->get()->toArray(); $aMsgData = []; foreach ($aZhuanfaList as $k => $v) { $v['use_width'] = Tools::flowToTB($v['use_width'])."t"; $v['max_width'] = Tools::flowToTB($v['max_width']).'t'; $v['today_width'] = Tools::flowToGB($v['today_width']).'g'; $aMsgData[] = $v; } $this->sendMessage(json_encode($aMsgData, JSON_PRETTY_PRINT)); Http::response(200, 'ok'); } // 节点设置变更 // /nodeOption_name_1 haha if (strpos($sText, '/nodeOption_') === 0 || strpos($sText, '\/nodeOption_') === 0) { list($sCmd, $sSet) = explode(" ", $sText, 2); list(, $sField, $iNodeId) = explode("_", $sCmd, 3); switch ($sField) { case "config": $sField = "custom_config"; break; case "duck": $sField = "duck_code"; break; case "zhuanfa": $sField = "zhuanfa_code"; break; default: $sField = $sField; break; } $sMsg = '?'; try { $oNode = Node::find($iNodeId); if (!$oNode) { $sMsg = "没有这个id"; } else { $oNode->$sField = $sSet; $oNode->save(); $sMsg = "ok"; } } catch (\Illuminate\Database\QueryException $e) { $sMsg = "数据库操作失败"; } $this->sendMessage($sMsg); Http::response(200, 'ok'); } // 节点搜索 if (strpos($sText, '/nodeLike_') === 0) { list($sCmd, $sLike) = explode(" ", $sText, 2); list(, $sField) = explode("_", $sCmd, 2); switch ($sField) { case "port": $sField = "custom_config"; break; case "config": $sField = "custom_config"; break; case "duck": $sField = "duck_code"; break; case "zhuanfa": $sField = "zhuanfa_code"; break; default: $sField = $sField; break; } try { $aNodeList = Node::where($sField, 'like', '%' . $sLike . '%')->get()->toArray(); } catch (\Illuminate\Database\QueryException $e) { $this->sendMessage("字段不存在"); Http::response(200, 'ok'); } if (empty($aNodeList)) { $sMsg = "没有"; } else { $sMsg = ''; foreach ($aNodeList as $row) { $sMsg .= "\n\n"; $sMsg .= "艾地:".$row['id']."。\n"; $sMsg .= "名字:".$row['name']."。\n"; $sMsg .= "转发:".$row['zhuanfa_code']."。\n"; $sMsg .= "机器:".$row['duck_code']."。\n"; $sMsg .= "目标:".$row['server']."。\n"; $sMsg .= "设置:".$row['custom_config']."。\n"; $sMsg .= "其他:"; $sMsg .= "【节点组:".$row['node_group']."】"; $sMsg .= "【排序组:".$row['order_group']."】"; $sMsg .= "【等级:".$row['node_class']."】"; $sMsg .= "【启用type:".$row['type']."】"; if ($row['memo']) { $sMsg .= "备注:".$row['memo']."。\n"; } } } $this->sendMessage($sMsg); Http::response(200, 'ok'); } // 工单查找 if (strpos($sText, '/ticketFind') === 0) { $iTicketId = $this->trimText($sText, '/ticketFind'); $aTicket = Ticket::where("id", $iTicketId)->first()->toArray(); $sMsg = "title:".$aTicket['title']."。\n"; $aTicketContent = json_decode($aTicket['content'], true); if (!is_array($aTicketContent[0])) { $aTicketContent[] = $aTicketContent; } foreach ($aTicketContent as $row) { $sMsg .= "\n"; $sMsg .= "name:".$row['commenter_name']."\n"; $sMsg .= "comment:".$row['comment']."\n"; } $this->sendMessage($sMsg); Http::response(200, 'ok'); } Http::response(200, '无'); } private function trimText($sText, $sTrim) { $sText = ltrim($sText, $sTrim); $sText = trim($sText); return $sText; } private function sendMessage($sText) { if ($_ENV['is_loc'] === true) { echo "
";
echo($sText);
} else {
$url = "https://api.telegram.org/bot$this->sApiToken/sendMessage?chat_id=$this->sApiChatId&text=" . urlencode($sText);
file_get_contents($url);
}
}
}