Skip to content

Commit 4cd09e2

Browse files
committed
Added feature to check if a user is a spammer using Combot Anti-Spam (CAS)
1 parent a35ed44 commit 4cd09e2

File tree

3 files changed

+89
-22
lines changed

3 files changed

+89
-22
lines changed

app/Http/Controllers/WebHookController.php

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,22 @@
22

33
namespace App\Http\Controllers;
44

5-
use App\Services\TelegramBot;
5+
use App\Jobs\TelegramMessage;
66
use Illuminate\Http\Request;
77

88
class WebHookController extends Controller
99
{
1010
/**
1111
* Handle incoming Telegram webhook requests.
1212
*
13-
* @param \Illuminate\Http\Request $request
14-
* @param \App\Services\TelegramBot $telegramBot
13+
* @param \Illuminate\Http\Request $request
1514
*
1615
* @return void
1716
*/
18-
public function telegram(Request $request, TelegramBot $telegramBot): void
17+
public function telegram(Request $request): void
1918
{
20-
$text = $request->input('message.text') ?? $request->input('message.caption');
21-
$messageId = $request->input('message.message_id');
22-
$chatId = $request->input('message.chat.id');
23-
$from = $request->input('message.from.id');
24-
25-
// Если сообщение - ответ на другое сообщение, то скорее всего это не спам.
26-
// Давайте не прерывать дискуссию и игнорируем его
27-
if ($request->has('message.reply_to_message') || $request->boolean('message.from.is_bot')) {
28-
return;
29-
}
30-
31-
if (! $telegramBot->isSpam($text)) {
32-
return;
33-
}
34-
35-
$telegramBot->deleteMessage($chatId, $messageId);
36-
$telegramBot->muteUserInGroup($chatId, $from);
19+
TelegramMessage::dispatch(
20+
$request->collect('message')
21+
);
3722
}
3823
}

app/Jobs/TelegramMessage.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace App\Jobs;
4+
5+
use App\Services\TelegramBot;
6+
use Illuminate\Bus\Queueable;
7+
use Illuminate\Contracts\Queue\ShouldQueue;
8+
use Illuminate\Foundation\Bus\Dispatchable;
9+
use Illuminate\Queue\InteractsWithQueue;
10+
use Illuminate\Queue\SerializesModels;
11+
use Illuminate\Support\Collection;
12+
13+
class TelegramMessage implements ShouldQueue
14+
{
15+
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
16+
17+
public $text;
18+
public $from;
19+
public $chatId;
20+
public $messageId;
21+
22+
/**
23+
* Create a new job instance.
24+
*/
25+
public function __construct(public Collection $message, public TelegramBot $telegramBot)
26+
{
27+
$this->text = $this->message->only(['text', 'caption'])->first();
28+
$this->messageId = $this->message->get('message_id');
29+
$this->chatId = $this->message->get('chat.id');
30+
$this->from = $this->message->get('from.id');
31+
}
32+
33+
/**
34+
* Execute the job.
35+
*/
36+
public function handle(): void
37+
{
38+
// If the message is a reply to another message, it's likely not spam.
39+
// Let's not disrupt the conversation and ignore it.
40+
if ($this->message->has('reply_to_message')) {
41+
return;
42+
}
43+
44+
if ($this->telegramBot->isSpam($this->text)) {
45+
$this->blocked();
46+
}
47+
}
48+
49+
/**
50+
* Block the message and mute the sender in the group.
51+
*/
52+
public function blocked(): void
53+
{
54+
// Delete the spam message from the group chat.
55+
$this->telegramBot->deleteMessage($this->chatId, $this->messageId);
56+
57+
// Mute the sender of the spam message in the group chat.
58+
$this->telegramBot->muteUserInGroup($this->chatId, $this->from);
59+
}
60+
}

app/Services/TelegramBot.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\Services;
44

55
use Illuminate\Http\Client\Response;
6+
use Illuminate\Support\Facades\Cache;
67
use Illuminate\Support\Facades\Http;
78

89
class TelegramBot
@@ -61,19 +62,40 @@ public function deleteMessage($chatId, $messageId): Response
6162
]);
6263
}
6364

65+
/**
66+
* Check if a user is spammer via Combot Anti-Spam (CAS)
67+
*
68+
* @param $userId
69+
*
70+
* @return bool
71+
*/
72+
public function checkByCAS($userId): bool
73+
{
74+
return Cache::remember('cas-user-'.$userId, now()->addHours(5), function () use ($userId) {
75+
return Http::get('https://api.cas.chat/check', [
76+
'user_id' => $userId,
77+
])->json('ok', true) === false;
78+
});
79+
}
80+
6481
/**
6582
* Check if a message is spam.
6683
*
6784
* @param string|null $message
85+
* @param null $userId
6886
*
6987
* @return bool
7088
*/
71-
public function isSpam(?string $message): bool
89+
public function isSpam(?string $message, $userId = null): bool
7290
{
7391
if (empty($message)) {
7492
return false;
7593
}
7694

95+
if ($userId !== null && $this->checkByCAS($userId)) {
96+
return true;
97+
}
98+
7799
$detector = new SpamDetector($message);
78100

79101
return $detector->isSpam();

0 commit comments

Comments
 (0)