Extract Telegram webhook registration into an action
This commit is contained in:
parent
f378469842
commit
deb1c6fa69
3 changed files with 99 additions and 21 deletions
45
app/Actions/SocialAccount/RegisterTelegramWebhook.php
Normal file
45
app/Actions/SocialAccount/RegisterTelegramWebhook.php
Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
Loading…
Reference in a new issue