# 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 1. Unter **Ausgänge** einen Ausgang anlegen: Name, eindeutige ID, Provider und dessen Verbindungsdaten. 2. Unter **Zuordnungen** als Ziel **Discord**, **HTTP-Webhook**, **SMTP**, **ntfy** oder **Gotify** und den Ausgang wählen. Quelle, Filter und Titel-/Text-Templates konfigurieren. 3. Mit **Regel prüfen** das Payload ansehen, anschließend speichern. Eingehende Testmeldungen erzeugen im Dry-Run ein Ergebnis ohne Netzwerkversand. 4. 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](https://docs.discord.com/developers/resources/webhook#execute-webhook). 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](OPERATIONS.md). Ausbauplan: [PROVIDER_PLAN.md](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 ```bash 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: ```bash 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: ```bash 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 ```bash 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`, `event` - `title_template`, `text_template`, `address_template` - `notification_type`: 1 Einheit/Standort, 2 alle, 3 Gruppen, 4 Benutzer (entsprechend Divera247) - `cluster_routes` (empfohlen für einheitsübergreifend, z. B. `{"123": 2}`), alternativ `clusters`, sowie `groups`, `users`, `vehicles` - `send_push`, `send_sms`, `send_call`, `send_mail`, `send_pager` - `private_mode` - `extra`: 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 `0600` gesetzt. 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=true` prüfen. Siehe `PROJECT_PLAN.md` und `API_SUPPORT.md` für Roadmap und Abdeckungsstand. ## Entwicklung prüfen ```sh 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: ```sh 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.