From 75f3b32fbd2c5dfdff57d882348dddf9227cd57f Mon Sep 17 00:00:00 2001 From: Thomas Dannenberg Date: Wed, 22 Oct 2025 11:56:06 +0000 Subject: [PATCH] Kapitel 18/Premium Rohtext.md aktualisiert --- Kapitel 18/Premium Rohtext.md | 160 +++++++++++++++++++++++++++++----- 1 file changed, 138 insertions(+), 22 deletions(-) diff --git a/Kapitel 18/Premium Rohtext.md b/Kapitel 18/Premium Rohtext.md index 81b60a3..8259955 100644 --- a/Kapitel 18/Premium Rohtext.md +++ b/Kapitel 18/Premium Rohtext.md @@ -359,14 +359,16 @@ sodass Elyra keine weiteren Nachrichten beantwortet, bis erneut ein gültiger Tr 👉 **Screenshot geeignet:** Webhook-Node mit sichtbarem Pfad `/webhook/elyra/inbound` -#### Node 2 – Function (chatId extrahieren + vorbereiten) +#### Node 2 – Function (Nachricht vorbereiten + Zeitstempel aktualisieren) -**Zweck:** Extrahiert die `chatId` aus der eingehenden Nachricht und speichert sie zur späteren Wiederverwendung. -Außerdem werden alle empfangenen Daten in einheitlicher Struktur für den weiteren Verlauf vorbereitet. +**Zweck:** +Extrahiert die `chatId` aus der eingehenden Nachricht, bereitet die Daten für den weiteren Verlauf auf +und speichert zusätzlich den Zeitpunkt der letzten Aktivität, um inaktive Sessions später automatisch beenden zu können. **Node-Typ:** Function **Name:** Elyra – Nachricht vorbereiten +**Code:** ```js const body = items[0].json || {}; @@ -374,19 +376,25 @@ const chatId = body.chatId || 'unbekannt'; const text = (body.text || '').trim().toLowerCase(); const timestamp = body.timestamp || new Date().toISOString(); -// Global für spätere Prüfung speichern -$input.item.json.chatId = chatId; -$input.item.json.text = text; -$input.item.json.timestamp = timestamp; +// Zeitstempel der letzten Aktivität speichern +$global.set('elyra_lastmsg_' + chatId, Date.now()); -return [$input.item]; +// Standardisierte Ausgabe für den weiteren Workflow +return [{ + json: { + chatId, + text, + timestamp + } +}]; ``` -> [!TIP] -> WAHA überträgt bei eingehenden Nachrichten u. a. `chatId`, `text` und `timestamp`. -> Diese Felder werden hier bewusst standardisiert, damit nachfolgende Nodes keine Sonderfälle behandeln müssen. +> [!NOTE] +> Der Eintrag `elyra_lastmsg_` ermöglicht dem separaten Cleanup-Workflow, +> inaktive Sessions nach 10 Minuten automatisch zu beenden. +> Jede eingehende Nachricht aktualisiert diesen Zeitstempel automatisch. -👉 **Screenshot geeignet:** Function-Node mit geöffnetem Code, markierte Zeile `const chatId = ...` +👉 **Screenshot geeignet:** Function-Node mit markierter Zeile `$global.set('elyra_lastmsg_' + chatId, Date.now());` #### Node 3 – IF (Trigger: Elyra deaktivieren?) @@ -636,7 +644,7 @@ return [item]; **Anschlusslogik:** - **TRUE →** weiter mit Node 12 – *Antwort generieren (Ollama)* -- **FALSE →** weiter mit Node 16 – *Antwort: Kapazitätsgrenze oder Thema abgelehnt* +- **FALSE →** weiter mit Node 22 – *Antwort: Kapazitätsgrenze oder Thema abgelehnt* #### Node 12 – Set (Kontext für Themenverzweigung vorbereiten) @@ -886,7 +894,7 @@ an das lokale Sprachmodell **Mistral** über den Ollama-Endpunkt und erhält ein #### Node 21 – HTTP Request (Antwort über WAHA senden) -**Zweck:** Sendet die von Ollama generierte oder anderweitig erzeugte Antwort als WhatsApp-Nachricht über die WAHA‑API an den Nutzer. +**Zweck:** Sendet die generierte Antwort als WhatsApp-Nachricht über die WAHA‑API an den ursprünglichen Absender. **Node-Typ:** HTTP Request **Name:** Elyra – Antwort senden (WAHA) @@ -899,7 +907,7 @@ an das lokale Sprachmodell **Mistral** über den Ollama-Endpunkt und erhält ein ``` - **Headers:** - `Content-Type`: `application/json` - - *(optional)* `Authorization`: `Bearer ` + - `Authorization`: `Bearer ` - **Body → JSON:** ```json { @@ -908,13 +916,121 @@ an das lokale Sprachmodell **Mistral** über den Ollama-Endpunkt und erhält ein } ``` -> [!NOTE] -> Das Feld `antwort` enthält entweder die direkte Antwort aus einem vorherigen Set‑Node -> oder die von **Ollama** generierte Antwort aus dem HTTP-Request‑Node davor. -> Falls `antwort` leer ist, wird ersatzweise `text` genutzt – z. B. für statische Fallbacks. +> [!IMPORTANT] +> Der **API-Token ist zwingend erforderlich**, damit WAHA die Anfrage akzeptiert. +> Du findest ihn im WAHA-Webinterface unter **Settings → API → Token**. +> Ohne gültigen Token gibt die API den Fehlercode `401 Unauthorized` zurück. -👉 **Screenshot geeignet:** HTTP Request mit gesetztem Body `chatId` + `text` +👉 **Screenshot geeignet:** HTTP-Request-Node mit gesetztem Authorization‑Header -**Anschlusslogik:** -- → **Ende des Workflows** +**Anschlusslogik:** +→ Ende des Haupt-Workflows + +#### Node 22 – Set (Ablehnungsprompt: Ressourcenmangel) + +**Zweck:** +Bereitet den Prompt für eine höfliche, aber bestimmte Ablehnungsantwort durch **Ollama** vor, +wenn das System aktuell keine ausreichenden Ressourcen (z. B. Rechenkapazität oder Slots) zur Bearbeitung hat. + +**Node-Typ:** +Set + +**Name:** +Elyra – Thema abgelehnt (Ressourcenmangel) + +**Felder hinzufügen:** +- `chatId`: + `={{$json["chatId"]}}` +- `text`: + `={{$json["text"]}}` +- `ablehnungskontext`: + ```text + Die Anfrage kann derzeit nicht bearbeitet werden, da die verfügbaren Ressourcen + (z. B. Rechenkapazität oder Ausführungsslots) vorübergehend ausgelastet sind. + Formuliere eine höfliche, aber klare Antwort, die den Nutzer darüber informiert, + dass Elyra aktuell keine weiteren Anfragen annehmen kann. + Bitte den Nutzer freundlich um Verständnis und erkläre, + dass er es zu einem späteren Zeitpunkt erneut versuchen kann. + ``` + +👉 **Screenshot geeignet:** +Set-Node mit sichtbarem Feld `ablehnungskontext` + +**Anschlusslogik:** +→ weiter mit **Node 20 – Antwort generieren (Ollama mit Kontext)** + +### Workflow: Elyra – Session Cleanup (automatische Sitzungsbeendigung) + +**Zweck:** +Beendet inaktive Elyra-Sessions automatisch, wenn über 10 Minuten keine Nachricht mehr eingegangen ist. +Dadurch werden belegte Slots im UCC wieder freigegeben und die Systemkapazität bleibt stabil. + +Der Workflow wird alle **5 Minuten** automatisch gestartet. +Er durchsucht den n8n-Global-Store nach aktiven Sessions (`elyra_active_`) +und prüft anhand des zugehörigen Zeitstempels (`elyra_lastmsg_`), +ob die letzte Nutzerinteraktion länger als 10 Minuten her ist. +Falls ja, wird die Session beendet. + +👉 **Screenshot geeignet:** Diagramm mit Cron-Trigger → Function-Node „Inaktive Sessions schließen“ + +#### Node 1 – Cron (Trigger) + +**Zweck:** +Startet den Workflow regelmäßig, um alte Sessions zu bereinigen. + +**Node-Typ:** Cron +**Name:** Elyra – Cleanup Trigger + +**Parameter:** +- **Mode:** Every X Minutes +- **Every:** `5` + +> [!NOTE] +> Der Workflow läuft alle 5 Minuten automatisch. +> Du kannst das Intervall bei Bedarf anpassen – z. B. auf 2 Minuten für sehr aktive Systeme. + +👉 **Screenshot geeignet:** Cron-Node mit „Every 5 Minutes“ + +**Anschlusslogik:** +→ weiter mit **Node 2 – Inaktive Sessions schließen** + +#### Node 2 – Function (Inaktive Sessions schließen) + +**Zweck:** +Überprüft alle global gespeicherten Elyra-Sessions und deaktiviert diejenigen, +bei denen seit mehr als 10 Minuten keine Aktivität registriert wurde. + +**Node-Typ:** Function +**Name:** Elyra – Inaktive Sessions schließen + +**Code:** +```js +const allKeys = Object.keys($global); +const now = Date.now(); +const timeout = 10 * 60 * 1000; // 10 Minuten + +for (const key of allKeys) { + if (key.startsWith('elyra_active_') && $global.get(key) === true) { + const chatId = key.replace('elyra_active_', ''); + const lastMsg = $global.get('elyra_lastmsg_' + chatId) || 0; + if (now - lastMsg > timeout) { + $global.set(key, false); + } + } +} + +return []; +``` + +> [!TIP] +> Die Timeout-Dauer (`timeout`) lässt sich frei anpassen. +> Standardwert sind 10 Minuten (600 000 ms). +> Für Livestream- oder Event-Kontexte sind 5–10 Minuten in der Regel sinnvoll. + +👉 **Screenshot geeignet:** Function-Node mit geöffnetem Code-Editor, markierte Zeile `if (now - lastMsg > timeout)` + +**Anschlusslogik:** +→ Ende des Workflows + +---