diff --git a/app/Actions/SocialAccount/RegisterTelegramWebhook.php b/app/Actions/SocialAccount/RegisterTelegramWebhook.php new file mode 100644 index 00000000..4b0757e0 --- /dev/null +++ b/app/Actions/SocialAccount/RegisterTelegramWebhook.php @@ -0,0 +1,45 @@ + $url, + 'secret_token' => $secret, + 'allowed_updates' => ['message', 'channel_post'], + ]); + + if (! $response->successful() || data_get($response->json(), 'ok') !== true) { + throw new RuntimeException("Failed to set Telegram webhook: {$response->body()}"); + } + + return $url; + } +} diff --git a/app/Console/Commands/Telegram/SetWebhook.php b/app/Console/Commands/Telegram/SetWebhook.php index 33a77dea..28a473c9 100644 --- a/app/Console/Commands/Telegram/SetWebhook.php +++ b/app/Console/Commands/Telegram/SetWebhook.php @@ -4,10 +4,11 @@ namespace App\Console\Commands\Telegram; +use App\Actions\SocialAccount\RegisterTelegramWebhook; use Illuminate\Console\Attributes\Description; use Illuminate\Console\Attributes\Signature; use Illuminate\Console\Command; -use Illuminate\Support\Facades\Http; +use Throwable; #[Signature('telegram:set-webhook')] #[Description('Register the Telegram bot webhook with the configured URL and secret token')] @@ -15,26 +16,10 @@ class SetWebhook extends Command { public function handle(): int { - $token = (string) config('trypost.platforms.telegram.bot_token'); - $api = rtrim((string) config('trypost.platforms.telegram.api'), '/'); - $secret = (string) config('trypost.platforms.telegram.webhook_secret'); - - if ($token === '' || $secret === '') { - $this->error('TELEGRAM_BOT_TOKEN and TELEGRAM_WEBHOOK_SECRET must both be set.'); - - return self::FAILURE; - } - - $url = route('telegram.webhook'); - - $response = Http::post("{$api}/bot{$token}/setWebhook", [ - 'url' => $url, - 'secret_token' => $secret, - 'allowed_updates' => ['message', 'channel_post'], - ]); - - if (! $response->successful() || data_get($response->json(), 'ok') !== true) { - $this->error('Failed to set webhook: '.$response->body()); + try { + $url = RegisterTelegramWebhook::execute(); + } catch (Throwable $e) { + $this->error($e->getMessage()); return self::FAILURE; } diff --git a/tests/Feature/Actions/SocialAccount/RegisterTelegramWebhookTest.php b/tests/Feature/Actions/SocialAccount/RegisterTelegramWebhookTest.php new file mode 100644 index 00000000..4bfea510 --- /dev/null +++ b/tests/Feature/Actions/SocialAccount/RegisterTelegramWebhookTest.php @@ -0,0 +1,48 @@ + 'TESTTOKEN', + 'trypost.platforms.telegram.webhook_secret' => 'shh-secret', + ]); +}); + +test('it registers the webhook with the url, secret and allowed updates', function () { + Http::fake([ + '*/botTESTTOKEN/setWebhook' => Http::response(['ok' => true, 'result' => true], 200), + ]); + + $url = RegisterTelegramWebhook::execute(); + + expect($url)->toBe(route('telegram.webhook')); + + Http::assertSent(function ($request) { + return str_contains($request->url(), '/botTESTTOKEN/setWebhook') + && $request['url'] === route('telegram.webhook') + && $request['secret_token'] === 'shh-secret' + && $request['allowed_updates'] === ['message', 'channel_post']; + }); +}); + +test('it throws when the bot token or secret is missing', function () { + config(['trypost.platforms.telegram.webhook_secret' => '']); + + Http::fake(); + + expect(fn () => RegisterTelegramWebhook::execute())->toThrow(InvalidArgumentException::class); + + Http::assertNothingSent(); +}); + +test('it throws when telegram rejects the request', function () { + Http::fake([ + '*/botTESTTOKEN/setWebhook' => Http::response(['ok' => false, 'description' => 'Unauthorized'], 401), + ]); + + expect(fn () => RegisterTelegramWebhook::execute())->toThrow(RuntimeException::class); +});