From cd6d10b3dbfec3c7e8086f36da281031f273b1ab Mon Sep 17 00:00:00 2001 From: BrettonYe <867057410@qq.com> Date: Sun, 15 Mar 2026 22:20:27 +0800 Subject: [PATCH] Improve Telegram Bot Correctly Solved #292 1st problem; --- .../Controllers/Admin/SystemController.php | 8 ++- app/Http/Controllers/TelegramController.php | 2 +- app/Http/Middleware/Telegram.php | 50 +++++++++++++++++-- app/Services/TelegramService.php | 21 +++++--- resources/lang/de/user.php | 2 +- resources/lang/en/user.php | 2 +- resources/lang/fa/user.php | 2 +- resources/lang/ja/user.php | 2 +- resources/lang/ko/user.php | 2 +- resources/lang/ru/user.php | 2 +- resources/lang/vi/user.php | 2 +- resources/lang/zh_CN/user.php | 2 +- routes/web.php | 2 +- 13 files changed, 77 insertions(+), 22 deletions(-) diff --git a/app/Http/Controllers/Admin/SystemController.php b/app/Http/Controllers/Admin/SystemController.php index 9f1e8dcd..2abd4df6 100644 --- a/app/Http/Controllers/Admin/SystemController.php +++ b/app/Http/Controllers/Admin/SystemController.php @@ -243,11 +243,15 @@ class SystemController extends Controller $value /= 100; } - // 设置TG机器人 + // 设置 TG 机器人 if ($name === 'telegram_token' && $value) { $telegramService = new TelegramService($value); $telegramService->getMe(); - $telegramService->setWebhook(rtrim(sysConfig('website_url'), '/').'/api/telegram/webhook?access_token='.md5($value)); + + $telegramService->setWebhook([ + 'url' => route('telegram.webhook'), + 'secret_token' => hash('sha256', explode(':', $value)[1]), + ]); } // 更新配置 diff --git a/app/Http/Controllers/TelegramController.php b/app/Http/Controllers/TelegramController.php index 00c5c5b0..914cdc47 100644 --- a/app/Http/Controllers/TelegramController.php +++ b/app/Http/Controllers/TelegramController.php @@ -176,7 +176,7 @@ class TelegramController extends Controller { $msg = $this->msg; $telegramService = new TelegramService; - $telegramService->sendMessage($msg->chat_id, trans('user.telegram.get_url', ['get_url' => sysConfig('website_name')]).': '.sysConfig('website_url'), 'markdown'); + $telegramService->sendMessage($msg->chat_id, trans('user.telegram.get_url', ['web_name' => sysConfig('website_name'), 'url' => sysConfig('website_url')]), 'markdown'); } private function unbind(): void diff --git a/app/Http/Middleware/Telegram.php b/app/Http/Middleware/Telegram.php index ecad6fa7..cf5a6d58 100644 --- a/app/Http/Middleware/Telegram.php +++ b/app/Http/Middleware/Telegram.php @@ -13,10 +13,54 @@ class Telegram */ public function handle($request, Closure $next) { - if (sysConfig('telegram_token') && hash_equals(sysConfig('telegram_token'), $request->input('access_token'))) { - abort(500, 'authentication failed'); + $token = sysConfig('telegram_token'); + $access_token = $request->header('x-telegram-bot-api-secret-token'); + + // 根据用户 language_code 设置语言 + $this->setLocaleFromRequest($request); + + if (isset($token, $access_token) && hash_equals(hash('sha256', explode(':', $token)[1]), $access_token)) { + return $next($request); } - return $next($request); + abort(500, 'authentication failed'); + } + + /** + * 从 Telegram 请求中提取 language_code 并设置语言. + */ + private function setLocaleFromRequest($request): void + { + $data = $request->all(); + + if (! isset($data['message']['from']['language_code'])) { + return; + } + + $languageCode = $data['message']['from']['language_code']; + $locale = $this->getLocaleFromLanguageCode($languageCode); + + app()->setLocale($locale); + } + + /** + * Telegram language_code 转换为 Laravel locale. + */ + private function getLocaleFromLanguageCode(string $languageCode): string + { + // 常见 Telegram 语言代码映射 + $mapping = [ + 'zh-hans' => 'zh_CN', // 简体中文 + 'zh-hant' => 'zh_CN', // 繁體中文 + 'ja' => 'ja', // 日本語 + 'ko' => 'ko', // 한국어 + 'ru' => 'ru', // Русский + 'de' => 'de', // Deutsch + 'vi' => 'vi', // Tiếng Việt + 'en' => 'en', + 'fa' => 'fa', + ]; + + return $mapping[$languageCode] ?? config('app.locale', 'en'); } } diff --git a/app/Services/TelegramService.php b/app/Services/TelegramService.php index 04df503c..194415ba 100644 --- a/app/Services/TelegramService.php +++ b/app/Services/TelegramService.php @@ -6,11 +6,11 @@ use Illuminate\Support\Facades\Http; class TelegramService { - private static string $api; + private string $api; public function __construct(?string $token = null) { - self::$api = 'https://api.telegram.org/bot'.($token ?? sysConfig('telegram_token')).'/'; + $this->api = 'https://api.telegram.org/bot'.($token ?? sysConfig('telegram_token')).'/'; } public function sendMessage(int $chatId, string $text, string $parseMode = ''): array @@ -22,15 +22,22 @@ class TelegramService ]); } - private function request(string $method, array $params = []): array + private function request(string $method, array $params = [], bool $usePost = false): array { - $response = Http::get(self::$api.$method.'?'.http_build_query($params)); + $http = Http::timeout(30); + + if ($usePost) { + $response = $http->post($this->api.$method, $params); + } else { + $response = $http->get($this->api.$method.'?'.http_build_query($params)); + } + $data = $response->json(); if ($response->ok()) { return $data; } - abort(500, "来自TG的错误:$data"); + abort(500, '来自 TG 的错误:'.json_encode($data)); } public function getMe(): array @@ -38,8 +45,8 @@ class TelegramService return $this->request('getMe'); } - public function setWebhook(string $url): array + public function setWebhook(array $config): array { - return $this->request('setWebhook', ['url' => $url]); + return $this->request('setWebhook', $config, true); } } diff --git a/resources/lang/de/user.php b/resources/lang/de/user.php index 48086d46..846f8533 100644 --- a/resources/lang/de/user.php +++ b/resources/lang/de/user.php @@ -247,7 +247,7 @@ return [ 'unbind' => 'Konto-Verknüpfung lösen', 'web_url' => 'Neueste :web_name Adresse abrufen', ], - 'get_url' => ':web_name neueste Adresse', + 'get_url' => ':web_name neueste Adresse: :url', 'params_missing' => 'Parameter fehlerhaft, bitte mit E-Mail-Adresse senden', 'ticket_missing' => 'Ticket existiert nicht', 'ticket_reply' => 'Ticket #:id wurde beantwortet', diff --git a/resources/lang/en/user.php b/resources/lang/en/user.php index 0fc941eb..61987438 100644 --- a/resources/lang/en/user.php +++ b/resources/lang/en/user.php @@ -247,7 +247,7 @@ return [ 'unbind' => 'Unlink account', 'web_url' => 'Retrieve the latest :web_name access link', ], - 'get_url' => ':web_name latest URL', + 'get_url' => ':web_name latest URL: :url', 'params_missing' => 'Invalid parameters. Include email address', 'ticket_missing' => 'Ticket not found', 'ticket_reply' => 'Ticket #:id has a new reply', diff --git a/resources/lang/fa/user.php b/resources/lang/fa/user.php index 8fe645a0..1a64355a 100644 --- a/resources/lang/fa/user.php +++ b/resources/lang/fa/user.php @@ -247,7 +247,7 @@ return [ 'unbind' => 'قطع پیوند حساب', 'web_url' => 'بازیابی آخرین لینک دسترسی :web_name', ], - 'get_url' => 'آخرین URL :web_name', + 'get_url' => ':web_name آخرین نشانی: :url', 'params_missing' => 'پارامترهای نامعتبر. آدرس ایمیل را شامل کنید', 'ticket_missing' => 'تیکت یافت نشد', 'ticket_reply' => 'تیکت #:id پاسخ جدیدی دارد', diff --git a/resources/lang/ja/user.php b/resources/lang/ja/user.php index ccb07790..6c7993fd 100644 --- a/resources/lang/ja/user.php +++ b/resources/lang/ja/user.php @@ -247,7 +247,7 @@ return [ 'unbind' => 'アカウント連携解除', 'web_url' => ':web_name 最新URLを取得', ], - 'get_url' => ':web_name 最新URL', + 'get_url' => ':web_name の最新リンク::url', 'params_missing' => 'パラメータエラー。メールアドレスを含めて送信してください', 'ticket_missing' => 'チケットが存在しません', 'ticket_reply' => 'チケット #:id に返信がありました', diff --git a/resources/lang/ko/user.php b/resources/lang/ko/user.php index f8d48828..f51185e8 100644 --- a/resources/lang/ko/user.php +++ b/resources/lang/ko/user.php @@ -247,7 +247,7 @@ return [ 'unbind' => '계정 연동 해제', 'web_url' => ':web_name 최신 URL 받기', ], - 'get_url' => ':web_name 최신 URL', + 'get_url' => ':web_name 최신 주소: :url', 'params_missing' => '매개변수 오류. 이메일 주소를 포함하여 발송하세요', 'ticket_missing' => '티켓이 존재하지 않습니다', 'ticket_reply' => '티켓 #:id에 답변이 있었습니다', diff --git a/resources/lang/ru/user.php b/resources/lang/ru/user.php index 9366b4c9..d7e06ca2 100644 --- a/resources/lang/ru/user.php +++ b/resources/lang/ru/user.php @@ -247,7 +247,7 @@ return [ 'unbind' => 'Отвязать аккаунт', 'web_url' => 'Получить последний адрес :web_name', ], - 'get_url' => 'Последний адрес :web_name', + 'get_url' => 'Последний адрес :web_name: :url', 'params_missing' => 'Неверные параметры, пожалуйста, отправьте с адресом электронной почты', 'ticket_missing' => 'Тикет не существует', 'ticket_reply' => 'На тикет #:id получен ответ', diff --git a/resources/lang/vi/user.php b/resources/lang/vi/user.php index 20968651..ee0eb8c9 100644 --- a/resources/lang/vi/user.php +++ b/resources/lang/vi/user.php @@ -247,7 +247,7 @@ return [ 'unbind' => 'Hủy liên kết tài khoản', 'web_url' => 'Lấy URL mới nhất :web_name', ], - 'get_url' => 'URL mới nhất :web_name', + 'get_url' => ':web_name URL mới nhất: :url', 'params_missing' => 'Lỗi tham số, vui lòng gửi kèm địa chỉ email', 'ticket_missing' => 'Ticket không tồn tại', 'ticket_reply' => 'Ticket #:id có trả lời', diff --git a/resources/lang/zh_CN/user.php b/resources/lang/zh_CN/user.php index ce331da2..a6315682 100644 --- a/resources/lang/zh_CN/user.php +++ b/resources/lang/zh_CN/user.php @@ -247,7 +247,7 @@ return [ 'unbind' => '解绑账号', 'web_url' => '获取:web_name最新网址', ], - 'get_url' => ':web_name 最新网址', + 'get_url' => ':web_name 最新网址::url', 'params_missing' => '参数有误,请携带邮箱地址发送', 'ticket_missing' => '工单不存在', 'ticket_reply' => '工单 #:id 已回复', diff --git a/routes/web.php b/routes/web.php index cc3f94b5..1fa6b8b6 100644 --- a/routes/web.php +++ b/routes/web.php @@ -21,7 +21,7 @@ if (config('app.key') && config('settings')) { } // API Webhook 路由 -Route::post('api/telegram/webhook', [TelegramController::class, 'webhook'])->middleware('telegram'); // Telegram webhook +Route::post('api/telegram/webhook', [TelegramController::class, 'webhook'])->middleware('telegram')->name('telegram.webhook'); // Telegram webhook Route::get('api/wechat/verify', [WeChatChannel::class, 'verify'])->name('wechat.verify'); // 微信回调验证 Route::get('/message/{type}/{msg_id}/show', [MessageController::class, 'index'])->name('message.show'); // 消息展示