---
tags: [archive, nodered, brouillon]
status: archived
---

source : https://claude.ai/chat/5e904b84-0a75-4f94-b5ca-dec3dd29fbf1

Voici la version mise à jour, avec Switch, Change et Split à la place de la plupart des Function. Je n'ai pas vérifié les spécificités de la 5.0.7 : ces nœuds existent depuis longtemps, mais j'ai marqué ⚠️ les points à tester chez vous.

## 1\. Flux principal


```mermaid
flowchart TD
  IN["Matrix in"] --> F1{"Switch: Filtrer
  expéditeur = ALLOWED_MXID"}
  F1 -- "autre" --> FIN1(("fin"))
  F1 -- "autorisé" --> C1["Change: Contexte
  roomId, userText,
  sessionId lu dans la table,
  attempts=0, absent=0"]
  C1 --> S1{"Switch: Commande
  regex"}

  S1 -- "/new" --> N1["Change: supprimer l'entrée
  de la table + texte"]
  S1 -- "/status" --> ST1["HTTP GET /api/session/active"]
  ST1 --> ST2["Change: texte d'état"]
  S1 -- "/stop" --> SP1["HTTP POST interrupt"]
  SP1 --> SP2["Change: texte de confirmation"]
  S1 -- "message" --> SF1[["SUBFLOW 1
  OC Session"]]

  SF1 --> G1["Function: Garde busy
  vérifie et marque en une étape"]
  G1 -- "déjà occupée" --> MB["Change: texte déjà en cours"]
  G1 -- "libre" --> A1["Matrix Typing on
  + message Reçu"]
  A1 --> P1["Change: Prép. prompt
  url + corps JSONata"]
  P1 --> H1["HTTP POST prompt"]
  H1 --> S2{"Switch: statusCode"}
  S2 -- "404 et pas déjà retenté" --> R1["Change: supprimer l'entrée
  de la table, retried=true"]
  R1 --> SF1
  S2 -- "autre erreur" --> ERRTXT["Change: texte d'erreur"]
  S2 -- "2xx" --> SF2[["SUBFLOW 2
  OC Attendre fin"]]

  SF2 -- "terminé" --> SF3[["SUBFLOW 3
  OC Lire réponse"]]
  SF2 -- "timeout" --> MT["Change: texte toujours en cours"]

  SF3 --> L1["Change: libérer busy
  + Typing off"]
  MT --> L1
  MB --> SF4
  ERRTXT --> L1
  N1 --> SF4
  ST2 --> SF4
  SP2 --> SF4
  L1 --> SF4[["SUBFLOW 4
  Matrix Envoyer"]]

  CT["Catch: tout le flux"] --> CE["Change: texte d'erreur
  error.message"]
  CE --> L1

  SESS[("GLOBAL, magasin fichier
  oc_sessions")]
  BUSYCTX[("FLOW, mémoire
  busy")]
  C1 -.-> SESS
  N1 -.-> SESS
  R1 -.-> SESS
  G1 -.-> BUSYCTX
  L1 -.-> BUSYCTX

  classDef sub fill:#dbeafe,stroke:#2563eb,color:#000
  classDef ctx fill:#fef3c7,stroke:#d97706,color:#000
  classDef fn fill:#fee2e2,stroke:#dc2626,color:#000
  class SF1,SF2,SF3,SF4 sub
  class SESS,BUSYCTX ctx
  class G1 fn
```

Une seule Function reste (en rouge) : la garde busy, pour que « vérifier puis marquer » se fasse en une étape. J'ai aussi déplacé « libérer busy » avant l'envoi Matrix : l'agent a fini à ce moment-là, et ça évite de l'exécuter une fois par morceau de message découpé.

## 2\. Subflow 1 : OC Session

```mermaid
flowchart TD
  I["Entrée"] --> SW{"Switch: sessionId vide ?"}
  SW -- "non" --> O["Sortie"]
  SW -- "oui" --> CP["Change: corps de création
  title = roomId"]
  CP --> HC["HTTP POST /api/session"]
  HC --> CS["Change:
  sessionId = payload.data.id
  table oc_sessions roomId = sessionId"]
  CS --> O
```

## 3\. Subflow 2 : OC Attendre fin

```mermaid
flowchart TD
  I["Entrée"] --> DLY["Delay fixe: POLL_MS"]
  DLY --> TYP["Matrix Typing"]
  TYP --> GET["HTTP GET /api/session/active"]
  GET --> CH["Change: compteurs JSONata
  running, attempts+1, absent"]
  CH --> SW{"Switch: décision
  premier match seulement"}
  SW -- "attempts > MAX_ATTEMPTS" --> O2["Sortie 2: timeout"]
  SW -- "absent >= ABSENT_REQUIRED" --> O1["Sortie 1: terminé"]
  SW -- "sinon" --> DLY
```

## 4\. Subflows 3 et 4

```mermaid
flowchart LR
  subgraph SF3["SUBFLOW 3 : OC Read Response"]
    direction TB
    A1["Change: url du GET message"] --> A2["HTTP GET message
    type=assistant, order=desc, limit=1"]
    A2 --> A3["Change: extraction du texte
    ⚠️ à écrire après le debug"]
  end
  subgraph SF4["SUBFLOW 4 : Matrix Send"]
    direction TB
    B1["Split: chaîne par longueur
    8000 caractères"] --> B2["Delay: limitation 1 msg/s"]
    B2 --> B3["Matrix out"]
  end
  SF3 --> SF4
```

## 5\. Réglages des nœuds

| Nœud | Réglage |
| --- | --- |
| Switch Filtrer | Propriété = l'expéditeur dans votre message Matrix (⚠️ nom à vérifier dans un `debug`), règle `==` avec type « variable d'environnement » `ALLOWED_MXID`. |
| Change Contexte | `msg.roomId` et `msg.userText` depuis la structure du nœud Matrix, `msg.sessionId` depuis `global.oc_sessions[msg.roomId]` (magasin fichier), `attempts` et `absent` à 0. |
| Switch Commande | Règles regex `^/new`, `^/status`, `^/stop`, puis « sinon ». |
| Change Prép. prompt | `msg.url` en JSONata : `$env('OC_BASE_URL') & '/api/session/' & sessionId & '/prompt'`. `msg.payload` en JSONata : `{"text": userText}`. |
| Nœuds HTTP | Méthode et « Return: parsed JSON ». Pour les URL des `/stop` et `/status`, même construction que ci-dessus. |
| Switch statusCode | Après le POST prompt : `404` ET `retried` non vrai, puis `>= 300`, puis sinon. |
| Change Compteurs | Règles appliquées dans l'ordre : `running = $exists($lookup(payload.data, sessionId))`, `attempts = attempts + 1`, `absent = running ? 0 : absent + 1`. |
| Switch Décision | Mode « arrêter après le premier match », règles dans l'ordre du schéma. Valeurs comparées : env `MAX_ATTEMPTS` et `ABSENT_REQUIRED`. |
| Change libérer busy | Supprimer `flow.busy[msg.roomId]`, et mettre `msg.typing` à off si votre nœud Typing le gère ainsi. |
| Split | « Split string using: a fixed length of 8000 characters ». |
| Delay Matrix | Mode « Rate Limit », 1 message par seconde (à ne pas confondre avec le Delay fixe du subflow 2). |

## 6\. Variables

| Nom | Type | Portée |
| --- | --- | --- |
| `oc_sessions` | contexte, magasin **fichier** | global : `{ roomId: sessionId }` |
| `busy` | contexte, mémoire | flow : `{ roomId: true }` |
| `OC_BASE_URL`, `OC_AUTH`, `ALLOWED_MXID`, `BOT_MXID` | environnement | flux |
| `POLL_MS`, `MAX_ATTEMPTS`, `ABSENT_REQUIRED` | environnement | subflow 2 |
| `roomId`, `sessionId`, `userText`, `attempts`, `absent`, `retried` | propriétés du `msg` | par conversation |

## Points à tester en premier

1.  **Chemins avec clé dynamique** (`flow.busy[msg.roomId]`, `global.oc_sessions[msg.roomId]` avec le magasin fichier) : essayez-les sur un cas simple avant de tout câbler.
2.  **`payload.data.id`** à la création de session : je suppose que l'identifiant est à cet endroit, sans avoir lu le schéma `Session.Info`. Un `debug` sur la réponse le confirmera.
3.  **Variables d'environnement dans le Delay** : si votre version ne les accepte pas, mettez 5 s en dur.
4.  **Retour du nœud Matrix Typing** : s'il ne se désactive pas par un `msg` dédié, regardez son aide intégrée.

Si vous voulez ces schémas en page rendue, plus pratique à consulter, je peux les publier.