Service Handlers Telegram
1. Quoi ? — Définition et contexte
Section intitulée « 1. Quoi ? — Définition et contexte »Les Service Handlers sont une famille de 4 sub-workflows N8N appelés par l’Orchestrateur Telegram une fois qu’une intention utilisateur a été détectée. Chacun encapsule un domaine fonctionnel (chat général, Odoo, Docker, administration N8N) et expose une interface stable à l’Orchestrateur : on lui passe {service, action, params, chatId, userId, isAdmin}, il retourne {chatId, text, parseMode, keyboard} prêt à être envoyé à Telegram.
Composants
Section intitulée « Composants »| Workflow | ID | Nodes | Rôle |
|---|---|---|---|
| Service Handler - General | eCayuEQg4e8OhW6z | 10 | Aide (help) + chat libre avec Claude (chat) |
| Service Handler - Odoo | QFvNDnHjV6MIBB7n | 33 | Contacts, factures, devis, opportunités, projets, taches, dashboard |
| Service Handler - Docker | lBrSuWWM2WpN1v9I | 5 | Dispatcher vers Docker Actions + formatage Telegram |
| Service Handler - N8N (parent) | lwY2qomOWjrx0EP8 | 6 | Gate admin + délégation au sub-workflow |
| SH N8N Action Executor (sub) | HpILpcfY8Z6OJq9b | 37 | Workflows, executions, datatables, triggers (extrait via #279) |
Position dans le pipeline Telegram
Section intitulée « Position dans le pipeline Telegram »2. Pourquoi ? — Enjeux et motivations
Section intitulée « 2. Pourquoi ? — Enjeux et motivations »Problèmes résolus
Section intitulée « Problèmes résolus »| Problème | Sans handlers dédiés | Avec Service Handlers |
|---|---|---|
| Couplage Orchestrateur/métier | L’Orchestrateur grossit à chaque action ajoutée | Le routage reste ~5 outputs ; le métier vit ailleurs |
| Permissions dispersées | Check isAdmin répété partout | Gate centralisée dans chaque handler sensible |
| Tests cassants | Tester Odoo nécessite de simuler tout le pipeline Telegram | Sub-workflow appelable isolément avec un payload |
| Évolutivité | Ajouter /projet ou des actions N8N gonfle un workflow déjà critique | Le handler concerné absorbe la croissance |
Pourquoi extraire SH N8N Action Executor (#279)
Section intitulée « Pourquoi extraire SH N8N Action Executor (#279) »Le Service Handler - N8N faisait initialement 40 nodes : gate admin + 15 actions (list_workflows, toggle, executions, datatables, triggers…). Trois symptômes ont déclenché le refactoring vers un parent fin + sub-workflow lourd :
| Symptôme | Cause |
|---|---|
| Re-tests complets à chaque ajout | Modifier une action obligeait à retester le gate admin |
| Pagination + callback partout | La logique pagination était dupliquée entre listes |
| Lecture difficile | 40 nodes dans un même canvas masquait le Switch d’actions |
Le découpage produit 6 nodes en parent (Trigger → Check Admin → Is Admin? → Restore Input → Execute Sub → Return) et 37 nodes dans SH N8N Action Executor qui orchestre les 15 actions N8N.
Pourquoi SH Odoo a grandi à 33 nodes (#187)
Section intitulée « Pourquoi SH Odoo a grandi à 33 nodes (#187) »L’ajout des commandes /projet a porté SH Odoo de 27 à 33 nodes : 3 nouveaux Switch outputs (list_projects, create_project, project_status), 5 nodes Odoo natifs supplémentaires, et un Code node d’agrégation pour le dashboard projet. C’est la limite haute supportable avant un découpage analogue à #279 ; cf. section “Et si ?”.
Conventions partagées
Section intitulée « Conventions partagées »Tous les handlers respectent les mêmes invariants :
| Invariant | Implémentation |
|---|---|
| Trigger unique | Execute Workflow Trigger avec inputSource: passthrough |
| Send Typing | Indicateur d’activité Telegram pendant l’attente |
| Format Response | Sortie standard {chatId, text, parseMode, keyboard.pattern} |
| Long message | Split / pagination si > 4096 caractères |
onError: continueRegularOutput | Sur les nodes externes (Odoo, HTTP) pour formatter les erreurs proprement |
3. Comment ? — Mise en œuvre technique
Section intitulée « 3. Comment ? — Mise en œuvre technique »Tableau récapitulatif
Section intitulée « Tableau récapitulatif »| Workflow | ID | Nodes | Rôle |
|---|---|---|---|
| Service Handler - General | eCayuEQg4e8OhW6z | 10 | Help statique + chat Claude via CLI Ollama |
| Service Handler - Odoo | QFvNDnHjV6MIBB7n | 33 | 13 actions Odoo (contacts, factures, projets, dashboard) |
| Service Handler - Docker | lBrSuWWM2WpN1v9I | 5 | Dispatch vers Docker Actions + keyboards contextuels |
| Service Handler - N8N | lwY2qomOWjrx0EP8 | 6 | Gate admin + appel sub-workflow |
| SH N8N Action Executor | HpILpcfY8Z6OJq9b | 37 | Exécution réelle des actions N8N (extrait #279) |
Flux interne par handler
Section intitulée « Flux interne par handler »Gate admin (Odoo & N8N)
Section intitulée « Gate admin (Odoo & N8N) »Les actions Odoo et N8N sont sensibles (mutation de données, exécution de workflows). Les deux handlers interrogent la même Data Table Telegram Authorized users (invf2IKyVDyzoBZr) et coupent net en cas d’absence du flag.
| Étape | Comportement |
|---|---|
Lookup Telegram Authorized users par telegram_user_id | Récupère la ligne utilisateur |
is_admin absent ou false | Sortie immédiate avec ⛔ Accès réservé aux administrateurs. |
is_admin === true | Continue le flux métier |
| Réponse non-admin | parseMode: HTML, keyboard.pattern: no_keyboard |
Service Handler - General · 10 nodes
Section intitulée « Service Handler - General · 10 nodes »Deux actions : help (réponse statique HTML), et chat (fallback, appel CLI Ollama /api/generate avec model: codex-yolo, session_id généré). Le body de l’appel est sérialisé via JSON.stringify pour échapper guillemets et retours ligne — sans quoi un texte issu de Gemini Vision OCR avec citations cassait le payload (correctif d80e5ce).
Service Handler - Odoo · 33 nodes
Section intitulée « Service Handler - Odoo · 33 nodes »Le handler implémente 13 actions via un Switch à 13 outputs + fallback :
| Action | Modèle Odoo | Particularité |
|---|---|---|
search_contact | res.partner | 3 recherches parallèles (name / email / phone) + Merge + Dedup |
create_contact / update_contact | res.partner | Update via Custom Resource avec champ dynamique |
search_invoice | account.move | IF conditionnel sur payment_state |
search_quote / search_opportunity | sale.order / crm.lead | Filtres simples |
create_opportunity | crm.lead | Champs : name, email, phone, revenue, probability |
project_hours | account.analytic.line | Switch Period (week / month / all) |
search_project / search_task | project.project / project.task | Custom Resource + filtre name like |
list_projects | project.project | Tous les projets actifs (limit 15) |
create_project | project.project | Via /projet create <nom> |
project_status | 3 modèles | Chaîne : Get Project → Tasks → Timesheets → Aggregate Code |
Tous les nodes Odoo utilisent le credential Odoo tool admin (xQmHuksl8E7nuwCV), onError: continueRegularOutput, et alwaysOutputData: true (top-level) pour que Format Response s’exécute même sans résultat.
Service Handler - Docker · 5 nodes
Section intitulée « Service Handler - Docker · 5 nodes »Le handler reste mince car le travail réel est délégué à Docker Actions (SSH vers le VPS, exécution de docker compose). Le node Parse Docker Params traduit l’intent IA Router en paire (dockerAction, dockerStack) :
- Passthrough si l’action est déjà valide (
status,restart,logs,update,start,stop,list-all). - Sinon mapping via
ACTION_MAP(container_status→status,restart_container→restart…). - Mapping container → stack via
CONTAINER_TO_STACK(n8n→n8n-stack,caddy→security-stack…). - Erreur explicite si action inconnue (au lieu d’un fallback silencieux sur
status).
Format Response produit keyboard.pattern parmi standard / critical / list-all / after-action. L’Orchestrateur applique ensuite le bon Switch côté envoi (cf. règle « Reply Markup non expressionable »).
| Pattern | Usage | Boutons |
|---|---|---|
standard | Stack non-critique après status/logs | Status · Restart · Logs · Update · Retour |
critical | security-stack (restart/stop/start/update bloqués) | Status · Logs · Retour |
list-all | Vue tous containers | Status… · Restart… · Logs… · Retour |
after-action | Après restart/update | Status · Logs · Restart · Retour |
Service Handler - N8N · 6 nodes + sub-workflow 37 nodes
Section intitulée « Service Handler - N8N · 6 nodes + sub-workflow 37 nodes »Le parent ne fait que (1) gate admin via Data Table, (2) restore input, (3) déléguer à SH N8N Action Executor via Execute Workflow. Le sub-workflow expose 15 actions :
| Famille | Actions |
|---|---|
| Workflows | list_workflows (paginé), toggle_workflow |
| Executions | list_running, list_executions (filtres status), view_execution, retry_execution |
| Data Tables | list_datatables, view_datatable (paginé), view_row, edit_row, delete_row |
| Triggers manuels | list_triggers, list_trigger_cat, confirm_trigger, execute_trigger |
Les IDs longs (>64 octets pour les callbacks Telegram) sont stockés dans la Data Table n8n_pending_actions avec un short ID 8 chars et un TTL de 5 minutes. Les workflows déclenchables manuellement sont déclarés dans n8n_trigger_whitelist (catégories backup / sync / cleanup / maintenance).
Long response handling
Section intitulée « Long response handling »Telegram impose 4096 caractères par message. Trois patterns coexistent :
| Pattern | Quand l’utiliser |
|---|---|
| Troncature | Listes simples, dernier message contient … N résultats |
| Pagination | Listes longues type executions ou data tables — boutons ◀️ N/M ▶️ |
| Multi-message | Détails d’exécution avec stack trace — multiMessage: true, keyboard sur le dernier seulement |
Data Tables référencées
Section intitulée « Data Tables référencées »| Data Table | ID | Utilisée par |
|---|---|---|
Telegram Authorized users | invf2IKyVDyzoBZr | SH Odoo, SH N8N (gate admin) |
n8n_trigger_whitelist | — | SH N8N Action Executor (triggers manuels) |
n8n_pending_actions | — | SH N8N Action Executor (short ID ↔ payload) |
n8n_datatable_metadata | — | SH N8N Action Executor (tables exposées) |
Interface d’entrée / sortie standard
Section intitulée « Interface d’entrée / sortie standard »Entrée (depuis l’Orchestrateur) :
{ "service": "odoo", "action": "search_contact", "params": { "query": "Dupont" }, "chatId": 123456789, "userId": 123456789, "isAdmin": true, "originalText": "Cherche le contact Dupont"}Sortie (vers l’Orchestrateur) :
{ "chatId": 123456789, "text": "📇 <b>Contacts</b> (2 résultats)...", "parseMode": "HTML", "keyboard": { "pattern": "odoo_contacts" }}L’Orchestrateur ne lit que text, parseMode, et keyboard.pattern pour router vers le bon node Telegram (la structure du Reply Markup est hardcodée par pattern dans l’UI — N8N ne supporte pas les expressions sur la structure du keyboard, seulement sur les valeurs des boutons).
4. Et si ? — Perspectives et limites
Section intitulée « 4. Et si ? — Perspectives et limites »Limites actuelles
Section intitulée « Limites actuelles »| Limite | Impact | Mitigation |
|---|---|---|
| SH Odoo à 33 nodes | Lecture du canvas devient pénible | Découpage prévu (par famille d’actions) sur le modèle de #279 |
| SH General sans mémoire | Le chat libre n’a pas d’historique multi-tours | Conversation Agent dédié pour les conversations multi-turn |
| SH Docker dépend de SSH | Toute panne SSH bloque toutes les actions Docker | Docker Actions retourne success/error, le handler formate l’erreur |
| Gate admin = column lookup | Pas de RBAC fin (juste admin / non-admin) | Suffisant pour usage solo, à élargir si multi-utilisateurs |
Reply Markup non expressionable | Chaque pattern nécessite un node Telegram dédié | Pattern Switch + keyboards hardcodés (cf. doc telegram orchestrator) |
Scénarios d’évolution
Section intitulée « Scénarios d’évolution »Si SH Odoo dépasse 40 nodes :
- Découper par famille (
SH Odoo Contacts,SH Odoo Projects,SH Odoo Sales) sur le modèle #279 - Garder le parent comme dispatcher de gate admin + Switch initial
- Bénéfice : tests indépendants, ajout d’actions sans toucher au reste
Si besoin de permissions plus fines :
- Ajouter des colonnes à
Telegram Authorized users(can_docker,can_odoo,can_n8n) - Remplacer le check binaire
is_adminpar un check capability-based dans chaque handler - Garder la rétrocompatibilité :
is_admin = trueimplique toutes les capacités
Si volume de chat Claude augmente :
- SH General reste single-turn (utilité limitée pour conversation continue)
- Router proactivement vers Conversation Agent au-delà de N messages dans la même fenêtre
- Cache de session côté CLI Ollama via Redis (déjà en place)
Si nouveau domaine (ex. monitoring direct) :
- Créer
Service Handler - Monitoring(Prometheus queries, Grafana dashboards) - Ajouter un output
monitoringdans Route by Service de l’Orchestrateur - L’IA Router apprend la nouvelle catégorie via examples dans son prompt
Pages liées
Section intitulée « Pages liées »Workflows
Section intitulée « Workflows »- Telegram Orchestrator — Appelant des Service Handlers
- IA Router & MCP — Détection d’intent en amont
- Notification Hub — Pattern de routage analogue côté sortie
- Docker Updates — Consommateur du flux Docker
- GitHub-Odoo Sync — Autre famille de sub-workflows extraits
Infrastructure
Section intitulée « Infrastructure »- Database Backup — Sauvegardes consultables via SH N8N triggers