Skip to content

Telegram Orchestrator

The Telegram Orchestrator is the N8N workflow that acts as the entry point for every human interaction with the VPS infrastructure. It receives every message and every Telegram callback, checks authentication, routes to the right handler, and delegates long-running tasks to 13 callback sub-workflows + 4 extracted service handlers.

ComponentRole
Telegram BotUser-facing surface (messages, inline buttons, ForceReply)
AI RouterIntent detection via Claude (5 services: docker, n8n, odoo, content, general)
Command RouterParsing of /menu, /docker, /n8n, /odoo, /help, /notif, /todo, /triage, /projet, /note, /blog, /research, /new, /conv, /endconv, /model, /plan, /templates, /mcp
13 callback sub-workflowsAuth, menus, n8n actions, photos, conversations, file provider, etc.
4 service handlersDocker, Odoo, N8N, General (Claude chat)
Binary Content HandlerPhotos (via Vision OCR), voice notes, vCard, PDF, videos
Conversation Agent + Plan EngineMulti-turn conversations and action plans

Conversation system

Service handlers · wait-for-result

Callback sub-workflows · fire-and-forget

Telegram Orchestrator · 124 nodes

Telegram · message or callback

Extract User ID

Check User Banned?

Route by Update Type

Parse Callback / Message Type

Route by Service

SW-1 File Provider · 20n

SW-2 Docker Response Sender · 7n

SW-3 New User Notifier · 7n

SW-4 Auth Callback · 26n

SW-5 N8N Action Response · 21n

SW-7a Menu Renderer · 12n

SW-8 Free Text Handler · 10n

SW-9 Notif Mode Handler · 10n

SW-10 Content Action · 10n

SW-11 Conv Callback · 87n

SW-12 Odoo Project Picker · 10n

SW-13 Photo Action · 19n

Service Handler Docker

Service Handler Odoo · 33n

Service Handler N8N · 6n

SH-N8N Action Executor · 37n

Service Handler General · 10n

Conversation Manager

Conversation Agent

Plan Engine

Binary Content Handler · 21n

Vision OCR · 14n

CategoryCommands
Menu/menu, /start, /docker, /n8n, /odoo, /help, /notif, /todo, /triage
Content/note, /blog, /research
Conversation/new, /conv, /endconv, /model, /plan, /templates, /mcp
Project/projet (sub-commands list, create, status with paginated picker)

ProblemWithout orchestratorWith orchestrator
Remote SSH accessSSH connection for every actionTelegram message from mobile
Complex commandsMemorise Docker commandsNatural language + menus
SecurityExposed SSHAuthenticated bot + whitelist
ReactivityNo problem notificationsAlerts + immediate actions

Why a sub-workflow refactoring (#273-#294)?

Section titled “Why a sub-workflow refactoring (#273-#294)?”

The initial orchestrator had grown to 224 nodes, to the point of slowing the N8N UI and making editing risky (moving a node could break off-screen connections). Three refactoring waves brought the parent down to 124 nodes by extracting fire-and-forget paths:

WaveIssueEffect
Phase 1#273224 → 142 nodes (5 SWs)
Phase 2#273142 → 98 nodes (5 additional SWs)
Conv Mgr#27847→21 + 32 (Conversation Command Handlers)
SH-N8N#279Service Handler N8N 40→6 + SH-N8N Action Executor 37
Photo routing#176+9 nodes for photo conv-routing + SW-13
MCP menu#294Conv Agent 16→21 + SW-11 72→87

Each SW has a strict contract: passthrough or typed input, return value ignored by the parent (for fire-and-forget), no side effect on the main runtime.

FeatureDescription
AuthenticationUser whitelist, admin approval, ban list
Intent detectionClaude analyses natural language (5 services)
Interactive menusInline buttons for frequent actions
Multi-serviceDocker, N8N, Odoo, Content from a single interface
Voice + PhotoAudio transcription + image extraction
ConversationsMulti-turn with Redis memory and tool calls
Action plansMulti-step with hybrid escalation
MCPNative n8n tools enabled per conversation

StepAction
1. Extract user IDPull userId, chatId, firstName from the message or callback
2. Check bannedLookup Data Table Telegram Banned Users
3. Check authorisedLookup Data Table Telegram Authorized users
4. Pending approvalIf not authorised: Data Table Telegram Pending Approvals + admin alert

Yes

No

Authorized

Unauthorized

Message received

Check Banned

Check Authorized

Process request

Insert Pending Approval

Alert Admin · SW-3

Callback approve / deny

SW-4 Auth Callback Handler · 26n

Ignore

When a text message is not an exact command and no conversation is active, the AI Router detects intent via Claude (cli-ollama):

const prompt = `You are an intent detection system for a Telegram assistant.
Return ONLY valid JSON (no markdown, no backticks).
Format: {
"intent": "<action>",
"service": "<odoo|n8n|docker|general>",
"action": "<specific>",
"params": {},
"confidence": <0.0-1.0>
}
Services:
- odoo: invoices, quotes, contacts, customers, projects, CRM
- n8n: workflows, automations, executions
- docker: containers (restart, status, logs)
- general: conversation, generic questions
User message: ${text}`;
ConfidenceBehaviour
≥ 0.7Routes directly to the service
0.5 - 0.7Asks confirmation (buttons)
< 0.5Routes to general

Fallback chain: claude-sonnet-yolo (priority) → claude-haiku-yolo (if quota exceeded) → keyword routing (if API down).

Four specialised service handlers, each with a narrow responsibility:

ActionCommandProtection
statusdocker compose ps --format jsonAll
logsdocker compose logs --tail 100All
restartdocker compose restartExcept security-stack
updatedocker compose pull && up -dExcept security-stack

The SH-N8N parent only handles the admin check and delegation. All N8N execution logic lives in SH-N8N Action Executor (37 nodes).

ActionDescription
list_workflowsList workflows with pagination
toggle_workflowEnable / disable a workflow
list_executionsRecent executions (filters)
execute_triggerTrigger a whitelisted workflow

Trigger whitelist: only workflows present in n8n_trigger_whitelist can be triggered manually (rate limit: 1/min/workflow).

33 nodes after the /projet extension. Covers contacts, invoices, quotes, CRM, projects. The Odoo Project Picker sub-workflow (SW-12) handles project pagination when the list overflows the inline keyboard.

10 nodes for /help and the generic Claude chat (open-ended questions outside any specific service).

The Binary Content Handler (21 nodes) handles media:

TypePipeline
PhotoVision OCR (sub-workflow 14n, classification + structured extraction)
VoiceVoice Transcription (Groq ≤30s, ElevenLabs >30s)
vCardIngress Contacts → Odoo res.partner
PDF / videoMetadata extraction + summary

Vision OCR returns a {status, docType, extracted, text} contract. Depending on docType:

docTypeRouting
business_cardOdoo contact creation via Ingress Contacts (fire-and-forget)
invoice / screenshot / handwritten / general_documentDisplay + [Discuss] button that starts a conversation
not_documentSwitch to AI Router for conversational handling
errorError notification via Notification Hub
# Navigation
menu_<section> → Menu (main, docker, n8n, odoo, help, notif, todo)
# Docker
menu_docker_stacks_<action> → Stack list for action
docker_<action>_<stack> → Run action on stack
# N8N (admin)
menu_n8n_workflows → Workflow list
n8n_wf_<id> → Toggle workflow
n8n_run_<id> → Trigger workflow
# Conversations
conv_switch_<id> → Change active conversation
conv_delete_<id> → Archive
plan_exec_<shortId> → Execute a plan
plan_modify_<shortId> → Edit a plan
plan_cancel_<shortId> → Cancel a plan
# User management
approve_<userId> → Approve user (admin)
deny_<userId> → Deny user (admin)
# Photos (#176)
photo_discuss_<shortId> → Start a conversation about the photo
photo_dismiss_<shortId> → Ignore the photo
# Notifications hub
notif_<action>_<id> → approve / retry / details / ignore

Execute Workflow nodes MUST use the __rl format for workflowId, otherwise they fail silently at runtime:

{
"workflowId": {
"__rl": true,
"value": "<workflow-id>",
"mode": "id"
},
"options": {}
}

The flat format {"mode": "id", "workflowId": "<id>"} produces “No information about the workflow to execute found” without surfacing the error.


LimitImpactMitigation
Claude latency2-5s for intent detectionCache for frequent intents to design
No multi-languagePrompts in French onlySufficient for personal use
Telegram rate limiting30 messages/second maxNever reached in normal use
Non-document photos = 2 LLM callsDetection + generic analysisAcceptable for the conversation context

If the team moves to multi-user:

  • Granular per-handler permissions (currently: admin / non-admin)
  • Per-user audit logs of actions
  • Group notifications for critical actions

If functional extension is needed:

  • Add a service to the Service Router Switch (new case)
  • Or enable an MCP server via the /mcp command in a conversation
  • The system is extensible by design — every addition is isolated in its own sub-workflow

If latency becomes critical:

  • Pre-fetch frequent Data Tables in N8N memory cache
  • Pipeline Odoo calls (already partially done)
  • Migrate fire-and-forget paths to a dedicated Bull queue

  • Glossary — Webhook, Callback, Intent, Sub-workflow