Notify Gateway
Go-Gateway mit ntfy-, Gotify-, Webhook-, IMAP- und Discord-Eingängen. Regeln verteilen Nachrichten über eine persistente Outbox an Divera247, Discord, HTTP-Webhooks, SMTP, ntfy und Gotify.
Stand: 0.1.0-alpha.5 – mit SQLite-Outbox, Wiederholungen, Deduplizierung und Zustellhistorie. Standardmäßig ist divera.dry_run=true; zusätzliche Ausgänge starten mit live=false.
Ausgänge einrichten
- Unter Ausgänge einen Ausgang anlegen: Name, eindeutige ID, Provider und dessen Verbindungsdaten.
- Unter Zuordnungen als Ziel Discord, HTTP-Webhook, SMTP, ntfy oder Gotify und den Ausgang wählen. Quelle, Filter und Titel-/Text-Templates konfigurieren.
- Mit Regel prüfen das Payload ansehen, anschließend speichern. Eingehende Testmeldungen erzeugen im Dry-Run ein Ergebnis ohne Netzwerkversand.
- Für echten Versand Live-Versand aktivieren am jeweiligen Ausgang einschalten und speichern. Dieser Schalter ist unabhängig von
divera.dry_run.
Mehrere passende Regeln erzeugen unabhängige Zustellaufträge. HTTP-Eingänge antworten nach Speicherung mit 202 Accepted und einer Referenz. Mit Idempotency-Key lassen sich Wiederholungen derselben Nachricht deduplizieren. Temporäre Versandfehler werden bis zu achtmal versucht; erfolgreiche Ziele werden dabei nicht erneut versendet. Status und manuelle Wiederholung stehen unter Zustellhistorie bereit.
Discord sendet Titel und Meldung, getrennt durch einen Zeilenumbruch, als Text. Leere Texte und Inhalte über 2000 UTF-16-Codeeinheiten werden abgelehnt, Mentions sind deaktiviert. Der Adapter verwendet wait=true für eine bestätigte API-Antwort. Siehe Discord-Webhooks.
HTTP-Webhooks erhalten per POST JSON mit source, channel, title, message, address, priority, tags und received_at. Raw-Eingangsdaten und Divera247-Extras werden nicht automatisch weitergegeben. Weiterleitungen werden blockiert. Die neuen Ausgänge liefern keine Remote-Antworttexte oder Ziel-URLs an den Eingang zurück.
Beispiele stehen in config.example.json. Bestehende Konfigurationen bleiben verwendbar; beim Start entsteht zusätzlich outbox.db daneben. Einrichtung von SMTP/IMAP und Discord, Zustellgarantien, Metriken und Backups: OPERATIONS.md. Ausbauplan: PROVIDER_PLAN.md.
Bereits enthalten
- Go 1.23+, SQLite ohne CGO, IMAP/MIME und bcrypt als versionierte Go-Abhängigkeiten.
- Persistente, atomar geschriebene JSON-Konfiguration (
0600). - Admin-WebUI mit Session-Login, formularbasierter Konfiguration, Passwortwechsel, Divera247-Verbindungstest und Stammdaten-Auswahl.
- Eingangs-Authentifizierung per Bearer-Token, ntfy-kompatiblem Basic-Auth-Passwort bzw. Gotify-
token/X-Gotify-Key. - ntfy-Publish als Text, JSON und GET-Trigger (
trigger,send,publish). - Gotify-kompatibler
POST /message?token=...sowie/in/gotify/message. - Generischer
POST/PUT /in/webhook/{channel}für JSON, Formular- oder Text-Payloads. - Regel-Engine mit Quelle, Kanal-, Titel- und Meldungs-Regex sowie Mindestpriorität; Regeln werden in der WebUI grafisch bearbeitet und können per Payload-Vorschau getestet werden.
- Mapping auf Divera247 Alarm, Mitteilung (News) oder Termin (Event), inkl. Stichwort, Meldung, Ort, Empfänger-Typ, Einheit(en), Gruppen, Personen, Fahrzeuge und Versandwege. Einheitsübergreifende Zuordnungen können pro Einheit die Empfängerart Alle/Gruppen/Personen setzen.
- Freies
extra-Objekt je Mapping, um zusätzliche Divera247-Felder ohne Codeänderung zu übergeben. - Divera247-v2-Client für CRUD, Archivieren, Lesen, Rückmeldungen, Reichweite, Downloads, Anhänge, Alarm schließen, Event-ICS und Pull-Daten. Zusätzlich steht ein generischer Request-Pfad für noch nicht typisierte API-Funktionen bereit.
- Dockerfile, Compose-Beispiel und Unit-Tests.
Start
export GATEWAY_ADMIN_PASSWORD='ein-langes-einmaliges-passwort'
go run ./cmd/gateway -config ./data/config.json
Danach: http://localhost:8080/ui/. Wenn beim ersten Start kein GATEWAY_ADMIN_PASSWORD gesetzt ist, erzeugt das Gateway einmalig ein Admin-Passwort und schreibt es ins Start-Log.
Die automatisch erzeugte Konfiguration startet mit divera.dry_run=true. Erst nach Eintragen des Divera247-Accesskeys und einem erfolgreichen Test sollte Dry-Run deaktiviert werden.
WebUI
Die WebUI unter http://localhost:8080/ui/ ist in Bereiche für Divera247, Eingänge, Zuordnungen sowie Server & Sicherheit gegliedert. Die Konfiguration erfolgt über Formulare; ein direkter JSON-Editor ist für den normalen Betrieb nicht mehr nötig.
Unter Divera247 können Accesskey, UCR, Timeout und Dry-Run gepflegt werden. Die Stammdaten werden primär über die stabile v2-Schnittstelle pull/all geladen. Für PRO-/Mehrfacheinheiten wertet das Gateway data.ucr aus und lädt jede erreichbare User-Cluster-Relation separat; Benutzer werden aus data.cluster.consumer übernommen, wobei der numerische Collection-Key als UCR-ID für gezielte Alarmempfänger erhalten bleibt. Der v3-Endpunkt user-cluster-relations dient nur noch als Fallback, falls v2 keine Personen liefert. Die Stammdaten stehen anschließend in Zuordnungsregeln als Such- und Auswahlfelder zur Verfügung. Die Regelvorschau zeigt das resultierende Divera247-Payload, ohne es zu versenden.
Beispiel: ntfy -> Divera247 Alarm
In der WebUI oder in config.json ein Mapping aktivieren und z. B. einen Token für Topic alarm setzen. Anschließend:
curl -X POST \
-H 'Authorization: Bearer replace-me' \
-H 'Title: FEUER3' \
-H 'Priority: high' \
--data 'Unklare Rauchentwicklung' \
http://localhost:8080/ntfy/alarm
JSON-Publish ist unter /ntfy oder /in/ntfy möglich:
curl -X POST -H 'Authorization: Bearer replace-me' \
-H 'Content-Type: application/json' \
-d '{"topic":"alarm","title":"TH1","message":"Baum auf Straße","priority":4}' \
http://localhost:8080/ntfy
Beispiel: Gotify
curl -X POST 'http://localhost:8080/message?token=replace-me' \
-H 'Content-Type: application/json' \
-d '{"title":"Meldung","message":"Test","priority":5}'
Konfigurationsmodell
Die Datei config.example.json zeigt das vollständige derzeitige Schema. Ein Mapping kann insbesondere diese Divera247-Ziele setzen:
target:alarm,news,eventtitle_template,text_template,address_templatenotification_type: 1 Einheit/Standort, 2 alle, 3 Gruppen, 4 Benutzer (entsprechend Divera247)cluster_routes(empfohlen für einheitsübergreifend, z. B.{"123": 2}), alternativclusters, sowiegroups,users,vehiclessend_push,send_sms,send_call,send_mail,send_pagerprivate_modeextra: zusätzliche API-Felder (z. B.foreign_id,priority,response_time, Event-Zeitstempel usw.)
Templates sind Go-text/template und erhalten das normalisierte Eingangsobjekt (.Source, .Channel, .Title, .Message, .Address, .Priority, .Tags, .Raw, .ReceivedAt).
Sicherheitshinweise zum Alpha-Stand
- Die WebUI gehört hinter TLS (Reverse Proxy oder direkt späterer TLS-Support).
- Divera247-Accesskey und Ingress-Tokens liegen derzeit in der Konfigurationsdatei; Dateirechte werden auf
0600gesetzt. Secret-Verschlüsselung/Secret-Store ist ein geplanter Schritt. - Neue Passwörter verwenden bcrypt; vorhandene SHA-256-Hashes werden beim Login migriert. CSRF-Schutz, CSP, Größenlimits und Login-Rate-Limit sind integriert.
- Für echte Alarmierung zuerst mit einer Divera247-Testeinheit und
dry_run=trueprüfen.
Siehe PROJECT_PLAN.md und API_SUPPORT.md für Roadmap und Abdeckungsstand.
Entwicklung prüfen
go test ./...
go vet ./...
node scripts/check-ui.cjs
Die Provider-Tests verwenden lokale HTTP-Testserver und Dry-Run; echte Nachrichten werden dabei nicht versendet. Die UI-Prüfung kontrolliert JavaScript-Syntax und eindeutige DOM-IDs. Zusätzlich existiert ein Browser-Test mit Chrome/Edge:
go build -o .cache/gateway-smoke.exe ./cmd/gateway
node scripts/browser-smoke.cjs
Er startet eine separate Testinstanz mit eigenem Profil und Dry-Run und prüft Login, Formulare, Vorschau, Speichern und Zustellhistorie.