Zum Hauptinhalt springen

Einheit 2 — Kanal-Bausteine: Eingang und Ausgang

Was du nach dieser Einheit weißt: Du kannst die Messenger-Anbindung so aufteilen, dass dein eigentlicher Workflow keinen Messenger kennen muss — und Antworten trotzdem automatisch im richtigen Chat landen.

Die Aufteilung​

             Kanal-Workflow „Nextcloud Talk“                      Dein Workflow
┌───────────────────────────────────────────────┐ ┌─────────────────────┐
│ [ Webhook ] → [ Eingang: übersetzen ] ─────────┼──────→ │ │
│ │ │ Router, Skills, │
│ [ Ausgang: Antwort senden ] ← [ Post Agent ] ←─┼─────── │ beliebige Logik │
└───────────────────────────────────────────────┘ └─────────────────────┘

Für jeden Messenger gibt es einen eigenen kleinen Kanal-Workflow mit zwei Teilen:

  • Der Eingang nimmt die Nachricht entgegen, prüft sie und übersetzt sie in das Einheitsformat (Kurs 7, Einheit 2).
  • Der Ausgang nimmt eine Antwort im Einheitsformat entgegen und schickt sie im Format des Messengers ab.

Dein eigentlicher Workflow sieht nur das Einheitsformat. Ob die Nachricht aus Teams oder Nextcloud kam, ist ihm egal.

Das Einheitsformat — kurz wiederholt​

Was der Eingang liefert:

{
"kanal": "nextcloud",
"nachricht_id": "48211",
"unterhaltung_id": "k7x2mqpa",
"absender_id": "m.mueller",
"absender_name": "Maria Müller",
"text": "Wie lief der Umsatz im Oktober?",
"datei": null,
"antwort_auf": "48211"
}

Was der Ausgang erwartet:

{
"kanal": "nextcloud",
"unterhaltung_id": "k7x2mqpa",
"antwort_auf": "48211",
"antwort_text": "Umsatz Oktober 2026: 84.200 € …"
}

Was der Ausgang zusätzlich wissen muss​

Für eine Antwort braucht jeder Messenger Angaben, die nicht ins Einheitsformat passen:

Messengerzusätzlich nötig
Nextcloud Talknichts — die unterhaltung_id ist das Token des Chats
Synology Chatdie numerische User-ID des Empfängers
Microsoft Teamsdie serviceUrl, die ID des Bots und der Typ der Unterhaltung

Diese Angaben durch alle Skills durchzureichen wäre umständlich und fehleranfällig. Stattdessen merkt sich der Eingang sie in einer Tabelle:

CREATE TABLE kanal_unterhaltung (
unterhaltung_id TEXT PRIMARY KEY,
kanal TEXT,
ziel TEXT, -- JSON mit den kanalspezifischen Angaben
aktualisiert TEXT
);
INSERT INTO kanal_unterhaltung (unterhaltung_id, kanal, ziel, aktualisiert)
VALUES ('{{ unterhaltung_id }}', '{{ kanal }}', '{{ ziel_sql }}', datetime('now'))
ON CONFLICT(unterhaltung_id) DO UPDATE SET ziel = excluded.ziel, aktualisiert = excluded.aktualisiert

Der Ausgang liest sie bei Bedarf wieder aus. Ein angenehmer Nebeneffekt: Auch proaktive Nachrichten (Morgenbriefing, Warnungen) finden so ihren Weg — der Workflow braucht nur die unterhaltung_id eines Chats, in dem schon einmal geschrieben wurde.

Mehrere Messenger gleichzeitig​

Wenn dein Workflow über mehrere Messenger erreichbar ist, verteilt ein Switch Agent die Antworten anhand des Feldes kanal:

EmpfängerBedingung
Ausgang Nextcloud'{{ kanal }}' == 'nextcloud'
Ausgang Synology'{{ kanal }}' == 'synology'
Ausgang Teams'{{ kanal }}' == 'teams'
Anzeige als Human Task'{{ kanal }}' == 'web'

Die Verbindung zwischen deinem Workflow und den Kanal-Workflows läuft über Source und Receiver (Kurs 5, Einheit 3).

Regeln für einen guten Eingang​

  1. Nur Nutzernachrichten. Messenger schicken auch Systemereignisse: Bot wurde hinzugefügt, jemand hat reagiert, eine Nachricht wurde bearbeitet. Lass nur neue Textnachrichten und Dateien durch.
  2. Nie auf die eigenen Nachrichten reagieren. Sonst antwortet der Bot sich selbst — endlos.
  3. IDs bereinigen. Entferne aus IDs alle Zeichen, die nicht in eine ID gehören. Sie landen später in SQL-Abfragen.
  4. Erwähnungen entfernen. „@Assistent wie hoch ist …“ → „wie hoch ist …“.
  5. Schnell bleiben. Der Eingang macht keine Arbeit, er übersetzt nur. Alles Weitere geschieht dahinter.

Kurzer Selbst-Check​

Warum speichert der Eingang die Teams-serviceUrl in einer Tabelle, statt sie als Feld mitzuschicken?

Weil das Feld sonst durch Router und alle Skills durchgereicht werden müsste — jeder Skill, der es vergisst, würde Antworten ins Leere schicken. Über die Tabelle findet der Ausgang die Angaben allein anhand der unterhaltung_id.