From 6b08230470ba64b5d2c581f4833795e36c8c068c Mon Sep 17 00:00:00 2001 From: bald-cat Date: Sun, 30 Mar 2025 12:19:55 +0300 Subject: [PATCH 1/4] Added release info messages to chats --- .../Controllers/GithubWebHookController.php | 40 +++++++++++++++++++ app/Http/Controllers/WebHookController.php | 2 - app/Services/Telegram/TelegramBot.php | 12 ++++++ config/telegram.php | 11 +++-- .../github-release-notification.blade.php | 7 ++++ routes/api.php | 3 ++ routes/web.php | 3 ++ 7 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 app/Http/Controllers/GithubWebHookController.php create mode 100644 resources/views/telegram/github-release-notification.blade.php diff --git a/app/Http/Controllers/GithubWebHookController.php b/app/Http/Controllers/GithubWebHookController.php new file mode 100644 index 00000000..660f493f --- /dev/null +++ b/app/Http/Controllers/GithubWebHookController.php @@ -0,0 +1,40 @@ +all(); + + if ($payload['action'] === 'published') { + $release = $payload['release']; + $repo = $payload['repository']; + + $message = view('telegram.github-release-notification', [ + 'repo' => $repo['full_name'], + 'version' => $release['tag_name'], + 'title' => $release['name'], + 'body' => $release['body'], + 'url' => $release['html_url'] + ])->render(); + + collect(config('telegram.chats')) + ->where('orchid_release', true) + ->each(fn($subscriber) => $telegramBot->sendMessageToChat($subscriber['id'], $message)); + } + } +} diff --git a/app/Http/Controllers/WebHookController.php b/app/Http/Controllers/WebHookController.php index f5915aa2..18cf46b2 100644 --- a/app/Http/Controllers/WebHookController.php +++ b/app/Http/Controllers/WebHookController.php @@ -31,8 +31,6 @@ public function telegram(Request $request): void ); } - Log::channel('telegram')->info(json_encode($request->all())); - TelegramMessage::dispatch( $request->collect('message'), $captcha, diff --git a/app/Services/Telegram/TelegramBot.php b/app/Services/Telegram/TelegramBot.php index 658620ee..575571fd 100644 --- a/app/Services/Telegram/TelegramBot.php +++ b/app/Services/Telegram/TelegramBot.php @@ -158,4 +158,16 @@ public function sendWelcomeButton($chatId, $userId, $name) return null; } + + public function sendMessageToChat(int $chatId, string $message): Response + { + $url = "https://api.telegram.org/bot{$this->token}/sendMessage"; + + return Http::post($url, [ + 'chat_id' => $chatId, + 'text' => $message, + 'parse_mode' => 'Markdown', + ]); + } + } diff --git a/config/telegram.php b/config/telegram.php index 3a6a9a2c..31b03d23 100644 --- a/config/telegram.php +++ b/config/telegram.php @@ -1,11 +1,12 @@ [ + 'chats' => [ [ - 'id' => '-1002111700088', - 'name' => 'Ахтунг laravel.su чат', - 'locale' => 'en', + 'id' => '-1002111700088', + 'name' => 'Ахтунг laravel.su чат', + 'locale' => 'en', + 'orchid_release' => true, ], [ 'id' => '-1001300166722', @@ -16,11 +17,13 @@ 'id' => '-1001450006147', 'name' => 'Laravel Orchid', 'locale' => 'en', + 'orchid_release' => true, ], [ 'id' => '-1001104353296', 'name' => 'Laravel Framework Russian Community', 'locale' => 'ru', + 'orchid_release' => true, ], ], 'default_locale' => 'ru', diff --git a/resources/views/telegram/github-release-notification.blade.php b/resources/views/telegram/github-release-notification.blade.php new file mode 100644 index 00000000..5b9916f9 --- /dev/null +++ b/resources/views/telegram/github-release-notification.blade.php @@ -0,0 +1,7 @@ +🚀 *New release {{ $version }}* in {{ $repo }} + +📝 *{{ $title }}* + +{{ $body }} + +[🔗 Link to release]({{ $url }}) diff --git a/routes/api.php b/routes/api.php index 1a5b3be5..65c714b0 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,5 +1,6 @@ name('webhook.telegram'); + +Route::post('/webhook/github/release', [GithubWebHookController::class, 'release'])->name('webhook.github.release'); diff --git a/routes/web.php b/routes/web.php index 8cb3320e..031376ce 100644 --- a/routes/web.php +++ b/routes/web.php @@ -6,6 +6,7 @@ use App\Http\Controllers\ChallengesController; use App\Http\Controllers\CommentsController; use App\Http\Controllers\DocsController; +use App\Http\Controllers\GithubWebHookController; use App\Http\Controllers\LikeController; use App\Http\Controllers\MeetController; use App\Http\Controllers\PackagesController; @@ -26,6 +27,8 @@ | */ +Route::get('/webhook/github/release', [GithubWebHookController::class, 'release'])->name('webhook.github.release'); + Route::view('/', 'pages.welcome')->name('home'); Route::view('/feature', 'pages.feature')->name('feature'); Route::view('/advertising', 'pages.advertising')->name('advertising'); From 105c00aa0916600aabfaefefc0fb1da87582a0c0 Mon Sep 17 00:00:00 2001 From: bald-cat Date: Sun, 30 Mar 2025 13:31:36 +0300 Subject: [PATCH 2/4] delete bot captcha --- .../Controllers/GithubWebHookController.php | 13 +- app/Http/Controllers/WebHookController.php | 13 -- app/Jobs/TelegramMessage.php | 53 +----- app/Services/Telegram/CaptchaCallback.php | 13 -- app/Services/Telegram/TelegramBot.php | 173 ------------------ app/Services/TelegramBot.php | 11 ++ 6 files changed, 20 insertions(+), 256 deletions(-) delete mode 100644 app/Services/Telegram/CaptchaCallback.php delete mode 100644 app/Services/Telegram/TelegramBot.php diff --git a/app/Http/Controllers/GithubWebHookController.php b/app/Http/Controllers/GithubWebHookController.php index 660f493f..090b5bf4 100644 --- a/app/Http/Controllers/GithubWebHookController.php +++ b/app/Http/Controllers/GithubWebHookController.php @@ -2,7 +2,7 @@ namespace App\Http\Controllers; -use App\Services\Telegram\TelegramBot; +use App\Services\TelegramBot; use Illuminate\Http\Request; class GithubWebHookController extends Controller @@ -10,11 +10,12 @@ class GithubWebHookController extends Controller /** * Handle incoming Telegram webhook requests. * - * @param \Illuminate\Http\Request $request - * @param TelegramBot $telegramBot + * @param \Illuminate\Http\Request $request + * @param TelegramBot $telegramBot * - * @return void * @throws \Throwable + * + * @return void */ public function release(Request $request, TelegramBot $telegramBot) { @@ -29,12 +30,12 @@ public function release(Request $request, TelegramBot $telegramBot) 'version' => $release['tag_name'], 'title' => $release['name'], 'body' => $release['body'], - 'url' => $release['html_url'] + 'url' => $release['html_url'], ])->render(); collect(config('telegram.chats')) ->where('orchid_release', true) - ->each(fn($subscriber) => $telegramBot->sendMessageToChat($subscriber['id'], $message)); + ->each(fn ($subscriber) => $telegramBot->sendMessageToChat($subscriber['id'], $message)); } } } diff --git a/app/Http/Controllers/WebHookController.php b/app/Http/Controllers/WebHookController.php index 18cf46b2..8d43ff7a 100644 --- a/app/Http/Controllers/WebHookController.php +++ b/app/Http/Controllers/WebHookController.php @@ -19,21 +19,8 @@ class WebHookController extends Controller */ public function telegram(Request $request): void { - $captcha = null; - if ($request->has('callback_query')) { - $data = $request->collect('callback_query'); - - $captcha = new CaptchaCallback( - checkId: $data->dot()->get('data'), - from: $data->dot()->get('from.id'), - messageId: $data->dot()->get('message.message_id'), - chatId: $data->dot()->get('message.chat.id'), - ); - } - TelegramMessage::dispatch( $request->collect('message'), - $captcha, ); } diff --git a/app/Jobs/TelegramMessage.php b/app/Jobs/TelegramMessage.php index c0bf0a86..8d9be0e6 100644 --- a/app/Jobs/TelegramMessage.php +++ b/app/Jobs/TelegramMessage.php @@ -3,17 +3,13 @@ namespace App\Jobs; use App\Models\AntiSpamRecord; -use App\Services\Telegram\CaptchaCallback; -use App\Services\Telegram\TelegramBot; +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; -use Illuminate\Support\Facades\App; -use Illuminate\Support\Facades\Cache; -use Illuminate\Support\Facades\Log; class TelegramMessage implements ShouldQueue { @@ -26,31 +22,17 @@ class TelegramMessage implements ShouldQueue public $firstName; - public $newChatMember; - - public $locale; /** * Create a new job instance. */ - public function __construct(public Collection $message, public ?CaptchaCallback $captcha) + public function __construct(public Collection $message) { $this->text = $this->message->only(['text', 'caption'])->first(); $this->messageId = $this->message->get('message_id'); $this->firstName = $this->message->dot()->get('from.first_name'); $this->chatId = $this->message->dot()->get('chat.id'); $this->from = $this->message->dot()->get('from.id'); - $this->newChatMember = (bool) $this->message->get('new_chat_member'); - - Log::channel('telegram')->info('CHAT MEMBER CONSTRUCTOR:'.$this->newChatMember); - - $chatConfig = collect(config('telegram.chats')) - ->where('id', $this->chatId) - ->first(); - - $this->locale = $chatConfig ? $chatConfig['locale'] : config('telegram.default_locale'); - - Log::channel('telegram')->info("TG Message Locale: $this->locale| TG Message chat:".json_encode($chatConfig)); } /** @@ -58,37 +40,6 @@ public function __construct(public Collection $message, public ?CaptchaCallback */ public function handle(TelegramBot $telegramBot): void { - // Ban new user without duration and send captcha button - /* - if ($this->newChatMember) { - Log::channel('telegram')->info('NEW CHAT MEMBER IF'); - App::setLocale($this->locale); - $telegramBot->banUserInGroup($this->chatId, $this->from); - $telegramBot->sendWelcomeButton($this->chatId, $this->from, $this->firstName); - - return; - } - */ - - // Unmute user after click button - if ($this->captcha?->checkId && ($this->captcha->checkId === $this->captcha->from)) { - - $telegramBot->unmuteUserInGroup($this->captcha->chatId, $this->captcha->from); - - $messageId = Cache::get("tg_message_{$this->captcha->chatId}_{$this->captcha->from}"); - - if ($messageId) { - $telegramBot->deleteMessage($this->captcha->chatId, $messageId); - Cache::forget("tg_message_{$this->captcha->chatId}_{$this->captcha->from}"); - } - - return; - } - - // Return when captcha clicked not muted users. - if ($this->captcha?->checkId && ($this->captcha->checkId !== $this->captcha->from)) { - return; - } if (empty($this->from)) { return; diff --git a/app/Services/Telegram/CaptchaCallback.php b/app/Services/Telegram/CaptchaCallback.php deleted file mode 100644 index 5b8c0bf0..00000000 --- a/app/Services/Telegram/CaptchaCallback.php +++ /dev/null @@ -1,13 +0,0 @@ -token = config('services.telegram-bot-api.token'); - } - - /** - * Mute a user in a group chat. - * - * @param int $chatId - * @param int $userId - * @param int $muteDuration - * - * @return \Illuminate\Http\Client\Response - */ - public function muteUserInGroup($chatId, $userId, int $muteDuration = 60): Response - { - $url = "https://api.telegram.org/bot{$this->token}/restrictChatMember"; - - return Http::post($url, [ - 'chat_id' => $chatId, - 'user_id' => $userId, - 'until_date' => time() + $muteDuration, - 'can_send_messages' => false, - 'can_send_media_messages' => false, - 'can_send_other_messages' => false, - 'can_add_web_page_previews' => false, - ]); - } - - public function banUserInGroup($chatId, $userId): Response - { - return $this->muteUserInGroup($chatId, $userId, 1); - } - - /** - * Unmute a user in a group chat. - * - * @param int $chatId - * @param int $userId - * - * @return \Illuminate\Http\Client\Response - */ - public function unmuteUserInGroup($chatId, $userId): Response - { - $url = "https://api.telegram.org/bot{$this->token}/restrictChatMember"; - - return Http::post($url, [ - 'chat_id' => $chatId, - 'user_id' => $userId, - 'can_send_messages' => true, - 'can_send_media_messages' => true, - 'can_send_other_messages' => true, - 'can_add_web_page_previews' => true, - ]); - } - - /** - * Delete a message from a chat. - * - * @param int $chatId - * @param int $messageId - * - * @return \Illuminate\Http\Client\Response - */ - public function deleteMessage($chatId, $messageId): Response - { - $url = "https://api.telegram.org/bot{$this->token}/deleteMessage"; - - return Http::post($url, [ - 'chat_id' => $chatId, - 'message_id' => $messageId, - ]); - } - - /** - * 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, $userId = null): bool - { - if (empty($message)) { - return false; - } - - if ($userId !== null && $this->checkByCAS($userId)) { - return true; - } - - return (new SpamDetector($message))->isSpam(); - } - - public function sendWelcomeButton($chatId, $userId, $name) - { - $url = "https://api.telegram.org/bot{$this->token}/sendMessage"; - - $keyboard = [ - 'inline_keyboard' => [ - [ - [ - 'text' => __('tg.button', ['name' => $name]), - 'callback_data' => $userId, - ], - ], - ], - ]; - - $response = Http::post($url, [ - 'chat_id' => $chatId, - 'text' => __('tg.welcome', ['name' => $name]), - 'reply_markup' => json_encode($keyboard), - ]); - - if ($response->successful()) { - $messageId = $response->json('result.message_id'); - - Cache::put("tg_message_{$chatId}_{$userId}", $messageId, now()->addMinutes(10)); - - return $messageId; - } - - return null; - } - - public function sendMessageToChat(int $chatId, string $message): Response - { - $url = "https://api.telegram.org/bot{$this->token}/sendMessage"; - - return Http::post($url, [ - 'chat_id' => $chatId, - 'text' => $message, - 'parse_mode' => 'Markdown', - ]); - } - -} diff --git a/app/Services/TelegramBot.php b/app/Services/TelegramBot.php index 9d858882..700da6fd 100644 --- a/app/Services/TelegramBot.php +++ b/app/Services/TelegramBot.php @@ -98,4 +98,15 @@ public function isSpam(?string $message, $userId = null): bool return (new SpamDetector($message))->isSpam(); } + + public function sendMessageToChat(int $chatId, string $message): Response + { + $url = "https://api.telegram.org/bot{$this->token}/sendMessage"; + + return Http::post($url, [ + 'chat_id' => $chatId, + 'text' => $message, + 'parse_mode' => 'Markdown', + ]); + } } From 91db67c99057dfbd288fa0ca31e6b58a394a5f93 Mon Sep 17 00:00:00 2001 From: bald-cat Date: Sun, 30 Mar 2025 13:32:37 +0300 Subject: [PATCH 3/4] remove extra test route --- routes/web.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/routes/web.php b/routes/web.php index 031376ce..5ca9480b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -27,8 +27,6 @@ | */ -Route::get('/webhook/github/release', [GithubWebHookController::class, 'release'])->name('webhook.github.release'); - Route::view('/', 'pages.welcome')->name('home'); Route::view('/feature', 'pages.feature')->name('feature'); Route::view('/advertising', 'pages.advertising')->name('advertising'); From 7680798c9aea5a944996dc10457a6cd313ab05f2 Mon Sep 17 00:00:00 2001 From: bald-cat Date: Sun, 30 Mar 2025 21:57:07 +0300 Subject: [PATCH 4/4] change chat list --- config/telegram.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/config/telegram.php b/config/telegram.php index 31b03d23..6dfe0e95 100644 --- a/config/telegram.php +++ b/config/telegram.php @@ -9,21 +9,21 @@ 'orchid_release' => true, ], [ - 'id' => '-1001300166722', - 'name' => 'Laravel Orchid Russian Community', - 'locale' => 'ru', + 'id' => '-1001300166722', + 'name' => 'Laravel Orchid Russian Community', + 'locale' => 'ru', + 'orchid_release' => true, ], [ - 'id' => '-1001450006147', - 'name' => 'Laravel Orchid', - 'locale' => 'en', + 'id' => '-1001450006147', + 'name' => 'Laravel Orchid', + 'locale' => 'en', 'orchid_release' => true, ], [ 'id' => '-1001104353296', 'name' => 'Laravel Framework Russian Community', 'locale' => 'ru', - 'orchid_release' => true, ], ], 'default_locale' => 'ru',