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 →
{
"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, '&').replace(/</g, '<').replace(/>/g, '>');\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.
httpBearerAuthhttpHeaderAuthopenRouterApitelegramApi
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 →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Bitlab-Chatbot. Uses telegramTrigger, telegram, snowflake, httpRequest. Event-driven trigger; 87 nodes.
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
Housemate. Uses telegramTrigger, openAi, googleDrive, telegram. Event-driven trigger; 34 nodes.
Bot - telegram - Clima. Uses telegramTrigger, agent, lmChatOpenAi, outputParserStructured. Event-driven trigger; 21 nodes.
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