Hermes-Webhooks anbinden: Business-Systeme pushen Alerts an Telegram, Discord und Slack

Die meisten Business-Systeme brauchen irgendwann dieselbe Automatisierung: Wenn sich ein Bestellstatus ändert, eine Zahlung erfolgreich ist, ein Monitor anschlägt oder eine CI-Pipeline fertig wird, soll eine Nachricht in einem Team-Kanal landen. Die schnellste erste Version ist meist ein Skript, das eine Datenbank oder API pollt und die Nachricht dann in Telegram, Discord, Slack oder einer anderen Chat-Plattform abwirft.
Polling funktioniert, hat aber echte langfristige Kosten:
- Latenz und API-Quota. Wenn du jede Minute abfragst, liefern die meisten Requests nichts; ein Wechsel auf Sekunden-Takt multipliziert API-Last und Kosten.
- Kopplung. Das Business-System wird mit Message-Templates und Chat-Plattform-Tokens hart verdrahtet. Ein Kanal- oder Gruppenwechsel erfordert eine Codeänderung.
- Erweiterbarkeit. Derselbe Alert muss vielleicht an Telegram, Slack oder erst von einer KI zusammengefasst werden. Polling-Skripte werden schnell komplex.
Hermes Agent bringt eine Webhook-Plattform mit – einen HTTP-Event-Receiver. Dein Business-System POSTet ein Event, Hermes validiert die Signatur, rendert ein Template und pusht die Nachricht an die Chat-Plattform, die du konfiguriert hast. Ist das Event eine reine Benachrichtigung ohne KI-Logik, kannst du den Direct-Delivery-Modus aktivieren: kein LLM-Aufruf, keine Agent-Schleife, Zustellung in unter einer Sekunde und keine Token-Kosten.
Dieser Beitrag ist ein praktischer Leitfaden, um Business-Systeme an Hermes-Webhooks anzubinden: Plattform aktivieren, Routes konfigurieren, drei vollständige Praxis-Szenarien und Security-Härtung.
Zwei Modi: Agent-Verarbeitung vs. Direct Delivery
Hermes-Webhooks unterstützen zwei Zustellpfade. Die richtige Wahl zu treffen, ist entscheidend.
| Modus | Ruft das LLM auf? | Am besten für | Latenz | Kosten |
|---|---|---|---|---|
| Agent-Verarbeitung | Ja | Events, die Verständnis, Zusammenfassung oder eine Entscheidung brauchen, bevor geantwortet oder weitergeleitet wird | Sekunden | Token-Kosten |
| Direct Delivery | Nein | Reine Benachrichtigungen: Bestellungen, Zahlungen, Alerts, CI-Status | Unter einer Sekunde | Keine LLM-Kosten |
Hier steht Direct Delivery im Fokus. Der Ablauf ist einfach:
- Das Business-System signiert und POSTet ein JSON-Payload an
https://your-server:8644/webhooks/<route-name>. - Hermes validiert die HMAC-Signatur, um zu bestätigen, dass der Absender vertrauenswürdig ist.
- Ein Template rendert die JSON-Felder zu einer lesbaren Nachricht.
- Die Nachricht wird direkt an Telegram, Discord, Slack, Feishu usw. zugestellt, und Hermes antwortet mit
200 OK.
Es ist kein LLM beteiligt, daher liegen Geschwindigkeit, Kosten und Zuverlässigkeit näher an einem klassischen Message-Gateway – Konfiguration und Erweiterbarkeit bleiben aber so flexibel wie der Rest von Hermes.
Schritt 1: Die Webhook-Plattform aktivieren
Du kannst Webhooks für einen schnellen Start über Umgebungsvariablen oder für langfristige Deployments über config.yaml aktivieren.
Umgebungsvariablen (am schnellsten)
Füge diese Zeilen zu ~/.hermes/.env hinzu:
WEBHOOK_ENABLED=true
WEBHOOK_PORT=8644 # default
WEBHOOK_SECRET=your-global-secret
Starte das Gateway neu:
hermes gateway restart
Prüfe, ob der Server lauscht:
curl http://localhost:8644/health
Eine Antwort von {"status": "ok", "platform": "webhook"} bedeutet, dass er läuft.
Config-Datei (für die Produktion empfohlen)
Deklariere den Block platforms.webhook in ~/.hermes/config.yaml:
platforms:
webhook:
enabled: true
extra:
port: 8644
secret: "your-global-secret"
Nach dem Neustart des Gateways lauscht Hermes auf Port 8644. Steht der Server im öffentlichen Internet, stelle sicher, dass die Firewall diesen Port erlaubt. Steht er hinter NAT oder hat keine öffentliche IP, exponiere ihn über einen Cloudflare Tunnel oder ngrok.
Schritt 2: Eine Business-Notification-Route konfigurieren
Routes liegen unter platforms.webhook.extra.routes. Jede Route hat einen Namen, einen Event-Filter, ein Secret, ein Message-Template und ein Zustellziel. Unten siehst du ein vollständiges E-Commerce-Bestellbenachrichtigungs-Beispiel, das neue Bestellungen an Telegram pusht.
platforms:
webhook:
enabled: true
extra:
port: 8644
secret: "global-fallback-secret"
routes:
order-notify:
events: ["order.created"]
secret: "shopify-webhook-secret"
prompt: |
🛒 New order #{order.id}
Amount: {order.total_price} {order.currency}
Customer: {order.customer.email}
Item: {order.line_items[0].title}
deliver: "telegram"
deliver_only: true
deliver_extra:
chat_id: "-1001234567890"
Die wichtigsten Punkte:
eventsist optional. Wenn dein Business-System einen Event-Typ überX-Webhook-Eventoderevent_typesendet, kannst du die Route auforder.createdbeschränken.secretwird für die HMAC-Signaturvalidierung verwendet. Hat die Route kein Secret, fällt sie auf das globalesecretzurück.deliver_only: trueaktiviert Direct Delivery und überspringt das LLM.promptist ein Template. Verwende Punktnotation wie{order.total_price}, um auf JSON-Felder zuzugreifen.{__raw__}gibt das gesamte Payload aus.deliver_extra.chat_idzielt auf eine bestimmte Gruppe. Fehlt der Wert, liefert Hermes an den konfigurierten Home-Channel der Plattform (dafür muss die Plattform aktiviert und verbunden sein).
Schritt 3: Events aus deinem Business-System senden
Dein Business-System POSTet an die richtige URL. Für das obige Beispiel:
POST https://your-server:8644/webhooks/order-notify
Verwende Generic-V2-Signing: Verkette timestamp.body, berechne HMAC-SHA256 und sende das Ergebnis im Header X-Webhook-Signature-V2 zusammen mit X-Webhook-Timestamp. Das Zeitfenster beträgt ±300 Sekunden, wodurch Replay-Angriffe blockiert werden.
import hmac
import hashlib
import time
import json
import requests
secret = b"shopify-webhook-secret"
body = json.dumps({
"event_type": "order.created",
"order": {
"id": 10086,
"total_price": "199.00",
"currency": "USD",
"customer": {"email": "[email protected]"},
"line_items": [{"title": "Hermes sticker pack"}]
}
}).encode()
timestamp = str(int(time.time()))
signature = hmac.new(secret, f"{timestamp}.{body.decode()}".encode(), hashlib.sha256).hexdigest()
requests.post(
"https://your-server:8644/webhooks/order-notify",
data=body,
headers={
"Content-Type": "application/json",
"X-Webhook-Signature-V2": signature,
"X-Webhook-Timestamp": timestamp,
}
)
GitHub- und GitLab-Signaturen werden ebenfalls automatisch erkannt. Für eigene Business-Systeme bevorzuge Generic V2.
Schritt 4: Die Route testen
Du musst nicht warten, bis das Business-System live geht. Teste zuerst lokal:
hermes webhook test order-notify \
--payload '{"event_type":"order.created","order":{"id":10086,"total_price":"199.00","currency":"USD","customer":{"email":"[email protected]"},"line_items":[{"title":"Hermes sticker pack"}]}}'
hermes webhook test simuliert einen POST, damit du Template-Rendering und Zustellung verifizieren kannst. Kommt die Nachricht nicht an, prüfe gateway.log oder starte hermes gateway run im Vordergrund, um zu sehen, ob die Signatur fehlgeschlagen ist, das Event gefiltert wurde oder das Zustellziel nicht verbunden ist.
Szenario 1: E-Commerce-Bestellbenachrichtigungen → Telegram
Das Beispiel order-notify oben ist bereits vollständig. Ein paar Details, die hervorgehoben werden sollten:
chat_id-Werte von Telegram-Gruppen sind in der Regel negativ und beginnen mit-100.- Um ein bestimmtes Forum-Thema anzusprechen, füge
message_thread_id: "42"indeliver_extrahinzu. {order.line_items[0].title}zeigt nur den ersten Artikel. Um alles aufzulisten, verarbeite das Payload entweder im Business-System vor oder nutze den Agent-Modus mit{__raw__}und lass das LLM zusammenfassen.
Szenario 2: Zahlungserfolg → Discord
Zahlungssysteme wie Stripe senden bereits Webhooks. Binde das Erfolgs-Event von Stripe an eine Discord-Nachricht:
routes:
payment-success:
events: ["payment_intent.succeeded"]
secret: "stripe-webhook-secret"
prompt: |
💰 Payment received: {amount} {currency}
Order: {metadata.order_id}
Customer: {receipt_email}
deliver: "discord"
deliver_only: true
deliver_extra:
chat_id: "123456789012345678"
Stripe sendet type statt event_type. Wenn Hermes den Event-Header nicht erkennt, wickle das Payload entweder in deinem Business-System ein oder lass events leer und verwende filters:
routes:
payment-success:
secret: "stripe-webhook-secret"
filters:
- field: "type"
equals: "payment_intent.succeeded"
prompt: "..."
deliver: "discord"
deliver_only: true
Szenario 3: Monitoring-Alerts → Slack
Grafana, Datadog oder jedes eigene Monitor-System kann Alerts senden. Pushe nur kritische Alerts an Slack:
routes:
critical-alert:
events: ["alert"]
secret: "monitoring-webhook-secret"
filters:
- field: "severity"
equals: "critical"
prompt: |
🚨 Critical alert
Service: {service}
Metric: {metric}
Current value: {current_value}
Threshold: {threshold}
deliver: "slack"
deliver_only: true
deliver_extra:
chat_id: "your-slack-channel-id"
Slack muss im Gateway aktiviert und verbunden sein. Wenn du Slack nur für Webhook-Benachrichtigungen nutzt, brauchst du es nicht als primäre Chat-Plattform; konfiguriere einfach platforms.slack mit einem Home-Channel oder gib die chat_id in deliver_extra an.
Fortgeschritten: Payloads mit Skripten filtern und transformieren
Wenn das JSON des Business-Systems unübersichtlich ist oder du nur unter bestimmten Bedingungen benachrichtigen willst, schreibe ein Vorverarbeitungsskript. Skripte müssen unter ~/.hermes/scripts/ liegen; relative Pfade werden dort aufgelöst.
# ~/.hermes/scripts/alert-filter.py
import json
import sys
payload = json.load(sys.stdin)
if payload.get("severity") != "critical":
print("[SILENT]")
raise SystemExit(0)
payload["body"] = f"{payload['service']} critical: {payload['metric']}"
print(json.dumps(payload))
Referenziere es in der Route:
routes:
critical-alert:
events: ["alert"]
secret: "monitoring-webhook-secret"
script: "alert-filter.py"
prompt: "{body}"
deliver: "slack"
deliver_only: true
JSON-Stdout ersetzt das Payload; reiner Text-Stdout wird als script_output injiziert; leere Ausgabe oder [SILENT] führt dazu, dass Hermes den Webhook ignoriert.
Sicherheit: Verlass dich nicht allein auf HMAC
HMAC beweist, dass der Absender vertrauenswürdig ist – nicht, dass der Inhalt des Payloads sicher ist. PR-Titel, Issue-Bodies, Bestellnotizen und Alert-Nachrichten stammen von Dritten und könnten injizierte Anweisungen enthalten. Also:
- Isoliere die Laufzeit. Ist der Webhook im Internet exponiert, betreibe das Gateway mit einem Docker- oder SSH-Terminal-Backend; exponiere den Host nicht direkt gegenüber Events.
- Direct Delivery ist von Natur aus sicherer. Da es das LLM überspringt, gibt es kein Prompt-Injection-Risiko, das Agent-Aktionen auslösen könnte.
- Begrenze das Toolset. Muss eine Route in den Agent-Modus, deaktiviere gefährliche Tools wie
terminalundfilefür diese Route. - Lass Approvals aktiviert. Wenn der webhook-ausgelöste Agent Befehle ausführen soll, lass die Freigaben aktiviert, damit injizierte Anweisungen nicht unbeaufsichtigt ausgeführt werden können.
- Templating eng halten. Vermeide den Missbrauch von
{__raw__}; nimm inpromptnur die Felder auf, die du brauchst.
Hermes bringt außerdem Guardrails mit: standardmäßig 30 Requests pro Minute pro Route, ein Body-Limit von 1 MB und ein 1-Stunden-Idempotenz-Cache. Diese Standardwerte reichen für die meisten Benachrichtigungen, du kannst sie aber in extra anpassen:
extra:
rate_limit: 60
max_body_bytes: 2097152
Troubleshooting-Checkliste
| Symptom | Wahrscheinliche Ursache | Was du prüfen solltest |
|---|---|---|
| POST des Business-Systems schlägt fehl | Port/Firewall nicht geöffnet | curl http://your-server:8644/health |
| 401 Unauthorized | Signatur stimmt nicht | Prüfe Secret und HMAC-Algorithmus; lies die Gateway-Logs |
| 200 OK, aber keine Nachricht | Event-Typ passt nicht | Prüfe die events-Liste und das Feld event_type |
| Doppelte Nachrichten | Retries + verfehlte Idempotenz | Stelle sicher, dass der Absender X-Request-ID oder X-GitHub-Delivery sendet |
| Template-Variablen nicht expandiert | Falsche Feldnamen | Iteriere mit hermes webhook test |
Dynamische Subscriptions vs. Config-Datei-Routes
Neben statischen Routes in config.yaml kannst du Subscriptions auch dynamisch per CLI anlegen:
hermes webhook subscribe order-notify \
--events "order.created" \
--prompt "New order #{order.id}, amount {order.total_price} {order.currency}" \
--deliver telegram \
--deliver-chat-id "-1001234567890" \
--deliver-only \
--description "E-commerce order notifications"
Dynamische Subscriptions werden in ~/.hermes/webhook_subscriptions.json gespeichert und vom Gateway heiß nachgeladen – kein Neustart erforderlich. Statische Routes mit demselben Namen haben Vorrang. Die vollständige Befehlsreferenz findest du auf unserer hermes webhook-Befehlsseite.
Zusammenfassung
Die Webhook-Plattform von Hermes ist kein Chatbot; sie ist ein eventgesteuerter Message-Router. Für Business-Systeme liegt ihr Hauptwert darin:
- Polling in Push zu verwandeln, API-Quota zu sparen und Latenz zu senken.
- Message-Templates und Zustellziele in Hermes zu zentralisieren, sodass ein Wechsel der Chat-Plattform oder Gruppe keinen Business-System-Deploy erfordert.
- Den Direct-Delivery-Modus für Token-freie Benachrichtigungen in unter einer Sekunde.
Wenn du Hermes bereits für tägliche Aufgaben nutzt, ist ein zusätzlicher Webhook-Endpoint fast kostenlos: Das Gateway läuft ohnehin schon – es lauscht nur auf einem weiteren Port. Deine Business-Systeme können proaktiv sprechen, und du entscheidest, was sie sagen und wo.
Neu bei Hermes? Starte mit dem Installations-Leitfaden. Die vollständige Webhook-Befehlsreferenz findest du auf der hermes webhook-Befehlsseite. Wenn du dich für eventgesteuerte Automatisierung interessierst, lies auch unseren Cron-Skript-Only-Leitfaden und den Yolo-Modus-Erklärer.