Extract Telegram webhook registration into an action

This commit is contained in:
Paulo Castellano 2026-06-13 22:20:52 -03:00
parent f378469842
commit deb1c6fa69
3 changed files with 99 additions and 21 deletions

View file

@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace App\Actions\SocialAccount;
use Illuminate\Support\Facades\Http;
use InvalidArgumentException;
use RuntimeException;
class RegisterTelegramWebhook
{
/**
* Register the bot webhook (URL + secret token) with the Telegram Bot API.
*
* @return string the webhook URL that was registered
*
* @throws InvalidArgumentException when the bot token or secret is missing
* @throws RuntimeException when Telegram rejects the request
*/
public static function execute(): string
{
$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 === '') {
throw new InvalidArgumentException('TELEGRAM_BOT_TOKEN and TELEGRAM_WEBHOOK_SECRET must both be set.');
}
$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) {
throw new RuntimeException("Failed to set Telegram webhook: {$response->body()}");
}
return $url;
}
}

View file

@ -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;
}

View file

@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
use App\Actions\SocialAccount\RegisterTelegramWebhook;
use Illuminate\Support\Facades\Http;
beforeEach(function () {
config([
'trypost.platforms.telegram.bot_token' => '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);
});