AutomationFlowsAI & RAG › Telegram Orchestrator

Telegram Orchestrator

Telegram Orchestrator. Uses lmChatOpenRouter, httpRequestTool, telegram, httpRequest. Event-driven trigger; 25 nodes.

Event trigger★★★★☆ complexityAI-powered25 nodesOpenRouter ChatHTTP Request ToolTelegramHTTP RequestAgent ToolAgentTelegram Trigger
AI & RAG Trigger: Event Nodes: 25 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Agent → Agenttool recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "Telegram Orchestrator",
  "nodes": [
    {
      "parameters": {
        "model": "openai/gpt-oss-20b:free",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        480,
        -176
      ],
      "id": "07e8bccc-d199-4212-b226-e40b087d2f5a",
      "name": "Fallback",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "raw",
        "jsonOutput": "={\n  \"parameters\": {\n    \"assignments\": {\n      \"assignments\": [\n        {\n          \"id\": \"a1\",\n          \"name\": \"userText\",\n          \"value\": \"{{ $('Telegram Trigger').first().json.message.text || $json.message?.text || '' }}\",\n          \"type\": \"string\"\n        },\n        {\n          \"id\": \"a2\",\n          \"name\": \"chatId\",\n          \"value\": \"{{ $('Telegram Trigger').first().json.message.chat.id }}\",\n          \"type\": \"string\"\n        }\n      ]\n    },\n    \"includeOtherFields\": false,\n    \"options\": {}\n  },\n  \"type\": \"n8n-nodes-base.set\",\n  \"typeVersion\": 3.4,\n  \"name\": \"Normalize Input\"\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        240,
        -320
      ],
      "id": "ead7694a-e48a-4232-8690-1a876a82d1a6",
      "name": "Normalize Input"
    },
    {
      "parameters": {
        "model": "deepseek/deepseek-v4-flash",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        368,
        -176
      ],
      "id": "1d87a805-7026-4358-bafa-7c5eeccb4b61",
      "name": "Model 1",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "nvidia/nemotron-3-ultra-550b-a55b:free",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        208,
        256
      ],
      "id": "c45e40c2-d343-418a-9a26-a2e1dffd2ba3",
      "name": "Analyst 1",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        336,
        256
      ],
      "id": "2d3355c0-783c-4b71-b009-d526b69495a5",
      "name": "Analyst2",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "openai/gpt-5.6-luna",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        544,
        256
      ],
      "id": "4711f536-64fe-43b6-b8ba-6f899289f444",
      "name": "Searcher1",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "deepseek/deepseek-v4-flash",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        656,
        256
      ],
      "id": "cba21537-40cf-4224-87db-8204dcf2bdd4",
      "name": "Searcher2",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "qwen/qwen3.5-flash-02-23",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        928,
        256
      ],
      "id": "6cd573ad-52e6-4ac4-a16b-3e34bc4f5801",
      "name": "Finance1",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        1024,
        256
      ],
      "id": "0a9f5fbf-3069-4636-aa59-7c44a93d89d1",
      "name": "Finance2",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "url": "https://query1.finance.yahoo.com/",
        "sendHeaders": true,
        "specifyHeaders": "json",
        "jsonHeaders": "{\n  \"headers\": {\n    \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36\",\n    \"Accept\": \"application/json\",\n    \"Accept-Language\": \"en-US,en;q=0.9\"\n  },\n  \"sendBody\": false,\n  \"body\": {}\n}",
        "options": {
          "timeout": 10000
        }
      },
      "type": "n8n-nodes-base.httpRequestTool",
      "typeVersion": 4.4,
      "position": [
        1152,
        256
      ],
      "id": "74af3e39-45ac-4f7a-9eba-e80589d753d3",
      "name": "WebSearch2"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.tavily.com/search",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpBearerAuth",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "query",
              "value": "={{ $fromAI('query', 'Testo o parole chiave da cercare sul web', 'string') }}"
            },
            {
              "name": "search_depth",
              "value": "advanced"
            },
            {
              "name": "max_results",
              "value": "3"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequestTool",
      "typeVersion": 4.4,
      "position": [
        800,
        256
      ],
      "id": "cda01f0f-9e0a-46ea-ac40-8598a7546d64",
      "name": "WebSearch1",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        },
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "editMessageText",
        "chatId": "={{ $('Normalize Input').item.json.parameters.assignments.assignments[1].value }}",
        "messageId": "={{ $('Processing Signal').first().json.result.message_id }}",
        "text": "={{ $json.response }}",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1104,
        -320
      ],
      "id": "1b01343c-6336-412f-b2b0-a81a351e4afd",
      "name": "Final Response",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "file",
        "fileId": "={{ $('Telegram Trigger').item.json.message.voice.file_id }}",
        "additionalFields": {
          "mimeType": "=audio/ogg"
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        160,
        -720
      ],
      "id": "d39828dd-f483-4b5f-ae73-97cc8022e9f8",
      "name": "Audio file",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const buffer = await this.helpers.getBinaryDataBuffer(0, 'data');\nconst item = $input.first();\nitem.binary.data = await this.helpers.prepareBinaryData(buffer, 'voice.ogg', 'audio/ogg');\nreturn [item];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        320,
        -720
      ],
      "id": "529c0ab4-f81f-4d34-b324-6d1361758748",
      "name": "Audio data"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 3
                },
                "conditions": [
                  {
                    "leftValue": "={{ $('Telegram Trigger').item.json.message.voice.file_id }}",
                    "rightValue": "",
                    "operator": {
                      "type": "string",
                      "operation": "notEmpty",
                      "singleValue": true
                    },
                    "id": "a9c45805-2bf8-499c-a6d9-e2a784ba5871"
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "41b32b2c-755c-4e8f-bb45-26636b501399",
                    "leftValue": "={{ $('Telegram Trigger').item.json.message.text }}",
                    "rightValue": "",
                    "operator": {
                      "type": "string",
                      "operation": "notEmpty",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "looseTypeValidation": "={{ true }}",
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        -64,
        -336
      ],
      "id": "d0fb6cd3-e24d-439e-bd66-cae4ada02241",
      "name": "Switch: Voice vs Text Input"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://host.docker.internal:8000/v1/audio/transcriptions",
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "parameterType": "formBinaryData",
              "name": "file",
              "inputDataFieldName": "data"
            },
            {
              "name": "response_format",
              "value": "json"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        160,
        -528
      ],
      "id": "6ac46b6f-0ed0-47a3-9fb4-4c8b4bff8262",
      "name": "Whisper - Transcriber"
    },
    {
      "parameters": {
        "jsCode": "const transcribedText = $json.text;\n\nreturn [\n  {\n    json: {\n      message: {\n        text: transcribedText,\n        chat: { id: $('Telegram Trigger').first().json.message.chat.id },\n        from: { first_name: $('Telegram Trigger').first().json.message.from.first_name }\n      }\n    }\n  }\n];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        320,
        -528
      ],
      "id": "15aefe70-a14a-45a7-bce3-1d3fbe374e0f",
      "name": "Converted message"
    },
    {
      "parameters": {
        "jsCode": "function extractOutput(value, depth = 0) {\n  if (depth > 5) return String(value);\n  if (typeof value === 'string') {\n    const trimmed = value.trim();\n    if (trimmed.startsWith('[') || trimmed.startsWith('{')) {\n      try {\n        return extractOutput(JSON.parse(trimmed), depth + 1);\n      } catch (e) {\n        return value;\n      }\n    }\n    return value;\n  }\n  if (Array.isArray(value)) {\n    return extractOutput(value[0], depth + 1);\n  }\n  if (value && typeof value === 'object') {\n    if (value.output !== undefined) return extractOutput(value.output, depth + 1);\n    if (value.response !== undefined) return extractOutput(value.response, depth + 1);\n    if (value.text !== undefined) return extractOutput(value.text, depth + 1);\n    if (value.content !== undefined) return extractOutput(value.content, depth + 1);\n    return JSON.stringify(value);\n  }\n  return String(value);\n}\n\nfunction stripPromptTags(text) {\n  const promptTags = ['role','context','objective','instructions','constraints','query','output_rules','output_structure','data_hierarchy','hard_rule','available_agents','formatting','ticker_resolution','metrics','direct_response'];\n  const tagPattern = new RegExp(`</?(?:${promptTags.join('|')})[^>]*>`, 'gi');\n  return text.replace(tagPattern, '');\n}\n\nfunction escapeHtml(str) {\n  return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\n// Tokenizza, HTML-esca tutto il testo (anche dentro <pre>/<code>),\n// e BILANCIA i tag: chiusure orfane scartate, tag aperti chiusi d'ufficio a fine stringa.\n// Garantisce sempre HTML Telegram valido, qualunque cosa emetta il modello.\nfunction sanitizeForTelegramHtml(text) {\n  const ALLOWED = ['b', 'i', 'code', 'pre', 'a'];\n  const TAG_RE = new RegExp(`<\\\\/?(?:${ALLOWED.join('|')})(?:\\\\s[^>]*)?>`, 'gi');\n\n  const tokens = [];\n  let last = 0;\n  let m;\n  TAG_RE.lastIndex = 0;\n  while ((m = TAG_RE.exec(text)) !== null) {\n    if (m.index > last) tokens.push({ type: 'text', value: text.slice(last, m.index) });\n    tokens.push({ type: 'tag', value: m[0] });\n    last = TAG_RE.lastIndex;\n  }\n  if (last < text.length) tokens.push({ type: 'text', value: text.slice(last) });\n\n  const out = [];\n  const stack = [];\n\n  for (const tok of tokens) {\n    if (tok.type === 'text') {\n      out.push(escapeHtml(tok.value));\n      continue;\n    }\n    const raw = tok.value;\n    const closing = /^<\\//.test(raw);\n    const name = raw.replace(/^<\\/?/, '').replace(/[\\s>].*$/, '').toLowerCase();\n\n    if (closing) {\n      const idx = stack.lastIndexOf(name);\n      if (idx === -1) continue; // chiusura orfana: scartata\n      while (stack.length - 1 > idx) out.push(`</${stack.pop()}>`); // auto-chiude interleaving errati\n      stack.pop();\n      out.push(`</${name}>`);\n    } else {\n      if (name === 'a') {\n        const href = (raw.match(/href\\s*=\\s*\"([^\"]*)\"/i) || [])[1];\n        if (!href) continue; // <a> senza href non \u00e8 valido su Telegram: scartato\n        stack.push('a');\n        out.push(`<a href=\"${href}\">`);\n      } else {\n        stack.push(name); // b/i/code/pre: attributi rimossi, forma nuda\n        out.push(`<${name}>`);\n      }\n    }\n  }\n\n  while (stack.length) out.push(`</${stack.pop()}>`); // chiude tag aperti (es. <pre> troncato)\n  return out.join('');\n}\n\nfunction cleanAgentOutput(text) {\n  if (typeof text !== 'string') return String(text);\n  let cleaned = stripPromptTags(text);\n  cleaned = cleaned.replace(/\\{\\{.*?\\}\\}/g, '');\n  cleaned = sanitizeForTelegramHtml(cleaned);\n  cleaned = cleaned.replace(/\\n{3,}/g, '\\n\\n').trim();\n  return cleaned;\n}\n\nconst rawOutput = extractOutput($input.first().json);\nconst cleanOutput = cleanAgentOutput(rawOutput);\n\nreturn [\n  {\n    json: {\n      response: cleanOutput,\n      raw: rawOutput,\n    }\n  }\n];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        880,
        -320
      ],
      "id": "02a55f89-40b9-4b9d-94f3-d60eeddcb3ab",
      "name": "Output Formatter"
    },
    {
      "parameters": {
        "toolDescription": "Executes live web searches via Tavily or SerpAPI tool node, synthesises retrieved content into a cited factual summary. The LLM here acts as an extraction and synthesis layer over raw search results ",
        "text": "=<role>\nReal-time research specialist. Always search live web data for anything time-sensitive, never rely on static memory for current events, prices, or dates.\n</role>\n\n<context>\nInput: {{ $json.parameters.assignments.assignments[0].value }}\n</context>\n\n<instructions>\nRun targeted searches, prefer sources from the last 30 days, prioritize official/major outlets. Cross-check up to 3 sources internally, never label them in the output. Answer in the user's language. Mention dates only if they change the claim's meaning. Fold contradictions into the prose only if material.\n</instructions>\n\n<formatting>\nTarget: Telegram mobile, narrow screen (~32 monospace chars usable). Pick the structure that survives a phone screen, not the one that looks good on desktop.\n- Simple factual answer: plain prose, 3-6 sentences, no structure.\n- List of distinct items/factors: bullet lines, one per line, prefix \"\u2022 \", no nesting.\n- Comparison of 2-3 entities across attributes (DEFAULT for comparisons): vertical labeled blocks. One attribute per block: <b>heading</b>, then one short line per entity marked with an emoji/flag. Never a wide table for this.\n    <b>Bev\u00f6lkerung</b>\n    \ud83c\udde9\ud83c\uddea 83,6 Mio.\n    \ud83c\uddee\ud83c\uddf9 58,9 Mio.\n- <pre> monospace table: ONLY if every cell is a short scalar (number, %, currency, \u22648 chars) AND \u22643 columns AND each line \u226432 chars. Right-align numbers, pad columns, NO emoji inside <pre>. If any cell needs prose, a table is forbidden: use labeled blocks.\n- Close a comparison with 2-3 plain-prose sentences of synthesis.\nSources: at most, bare links at the end, one per line, no labels. Omit if not needed.\nTelegram HTML only: <b> <i> <code> <pre> <a href=\"...\">. No markdown, no <table>/<ul>/<li>/<div>.\n</formatting>\n\n<constraints>\nMax 300 words. No em dashes. Blacklist: delve, tapestry, multifaceted, embark, unlocking. No preamble, start with the answer.\n</constraints>\n\n<query>{{ $json.parameters.assignments.assignments[0].value }}</query>",
        "needsFallback": true,
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.agentTool",
      "typeVersion": 3,
      "position": [
        624,
        64
      ],
      "id": "a79a7985-e462-45db-8641-2d9c823029ac",
      "name": "Agent - Web Researcher"
    },
    {
      "parameters": {
        "toolDescription": "Retrieves and processes market data via HTTP tool calls (Yahoo Finance / Alpha Vantage), computes performance metrics (weekly return, benchmark delta, Sharpe), and returns structured Telegram markdown. Data-fetching is the bottleneck, not LLM inference.",
        "text": "=<role>\nQuantitative analyst. Precision over style, never fabricate data or metrics.\n</role>\n\n<context>\nInput: {{ fromAI('query') }}\nAlways fetch live data via tools before answering. Respond in the user's language.\n</context>\n\n<ticker_resolution>\nConvert names to Yahoo Finance tickers before any tool call: S&P 500\u2192%5EGSPC, Nasdaq\u2192%5EIXIC, Dow\u2192%5EDJI, Bitcoin\u2192BTC-USD, Ethereum\u2192ETH-USD, Gold\u2192GC=F, Oil\u2192CL=F. Company names\u2192ticker (Tesla\u2192TSLA, Nvidia\u2192NVDA). If ambiguous, pick the most liquid instrument; if truly unclear, ask.\n</ticker_resolution>\n\n<data_hierarchy>\nYahoo Finance first, Alpha Vantage fallback. If both fail: state \"Dati non disponibili: [motivo]\", never estimate.\n</data_hierarchy>\n\n<metrics>\nCompute when data allows: weekly return, benchmark delta, volatility, annualized Sharpe. If asked: alpha, beta, max drawdown, correlation. Never invent unsupported metrics.\n</metrics>\n\n<formatting>\nTarget: Telegram mobile, narrow screen (~32 monospace chars usable). Pick the structure that survives a phone screen.\n- Single asset / quick number: plain prose, numbers woven into the sentence (\"NVDA +4.2% this week, +3.2 pts over the Nasdaq, Sharpe 1.8\"). No structure.\n- Distinct risk signals: bullet lines, one per line, prefix \"\u2022 \", no nesting.\n- Comparison of 2-3 assets across attributes: vertical labeled blocks. One metric per block, <b>heading</b>, one short line per asset. No wide table for prose content.\n- <pre> monospace table: the right tool for a numeric ranking/matrix, but ONLY if every cell is a short scalar (number, %, ticker, \u22648 chars) AND \u22643 columns AND each line \u226432 chars. Right-align numbers, pad columns to fixed width, NO emoji inside <pre>.\n    <pre>\n    Titolo    Sett.   vs Idx\n    NVDA     +4.2%    +3.2\n    AAPL     -1.1%    -2.1\n    </pre>\n- If any cell needs prose, a table is forbidden: use labeled blocks.\nTelegram HTML only: <b> <i> <code> <pre>. No markdown, no <table>/<ul>/<li>/<div>.\n</formatting>\n\n<constraints>\nNo forecasts, no investment advice, no speculative language. Max 200 words unless a numeric table is genuinely needed. No em dashes. Blacklist: delve, tapestry, multifaceted, comprehensive, unlocking, transformative. No preamble, start with the answer.\n</constraints>\n\n<query>\n{{ fromAI('query') }}\n</query>",
        "needsFallback": true,
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.agentTool",
      "typeVersion": 3,
      "position": [
        944,
        64
      ],
      "id": "3fc7f053-fd17-431f-96fa-4186df7ea493",
      "name": "Agent - Finance Analyst"
    },
    {
      "parameters": {
        "toolDescription": "Accepts quantitative or code-generation requests, produces executable Python/JS blocks with minimal commentary, and optionally pipes output through n8n's Code Node for immediate execution.",
        "text": "=<role>\nGeneral-purpose reasoning and code assistant. Handles calculations, logic, code generation/review, and organizing notes. No live data access, no persistent storage: if asked to set a reminder or save something, say clearly you can't persist it beyond this chat and return the info as text instead.\n</role>\n\n<context>\nInput: {{ fromAI('query') }}\nRespond in the user's language.\n</context>\n\n<instructions>\nCode: clean, minimal, runnable Python or JS. Comment only non-obvious lines. No preamble.\nCalculations/logic: show steps only if they aid understanding.\nNotes/organization: structure only as much as the content needs.\nNever fabricate facts or data you don't have.\n</instructions>\n\n<formatting>\nTarget: Telegram mobile, narrow screen (~32 monospace chars usable for data tables).\n- Prose answer: plain text, no structure.\n- Distinct items: bullet lines, one per line, prefix \"\u2022 \", no nesting.\n- Code: always inside <pre>. The ~32-char width limit does NOT apply to code, horizontal scroll is acceptable for code blocks. Keep original indentation.\n- Comparison of 2-3 entities: vertical labeled blocks (<b>heading</b> + one short line per entity). No wide prose tables.\n- Data table in <pre>: ONLY short scalar cells, \u22643 columns, \u226432 chars/line, no emoji inside <pre>.\nTelegram HTML only: <b> <i> <code> <pre>. No markdown, no <table>/<ul>/<li>/<div>.\n</formatting>\n\n<constraints>\nMax 200 words unless code genuinely needs more. No em dashes. Blacklist: delve, tapestry, multifaceted, comprehensive, unlocking, transformative. No preamble, start with the answer.\n</constraints>\n\n<query>\n{{ fromAI('query') }}\n</query>",
        "needsFallback": true,
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.agentTool",
      "typeVersion": 3,
      "position": [
        304,
        64
      ],
      "id": "4f4de8fa-5907-4771-b9dc-c28490fa0674",
      "name": "Agent - Data & Coding Analyst"
    },
    {
      "parameters": {
        "chatId": "={{ $json.message.chat.id }}",
        "text": "\u23f3 Sto elaborando la risposta...",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        -416,
        -336
      ],
      "id": "86854fe3-2fb5-4d82-8d0e-185b64cf1199",
      "name": "Processing Signal",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=<role>\nAct as a Senior Metacognitive Orchestrator for a multi-agent system. Your job is precise intent classification and mandatory delegation to exactly one sub-agent. You answer directly ONLY for trivial DIRECT_RESPONSE cases.\n</role>\n\n<context>\nInput: {{ $json.parameters.assignments.assignments[0].value }}\nClassify the message, then either answer directly (DIRECT_RESPONSE only) or delegate to exactly one specialized sub-agent tool.\n\nAvailable agents:\n1. FINANCE_AGENT: ETFs, stocks, portfolio analysis, market data, finance.\n2. WEB_RESEARCHER: factual research, news, recipes, summaries, web lookups.\n3. DATA_ANALYST: calculations, code generation/review, logic, organizing notes.\n</context>\n\n<direct_response>\nDIRECT_RESPONSE is for messages needing no external data, computation, or specialized reasoning:\n- greetings and social pleasantries (hi, thanks, how are you)\n- meta-questions about the bot (what can you do, who are you)\n- acknowledgments and conversation closers\n- basic static facts (e.g. \"12*7\", \"capital of France\")\nIf there is ANY ambiguity about whether specialized data or reasoning is needed, delegate. DIRECT_RESPONSE is the exception, not the default.\n</direct_response>\n\n<instructions>\nReason internally in three phases:\n1. Intent Analysis: map the primary intent to exactly one agent.\n2. Parameter Extraction: pull the entities the selected agent needs.\n3. Delegation: invoke that single agent tool with the processed query. Forward the request unchanged unless minimal clarification is strictly necessary.\n</instructions>\n\n<constraints>\n- DIRECT_RESPONSE: answer directly, concise, in the user's language. Telegram HTML only (<b> <i> <code>), no markdown, no preamble.\n- Delegated cases: call exactly one agent tool, never zero, never two. When a tool returns, output its result VERBATIM: do not reformat, re-summarize, wrap, or add commentary. The sub-agent output is the final answer.\n- Never produce a standalone answer for non-trivial queries.\n- No em dashes, prefer colons or commas. Blacklist: delve, tapestry, comprehensive.\n</constraints>\n\n<query>\n{{ $json.parameters.assignments.assignments[0].value }}\n</query>\n",
        "needsFallback": true,
        "options": {
          "maxIterations": 10
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        528,
        -320
      ],
      "id": "cfe211a5-1a43-44af-9d69-0ee3ae0c8543",
      "name": "AI Orchestrator"
    },
    {
      "parameters": {
        "operation": "sendChatAction",
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}"
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        -240,
        -336
      ],
      "id": "da2e62fd-7c78-4d2b-9cfc-204d8474f20e",
      "name": "Typing Indicator",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.3,
      "position": [
        -592,
        -336
      ],
      "id": "ad85571b-f7ab-4681-955e-209bd78dcd39",
      "name": "Telegram Trigger",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Fallback": {
      "ai_languageModel": [
        [
          {
            "node": "AI Orchestrator",
            "type": "ai_languageModel",
            "index": 1
          }
        ]
      ]
    },
    "Normalize Input": {
      "main": [
        [
          {
            "node": "AI Orchestrator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Model 1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Orchestrator",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Analyst 1": {
      "ai_languageModel": [
        [
          {
            "node": "Agent - Data & Coding Analyst",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Analyst2": {
      "ai_languageModel": [
        [
          {
            "node": "Agent - Data & Coding Analyst",
            "type": "ai_languageModel",
            "index": 1
          }
        ]
      ]
    },
    "Searcher1": {
      "ai_languageModel": [
        [
          {
            "node": "Agent - Web Researcher",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Searcher2": {
      "ai_languageModel": [
        [
          {
            "node": "Agent - Web Researcher",
            "type": "ai_languageModel",
            "index": 1
          }
        ]
      ]
    },
    "Finance1": {
      "ai_languageModel": [
        [
          {
            "node": "Agent - Finance Analyst",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Finance2": {
      "ai_languageModel": [
        [
          {
            "node": "Agent - Finance Analyst",
            "type": "ai_languageModel",
            "index": 1
          }
        ]
      ]
    },
    "WebSearch2": {
      "ai_tool": [
        [
          {
            "node": "Agent - Finance Analyst",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "WebSearch1": {
      "ai_tool": [
        [
          {
            "node": "Agent - Web Researcher",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Audio file": {
      "main": [
        [
          {
            "node": "Audio data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Audio data": {
      "main": [
        [
          {
            "node": "Whisper - Transcriber",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch: Voice vs Text Input": {
      "main": [
        [
          {
            "node": "Audio file",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Normalize Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Whisper - Transcriber": {
      "main": [
        [
          {
            "node": "Converted message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Converted message": {
      "main": [
        [
          {
            "node": "Normalize Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Output Formatter": {
      "main": [
        [
          {
            "node": "Final Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Agent - Web Researcher": {
      "ai_tool": [
        [
          {
            "node": "AI Orchestrator",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Agent - Finance Analyst": {
      "ai_tool": [
        [
          {
            "node": "AI Orchestrator",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Agent - Data & Coding Analyst": {
      "ai_tool": [
        [
          {
            "node": "AI Orchestrator",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Processing Signal": {
      "main": [
        [
          {
            "node": "Typing Indicator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Orchestrator": {
      "main": [
        [
          {
            "node": "Output Formatter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Typing Indicator": {
      "main": [
        [
          {
            "node": "Switch: Voice vs Text Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Processing Signal",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate"
  },
  "versionId": "a3155b90-8082-49c1-977c-25b85ad5eded",
  "id": "aV5Bq1O1PEzuMiYl",
  "tags": []
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Telegram Orchestrator. Uses lmChatOpenRouter, httpRequestTool, telegram, httpRequest. Event-driven trigger; 25 nodes.

Source: https://github.com/a-schnu/telegram-multiagent-bot/blob/main/Telegram_Orchestrator.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Bitlab-Chatbot. Uses telegramTrigger, telegram, snowflake, httpRequest. Event-driven trigger; 87 nodes.

Telegram Trigger, Telegram, Snowflake +13
AI & RAG

AI-powered Telegram bot for effortless expense tracking. Send receipts, voice messages, or text - the bot automatically extracts and categorizes your expenses. 📸 Receipt & Invoice OCR - Send photos of

Telegram Trigger, Mcp Client Tool, Tool Calculator +7
AI & RAG

Housemate. Uses telegramTrigger, openAi, googleDrive, telegram. Event-driven trigger; 34 nodes.

Telegram Trigger, OpenAI, Google Drive +10
AI & RAG

Bot - telegram - Clima. Uses telegramTrigger, agent, lmChatOpenAi, outputParserStructured. Event-driven trigger; 21 nodes.

Telegram Trigger, Agent, OpenAI Chat +7
AI & RAG

How it works Listens to Telegram messages to detect stock-related queries. Extracts company name and identifies its exact stock ticker symbol. Searches Yahoo Finance for stock info using the ticker. F

Telegram Trigger, OpenRouter Chat, Execute Workflow Trigger +7