Zum Inhalt springen
Alle Artikel

Telegram-Benachrichtigungen für eine bestehende Laravel-Anwendung

16. Sept. 2026 · Automatisierung · 3 min

·Von Dimitri Pisarev

Telegram ist der preiswerteste brauchbare Notification-Channel, den eine Laravel-Anwendung hinzufügen kann: Bot registrieren, die Chat-ID jedes Empfängers speichern, und ein Queue-Job POSTet JSON an den sendMessage-Endpunkt. Ein SDK braucht es nicht, einen Webhook für reine Zustellung ebensowenig, und die dokumentierten Limits (rund 30 Nachrichten pro Sekunde insgesamt, eine pro Sekunde pro Chat) sind Queue-Probleme mit Queue-Lösungen.

Was brauchst du, bevor die erste Nachricht geht?#

Zwei Werte und ein Einwilligungsschritt:

  1. Ein Bot-Token von @BotFather: /newbot, sechzig Sekunden.
  2. Die Chat-ID des Empfängers. Eine Person öffnet den Bot und drückt Start; die ID kommt mit jedem Update (in der Entwicklung zeigt getUpdates sie direkt). Gruppen funktionieren genauso, ihre IDs sind negativ.
  3. Der Einwilligungsschritt ist der entscheidende: Ein Bot kann einem Nutzer nicht schreiben, der ihn nie gestartet hat. Telegram erzwingt das, und es ist ohnehin die richtige Voreinstellung. Chat-IDs sind opt-in personenbezogene Daten; speichere und behandle sie so.

Der Channel in einer Klasse#

Laravels Notification-System nimmt einen eigenen Channel in etwa einem Dutzend Zeilen:

class TelegramChannel
{
    public function send(object $notifiable, Notification $notification): void
    {
        $payload = $notification->toTelegram($notifiable);
 
        $response = Http::asJson()->post(
            'https://api.telegram.org/bot'.config('services.telegram.token').'/sendMessage',
            [
                'chat_id'              => $payload->chatId,
                'text'                 => $payload->text,
                'parse_mode'           => 'HTML',
                'link_preview_options' => ['is_disabled' => true],
            ],
        )->json();
 
        if (! ($response['ok'] ?? false)) {
            throw TelegramDelivery::failed($response['description'] ?? 'unknown error');
        }
    }
}

Die Notification deklariert den Channel in via(), das notifiable Model stellt routeNotificationForTelegram() bereit und liefert die gespeicherte Chat-ID, die Queue-Verbindung macht den Rest. Mit parse_mode: HTML ist Escaping eigene Aufgabe: Nutzerdaten durch htmlspecialchars(), sonst stirbt die Nachricht an der ersten spitzen Klammer in einem Stack Trace.

Rate-Limits sind eine Queue-Frage, keine Channel-Frage#

Die Bot-API-FAQ nennt die Zahlen: nicht mehr als eine Nachricht pro Sekunde an denselben Chat, unter etwa 30 pro Sekunde beim Broadcast. Verstöße kommen als HTTP 429 mit einem retry_after-Wert zurück. Dort gehört er hin: in die Queue.

// inside the queued job, on a 429 response
$this->release($response['parameters']['retry_after'] ?? 5);

Ein Report-Loop, der zweihundert Abonnenten benachrichtigt, sind zweihundert Queue-Jobs mit Jitter dazwischen, kein synchroner foreach. Dieselbe Disziplin gilt wie für jeden webhook-artigen Verkehr: Idempotente Worker, begrenzte Parallelität, ein Dead-Letter-Pfad, den ein Mensch tatsächlich liest.

Buttons machen aus Alarmen Workflows#

sendMessage nimmt ein InlineKeyboardMarkup. Ein Deploy-Hinweis mit Roll-back-Knopf, ein Bestellereignis mit Genehmigen und Ablehnen: Aus dem Zettel wird eine Aktion. URL-Buttons bleiben einwegig und brauchen keinen Webhook, ein Deep Link direkt ins Admin-Panel reicht oft.

Callback-Buttons sind eine andere Zusage: Die Drucke kommen als Callback-Queries an, der Bot braucht dann einen Webhook und einen idempotenten Handler. Ab dem Punkt baust du einen zweiseitigen Bot, und die Shop-Bot-Anatomie gilt, bevor man improvisiert.

Note

Die Nachrichtenlänge ist auf 4096 Zeichen begrenzt. Lange Reports bewusst im Code splitten oder kürzen. „Bad Request: message is too long“ von der API ist Kürzung durch Absturz, das schlechteste von beiden.

Wo das seinen Wert zeigt#

Ich route Betriebssignale kleiner Systeme in eine Telegram-Gruppe statt in ein Monitoring-Produkt: Queue-Tiefe, fehlgeschlagene Job-Spitzen, nächtliche Backups, Bestellereignisse. Das Gruppenarchiv wird eine durchsuchbare Incident-Timeline, Emoji-Reaktionen funktionieren als Acknowledgment, und das Team hat die App ohnehin installiert. Für ein kleines Team ist das ein gut ausgegebenes Observability-Budget. Nachrichten sind die Zustellungsebene, nicht die Auswertungsebene: Wenn Metriken wichtiger werden als Nachrichten, weiter zu echtem Tooling und Telegram als Pager behalten.