onQueue('high'); } /** * Execute the job. */ public function handle(): void { $response = $this->sendMessage(); // 401: invalid bot token, 404: malformed 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, 404], 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 { // Pasted values often keep a space or new line. In the URL it gives a malformed token, so Telegram answers 404. $url = 'https://api.telegram.org/bot'.trim($this->token).'/sendMessage'; $inlineButtons = []; if (! empty($this->buttons)) { foreach ($this->buttons as $button) { $buttonUrl = data_get($button, 'url'); $text = data_get($button, 'text', 'Click here'); if ($buttonUrl && Str::contains($buttonUrl, 'http://localhost')) { $buttonUrl = str_replace('http://localhost', config('app.url'), $buttonUrl); } $inlineButtons[] = [ 'text' => $text, 'url' => $buttonUrl, ]; } } $payload = [ 'chat_id' => trim($this->chatId), 'text' => $this->text, ]; if ($this->threadId) { $payload['message_thread_id'] = $this->threadId; } $response = $this->sendNotificationRequest('Telegram', $url, fn () => Http::post($url, [ ...$payload, 'reply_markup' => json_encode(['inline_keyboard' => [$inlineButtons]]), ])); // Telegram rejects the whole message when it cannot open a button URL (for example localhost or an IP address without a domain). if ($inlineButtons !== [] && $response->status() === 400 && Str::contains((string) $response->json('description'), ['button url', 'button_url'], true)) { $links = collect($inlineButtons)->map(fn (array $button) => "{$button['text']}: {$button['url']}")->implode("\n"); $response = $this->sendNotificationRequest('Telegram', $url, fn () => Http::post($url, [ ...$payload, 'text' => "{$this->text}\n\n{$links}", ])); } return $response; } }