From 4cd09e2ef4a97a1f6a86407ca0debe865b90c741 Mon Sep 17 00:00:00 2001 From: tabuna Date: Fri, 22 Mar 2024 02:08:07 +0300 Subject: [PATCH] Added feature to check if a user is a spammer using Combot Anti-Spam (CAS) --- app/Http/Controllers/WebHookController.php | 27 +++------- app/Jobs/TelegramMessage.php | 60 ++++++++++++++++++++++ app/Services/TelegramBot.php | 24 ++++++++- 3 files changed, 89 insertions(+), 22 deletions(-) create mode 100644 app/Jobs/TelegramMessage.php diff --git a/app/Http/Controllers/WebHookController.php b/app/Http/Controllers/WebHookController.php index e1f43451..755b8c6a 100644 --- a/app/Http/Controllers/WebHookController.php +++ b/app/Http/Controllers/WebHookController.php @@ -2,7 +2,7 @@ namespace App\Http\Controllers; -use App\Services\TelegramBot; +use App\Jobs\TelegramMessage; use Illuminate\Http\Request; class WebHookController extends Controller @@ -10,29 +10,14 @@ class WebHookController extends Controller /** * Handle incoming Telegram webhook requests. * - * @param \Illuminate\Http\Request $request - * @param \App\Services\TelegramBot $telegramBot + * @param \Illuminate\Http\Request $request * * @return void */ - public function telegram(Request $request, TelegramBot $telegramBot): void + public function telegram(Request $request): void { - $text = $request->input('message.text') ?? $request->input('message.caption'); - $messageId = $request->input('message.message_id'); - $chatId = $request->input('message.chat.id'); - $from = $request->input('message.from.id'); - - // Если сообщение - ответ на другое сообщение, то скорее всего это не спам. - // Давайте не прерывать дискуссию и игнорируем его - if ($request->has('message.reply_to_message') || $request->boolean('message.from.is_bot')) { - return; - } - - if (! $telegramBot->isSpam($text)) { - return; - } - - $telegramBot->deleteMessage($chatId, $messageId); - $telegramBot->muteUserInGroup($chatId, $from); + TelegramMessage::dispatch( + $request->collect('message') + ); } } diff --git a/app/Jobs/TelegramMessage.php b/app/Jobs/TelegramMessage.php new file mode 100644 index 00000000..746ab7de --- /dev/null +++ b/app/Jobs/TelegramMessage.php @@ -0,0 +1,60 @@ +text = $this->message->only(['text', 'caption'])->first(); + $this->messageId = $this->message->get('message_id'); + $this->chatId = $this->message->get('chat.id'); + $this->from = $this->message->get('from.id'); + } + + /** + * Execute the job. + */ + public function handle(): void + { + // If the message is a reply to another message, it's likely not spam. + // Let's not disrupt the conversation and ignore it. + if ($this->message->has('reply_to_message')) { + return; + } + + if ($this->telegramBot->isSpam($this->text)) { + $this->blocked(); + } + } + + /** + * Block the message and mute the sender in the group. + */ + public function blocked(): void + { + // Delete the spam message from the group chat. + $this->telegramBot->deleteMessage($this->chatId, $this->messageId); + + // Mute the sender of the spam message in the group chat. + $this->telegramBot->muteUserInGroup($this->chatId, $this->from); + } +} diff --git a/app/Services/TelegramBot.php b/app/Services/TelegramBot.php index bf508789..d434ba1b 100644 --- a/app/Services/TelegramBot.php +++ b/app/Services/TelegramBot.php @@ -3,6 +3,7 @@ namespace App\Services; use Illuminate\Http\Client\Response; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Http; class TelegramBot @@ -61,19 +62,40 @@ public function deleteMessage($chatId, $messageId): Response ]); } + /** + * Check if a user is spammer via Combot Anti-Spam (CAS) + * + * @param $userId + * + * @return bool + */ + public function checkByCAS($userId): bool + { + return Cache::remember('cas-user-'.$userId, now()->addHours(5), function () use ($userId) { + return Http::get('https://api.cas.chat/check', [ + 'user_id' => $userId, + ])->json('ok', true) === false; + }); + } + /** * Check if a message is spam. * * @param string|null $message + * @param null $userId * * @return bool */ - public function isSpam(?string $message): bool + public function isSpam(?string $message, $userId = null): bool { if (empty($message)) { return false; } + if ($userId !== null && $this->checkByCAS($userId)) { + return true; + } + $detector = new SpamDetector($message); return $detector->isSpam();