mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix(telegram): show API errors when sending test notifications (#12219)
This commit is contained in:
@@ -8,6 +8,7 @@ use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Http\Client\Response;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
@@ -49,6 +50,19 @@ class SendMessageToTelegramJob implements ShouldBeEncrypted, ShouldQueue
|
||||
* Execute the job.
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$response = $this->sendMessage();
|
||||
|
||||
// 401: invalid bot token, 403: the bot was blocked or removed from the chat, 400 "chat not found": wrong chat ID.
|
||||
$isConfigurationError = in_array($response->status(), [401, 403], true)
|
||||
|| ($response->status() === 400 && Str::contains((string) $response->json('description'), 'chat not found', true));
|
||||
$this->handleNotificationResponse($response, 'Telegram', $isConfigurationError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the Telegram sendMessage API and return its response without handling errors.
|
||||
*/
|
||||
public function sendMessage(): Response
|
||||
{
|
||||
$url = 'https://api.telegram.org/bot'.$this->token.'/sendMessage';
|
||||
$inlineButtons = [];
|
||||
@@ -78,11 +92,7 @@ class SendMessageToTelegramJob implements ShouldBeEncrypted, ShouldQueue
|
||||
if ($this->threadId) {
|
||||
$payload['message_thread_id'] = $this->threadId;
|
||||
}
|
||||
$response = Http::post($url, $payload);
|
||||
|
||||
// 401: invalid bot token, 403: the bot was blocked or removed from the chat, 400 "chat not found": wrong chat ID.
|
||||
$isConfigurationError = in_array($response->status(), [401, 403], true)
|
||||
|| ($response->status() === 400 && Str::contains((string) $response->json('description'), 'chat not found', true));
|
||||
$this->handleNotificationResponse($response, 'Telegram', $isConfigurationError);
|
||||
return Http::post($url, $payload);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Livewire\Notifications;
|
||||
|
||||
use App\Jobs\SendMessageToTelegramJob;
|
||||
use App\Livewire\Notifications\Concerns\TogglesNotificationEvents;
|
||||
use App\Models\Team;
|
||||
use App\Models\TelegramNotificationSettings;
|
||||
@@ -306,7 +307,23 @@ class Telegram extends Component
|
||||
{
|
||||
try {
|
||||
$this->authorize('sendTest', $this->settings);
|
||||
$this->team->notify(new Test(channel: 'telegram'));
|
||||
|
||||
// Send synchronously so that the user sees the error from Telegram (a queued test always "succeeds").
|
||||
$message = (new Test(channel: 'telegram'))->toTelegram();
|
||||
$response = (new SendMessageToTelegramJob(
|
||||
text: $message['message'],
|
||||
buttons: $message['buttons'],
|
||||
token: (string) $this->settings->telegram_token,
|
||||
chatId: (string) $this->settings->telegram_chat_id,
|
||||
))->sendMessage();
|
||||
|
||||
if ($response->failed()) {
|
||||
$reason = $response->json('description') ?? "HTTP {$response->status()}";
|
||||
$this->dispatch('error', 'Telegram rejected the test notification.', e($reason));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->dispatch('success', 'Test notification sent.');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Notifications\Telegram as TelegramNotification;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Livewire\Livewire;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
InstanceSettings::unguarded(fn () => InstanceSettings::updateOrCreate(['id' => 0], ['id' => 0]));
|
||||
|
||||
$this->team = Team::factory()->create();
|
||||
$this->team->telegramNotificationSettings->update([
|
||||
'telegram_enabled' => true,
|
||||
'telegram_token' => 'bot-token',
|
||||
'telegram_chat_id' => '123456',
|
||||
]);
|
||||
|
||||
$admin = User::factory()->create();
|
||||
$admin->teams()->attach($this->team, ['role' => 'admin']);
|
||||
$this->actingAs($admin);
|
||||
session(['currentTeam' => $this->team]);
|
||||
Queue::fake();
|
||||
});
|
||||
|
||||
it('shows the error from Telegram when the test notification is rejected', function () {
|
||||
Http::fake(['api.telegram.org/*' => Http::response(['ok' => false, 'description' => 'Bad Request: chat not found'], 400)]);
|
||||
|
||||
Livewire::test(TelegramNotification::class)
|
||||
->call('sendTestNotification')
|
||||
->assertDispatched('error', 'Telegram rejected the test notification.', 'Bad Request: chat not found')
|
||||
->assertNotDispatched('success');
|
||||
|
||||
Queue::assertNothingPushed();
|
||||
});
|
||||
|
||||
it('sends the test notification synchronously and reports success', function () {
|
||||
Http::fake(['api.telegram.org/*' => Http::response(['ok' => true, 'result' => []])]);
|
||||
|
||||
Livewire::test(TelegramNotification::class)
|
||||
->call('sendTestNotification')
|
||||
->assertDispatched('success', 'Test notification sent.');
|
||||
|
||||
Http::assertSent(fn ($request) => $request->url() === 'https://api.telegram.org/botbot-token/sendMessage'
|
||||
&& $request['chat_id'] === '123456');
|
||||
Queue::assertNothingPushed();
|
||||
});
|
||||
Reference in New Issue
Block a user