Skip to content

Commit

Permalink
Added feature to check if a user is a spammer using Combot Anti-Spam …
Browse files Browse the repository at this point in the history
…(CAS)
  • Loading branch information
tabuna committed Mar 21, 2024
1 parent a35ed44 commit 4cd09e2
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 22 deletions.
27 changes: 6 additions & 21 deletions app/Http/Controllers/WebHookController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,22 @@

namespace App\Http\Controllers;

use App\Services\TelegramBot;
use App\Jobs\TelegramMessage;
use Illuminate\Http\Request;

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')
);
}
}
60 changes: 60 additions & 0 deletions app/Jobs/TelegramMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace App\Jobs;

use App\Services\TelegramBot;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;

class TelegramMessage implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

public $text;
public $from;
public $chatId;
public $messageId;

/**
* Create a new job instance.
*/
public function __construct(public Collection $message, public TelegramBot $telegramBot)
{
$this->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);
}
}
24 changes: 23 additions & 1 deletion app/Services/TelegramBot.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Services;

use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;

class TelegramBot
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 4cd09e2

Please sign in to comment.