Das ist ein bekanntes Problem, und die übliche Antwort lautet „baue halt Backoff-Logik ein". Aber was, wenn du den Bot gar nicht brauchst? Was, wenn Push-Notifications ein HTTP-POST und sonst nichts sind?
Genau das ist ntfy.sh.
Nebenbei: Telegrams Bot API 10.2 ist gerade einmal zwei Wochen alt (14. Juli 2026) und bringt Rich Messages. Telegram entwickelt sein Bot-Ökosystem also weiter — für interaktive Workflows. Für reine Push-Alerts bleibt das aber irrelevant, und genau darum geht es hier.
Ausgangslage
Mein Watch-&-Alert-Setup läuft seit Anfang 2026 produktiv. Die Architektur ist im Buch ausführlich beschrieben, kurz zusammengefasst:
- Daten holen (Kapitel 9): 12 RSS-Feeds, 3 Google-News-Alerts, ein paar Webhook-Quellen
- Daten verstehen (Kapitel 11): LLM-Klassifikation über ein lokales Ollama-Setup, mit Fallback auf Cloud-Modelle
- Daten filtern (Kapitel 12): Dedup gegen SQLite, Threshold-basierte Reduktion auf „das ist neu und wichtig"
- Daten senden (Kapitel 13): Telegram-Bot, der die Treffer an einen privaten Channel postet
Im Schnitt kommen am Tag 8–15 Alerts durch. Harmlos. Aber dreimal pro Woche gibt es einen Spike — ein größeres CVE, ein Branchen-Event, eine Security-Advisory — und plötzlich sind es 30 Alerts in 90 Sekunden. Der Telegram-Bot bekommt 429, mein Skript loggt die Fehler, ich verpasse die wichtigen davon, weil sie in der Retry-Schleife verloren gehen.
Die Fehleranalyse war klar: nicht die Pipeline ist das Problem, sondern der Push-Kanal.
Anforderungen
Was ich von einem Push-Kanal für Watch-&-Alert-Setups erwarte:
- Kein Account-Setup. Ich will nicht erst einen BotFather-Dialog führen, einen Token generieren und in einer
.envablegen. - Keine Token-Rotation. Telegram-Tokens sind sicherheitskritisch, rotieren regelmäßig, und jede Rotation ist ein Wartungs-Schritt, der schiefgehen kann.
- Keine Rate-Limits im Normalbetrieb. Bei einem Spike sollen alle Alerts ankommen, nicht 80% davon.
- Self-Hosting-Option. Ich will nicht von einem Drittanbieter abhängig sein, der morgen seine Preise ändert oder sein Angebot einstellt.
- Einfache HTTP-API. Mein Watch-&-Alert-Skript spricht schon HTTP — es soll nicht lernen, mit einem SDK zu telefonieren.
- Push auf das Handy. Ich will Alerts unterwegs sehen, nicht nur auf dem Server-Log.
Telegram erfüllt einige davon, aber nicht alle. ntfy.sh erfüllt alle.
Drei Optionen im Vergleich
Option 1: Telegram-Bot (wie bisher)
Telegram-Bots sind mächtig. Commands, Inline-Keyboards, interaktive Workflows — wenn du einen Chatbot bauen willst, ist die Telegram-Bot-API das beste verfügbare Ökosystem. Mein Setup nutzt python-telegram-bot als Library.
Aber für reine Push-Alerts ist das Overkill:
- Du brauchst einen Telegram-Account.
- Du brauchst einen Dialog mit @BotFather zur Bot-Erstellung.
- Du brauchst ein Token, das du sicher speichern und regelmäßig rotieren musst.
- Du brauchst eine Server-URL, wenn du Webhooks nutzt (oder Long Polling, das dein Skript offenhält).
- Du bist auf 30 Messages pro Sekunde global limitiert (core.telegram.org/bots/faq) — alles darüber gibt 429.
- Die Nachrichten laufen durch Telegrams Infrastruktur — Vertrauensfrage.
Für mein Watch-&-Alert-Setup ist die Bilanz negativ. Ich nutze Telegram nicht als Chatbot, sondern als reinen Push-Kanal. Dafür ist es zu teuer im Aufwand.
Option 2: ntfy.sh Cloud
ntfy.sh ist ein HTTP-basierter Pub/Sub-Service für Push-Notifications. Der Name steht für „notify". Das Konzept:
- Du wählst einen Topic-Namen — zum Beispiel
stephan-watch-alert-7k9x-mn4p-q2vr. - Du abonnierst den Topic in der ntfy-App auf deinem Handy (Android, iOS, Desktop).
- Du sendest Nachrichten per
POSToderPUTanhttps://ntfy.sh/<topic>. - Fertig. Die Nachricht kommt als Push-Notification an.
Kein Account, kein Token, kein Server. Topics müssen nicht explizit erstellt werden — der erste POST erzeugt sie. Die App speichert eine History der letzten Nachrichten.
Vorteile:
- Setup in 2 Minuten. Topic-Name wählen, App installieren, ersten POST absetzen.
- Keine Rate-Limits im Normalbetrieb. Bei Spikes gibt es keine 429er. ntfy.sh skaliert Cloud-seitig.
- Keine Server-Pflicht. Wenn du die Cloud-Variante nutzt, läuft alles auf der Infrastruktur von ntfy.sh.
- E2E-Verschlüsselung möglich. Topics können mit einem Topic-Passwort verschlüsselt werden.
Nachteile:
- Cloud-Abhängigkeit. Wenn ntfy.sh ausfällt, kommen keine Alerts. Für nicht-zeitkritische Watch-&-Alert-Setups ist das OK.
- Topic-Namen sind öffentlich. Wenn du
stephan-alertsals Topic nimmst, kann jeder mit dem Namen POSTen. Die Lösung: lange, zufällige Topic-Namen wiestephan-watch-alert-7k9x-mn4p-q2vr. - Keine Commands. Reine Push-Notifications, keine interaktiven Buttons.
Option 3: ntfy.sh self-hosted
Wenn du die Cloud-Variante nicht vertrauen willst (oder aus Compliance-Gründen nicht nutzen darfst): ntfy.sh lässt sich komplett self-hosten. Ein einzelnes Docker-Container-Image oder ein Go-Binary reicht.
docker run -d \
--name ntfy \
-p 2586:80 \
-v /var/cache/ntfy:/var/cache/ntfy \
-v /etc/ntfy:/etc/ntfy \
binwiederhier/ntfy serve
Die Konfiguration ist eine einzelne server.yml mit Theme, Authentifizierung, Rate-Limits und Retention-Policies. Für Watch-&-Alert-Setups reicht die Default-Konfiguration; ACLs kommen erst ins Spiel, wenn mehrere User denselben Server nutzen.
Self-Hosting-Vorteile:
- Volle Datenkontrolle. Alerts verlassen dein Netzwerk nicht.
- Keine Abhängigkeit von ntfy.sh-Cloud.
- Beliebig erweiterbar — E2E-Verschlüsselung ist optional, Attachments funktionieren, Webhooks für Quellen-Integration.
Self-Hosting-Nachteile:
- Du bist für Uptime verantwortlich. Wenn dein Heim-Server nachts ausfällt, bekommst du keine Alerts über den ausgefallenen Service — direkt aus.
- TLS-Zertifikate brauchst du trotzdem, damit die Mobile-App funktioniert (Let's Encrypt über Caddy oder nginx).
Die Migration
Mein Migrationspfad vom Telegram-Bot zu ntfy.sh war erstaunlich kurz. Hier die Schritte:
Schritt 1 — Topic wählen und App installieren
Der Topic-Name sollte lang, zufällig und nicht ratbar sein. Ich nutze:
stephan-watch-alert-7k9x-mn4p-q2vr
In der ntfy-App (Android, iOS oder Web-App) auf „Subscribe topic" klicken, Namen eingeben, fertig.
Schritt 2 — Test-Nachricht senden
curl -d "Watch-&-Alert-Test: Pipeline läuft" \
https://ntfy.sh/stephan-watch-alert-7k9x-mn4p-q2vr
Wenn die Push-Notification auf dem Handy ankommt, ist die Verbindung live.
Schritt 3 — Python-Integration im Watch-&-Alert-Skript
Mein bisheriger Telegram-Versand sah so aus (gekürzt, aus Kapitel 13 des Buches):
import telegram
bot = telegram.Bot(token=os.environ["TELEGRAM_BOT_TOKEN"])
def send_alert(message: str) -> None:
bot.send_message(
chat_id=os.environ["TELEGRAM_CHAT_ID"],
text=message,
parse_mode=telegram.ParseMode.MARKDOWN,
)
Die ntfy-Integration ersetzt das durch einen einzigen HTTP-POST:
import requests
def send_alert(message: str, *, priority: int = 3) -> None:
requests.post(
f"https://ntfy.sh/{os.environ['NTFY_TOPIC']}",
data=message.encode("utf-8"),
headers={
"Title": "Watch & Alert",
"Priority": str(priority),
"Tags": "warning",
},
timeout=5,
)
Keine SDK-Abhängigkeit, keine Authentifizierung außer dem geheimen Topic-Namen. Die requests-Library ist sowieso schon im Projekt.
Schritt 4 — Prioritäten nutzen
ntfy.sh unterstützt fünf Prioritätsstufen:
| Priorität | Bedeutung | Wann ich sie nutze |
|---|---|---|
| 1 (min) | Stille Notification | Heartbeat-„alles OK"-Meldungen |
| 3 (default) | Normale Notification | Standard-Alerts |
| 4 (high) | Sound + Vibration | Wichtige Alerts, die sofort gesehen werden sollen |
| 5 (urgent) | Sound + Vibration + Vollbild | Kritische Alerts (CVE betrifft eigene Infrastruktur) |
In meinem Watch-&-Alert-Setup bekommen Sicherheits-relevante Treffer priority=5, Branchen-News priority=3, tägliche Heartbeats priority=1. Die Telegram-Variante hatte das nicht — dort waren alle Alerts gleich sichtbar.
Schritt 5 — Fallback auf Telegram behalten
ntfy.sh ist mein primärer Push-Kanal. Aber für interaktive Anwendungsfälle (ein Watch-Bot, der per /pause stumm geschaltet werden kann) bleibt Telegram im Spiel. Mein Watch-&-Alert-Setup prüft beide Kanäle:
def send_alert(message: str, *, priority: int = 3) -> None:
send_via_ntfy(message, priority=priority)
if priority >= 4:
send_via_telegram(message)
Kritische Alerts gehen auf beide Kanäle — ntfy für die Geschwindigkeit, Telegram für die Commands.
Was wir dabei gelernt haben
Drei Erkenntnisse aus der produktiven Nutzung seit drei Monaten:
Erkenntnis 1: Topic-Namen sind API-Keys.
Wer deinen Topic-Namen kennt, kann POSTen. Also: nicht stephan-alerts, sondern stephan-watch-alert-7k9x-mn4p-q2vr. Lange, zufällige Namen wie ein Passwort behandeln.
Erkenntnis 2: Push ist nicht gleich Push.
Telegram-Bots sind für Chat-Workflows gebaut. ntfy.sh ist für Maschine-zu-Mensch-Push. Wenn dein Use Case nur „Server soll mich informieren" ist, ist ntfy.sh das bessere Werkzeug — nicht weil Telegram schlecht ist, sondern weil du einen Hammer benutzt hast, wo ein Schraubendreher reicht.
Erkenntnis 3: Self-Hosting ist billiger als gedacht.
Ein einzelner ntfy-Container auf einem Raspberry Pi 4 reicht für ein Dutzend Datenquellen. Die einzige wirkliche Komplexität ist TLS — aber die ist mit Caddy in zehn Minuten erledigt.
Erkenntnis 4: Überwache die Push-Pipeline selbst.
Ein Push-Kanal, der ausfällt, ohne dass du es merkst, ist schlimmer als gar kein Push-Kanal. Wir senden seit der Migration einmal pro Stunde eine Heartbeat-Nachricht mit niedrigster Priorität (priority=1) auf einen separaten Topic. Wenn der Heartbeat ausbleibt, weiß das Watch-&-Alert-System, dass ntfy.sh selbst nicht erreichbar ist — und schaltet automatisch auf den Telegram-Fallback um.
Erkenntnis 5: Topic-Namen sind nicht wiederherstellbar.
Wenn du deinen geheimen Topic-Namen verlierst, ist der Topic für immer weg. ntfy.sh hat keine Account-Bindung, also gibt es keinen Wiederherstellungs-Weg. Wir speichern den Topic-Namen deshalb an drei Stellen: in der Watch-&-Alert-Pipeline (.env), im Passwort-Safe (GPG-verschlüsselt), und in einem ausgedruckten Notfall-Zettel im Server-Schrank. Drei Stellen klingt paranoid, aber genau das ist das Sicherheitsniveau, das ein Push-Kanal für sicherheitsrelevante Watch-Systeme verdient.
Bezug zum Buch
Das Buch Watch & Alert behandelt in Kapitel 13 drei Push-Kanäle für Watch-Systeme: Telegram-Bots, ntfy.sh und E-Mail via SMTP/IMAP. Der Telegram-Abschnitt ist ausführlich, weil das SDK mächtig ist und viele Beispiele existieren. Der ntfy-Abschnitt ist kürzer, weil die API trivial ist — ein POST-Request, fertig.
Dieser Artikel ergänzt das Buch an einer Stelle, die im Kapitel nur angerissen wird: den konkreten Migrationspfad aus einem produktiven Setup. Wenn du nach dem Buch ntfy.sh selbst produktiv einsetzen willst, ist die hier gezeigte Architektur (Hybrid: ntfy für Push, Telegram für Commands) der Pfad, den ich empfehlen würde.
Mehr zur Watch-&-Alert-Pipeline-Architektur findest du in Kapitel 12 (Daten filtern) und Kapitel 13 (Daten senden) des Buches.
Wann du das nachbauen solltest — und wann nicht
ntfy.sh statt Telegram ist das Richtige für dich, wenn:
- du mehrere Datenquellen hast und Spikes möglich sind
- du keinen interaktiven Chatbot brauchst, sondern nur Push
- du einen geheimen Topic-Namen sicher speichern kannst (in einer
.envoder im Passwort-Safe) - du bereit bist, im Worst-Case auf eine Cloud-Variante zurückzugreifen
Bleib bei Telegram, wenn:
- du Commands brauchst (
/pause,/status,/mute-source xyz) - du Inline-Keyboards für interaktive Workflows nutzt
- deine Alerts in einen bestehenden Telegram-Channel fließen sollen, der nicht nur dir gehört
- du bereits eine Telegram-Bot-Infrastruktur hast, die funktioniert
Für ein reines Watch-&-Alert-Setup ohne Interaktion ist ntfy.sh die ehrlichere Lösung: weniger Code, weniger Infrastruktur, weniger Limits.
Nächste Schritte für dich:
- Topic-Namen generieren und in der App abonnieren.
- Test-CURL abschicken.
requests.post()in dein Watch-&-Alert-Skript einbauen.- Eine Woche lang parallel zu Telegram laufen lassen.
- Wenn keine 429er mehr — Telegram abschalten.
Der vollständige Code und die Test-Strategie für Watch-Systeme sind im Buch in Kapitel 13 und Kapitel 16 beschrieben.