This workflow follows the HTTP Request → Telegram 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": "wf_main",
"nodes": [
{
"parameters": {
"content": "## wf_main\n\nTelegram entry point.\n\n**Commands:** /start, /setkey, /agents, /cancel, /help.\n**Callbacks:** agent:<id>, action:<mode>.\n**Text input in await_* state** is forwarded to wf_editor.\n\n**Credentials.** TG_BOT (Telegram), MYSQL (n8n_app).\n\n**Sub-workflow contract** (wf_main \u2192 wf_editor):\n```\n{ user_id, eleven_api_key, eleven_agent_id, mode, payload, chat_id }\n```\nmode \u2208 {prompt, welcome, kb_text, kb_url}.",
"height": 320,
"width": 600
},
"id": "sticky-readme",
"name": "README",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-200,
-100
]
},
{
"parameters": {
"updates": [
"message",
"callback_query"
],
"additionalFields": {}
},
"id": "tg-trigger",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.1,
"position": [
200,
600
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const update = $json;\nconst msg = update.message;\nconst cb = update.callback_query;\n\nlet kind = 'ignore';\nlet command = null;\nlet command_args = null;\nlet callback_payload = null;\nlet text = null;\nlet chat_id = null;\nlet telegram_user_id = null;\nlet username = null;\nlet first_name = null;\nlet callback_query_id = null;\nlet message_id = null;\n\nif (cb) {\n const data = cb.data || '';\n telegram_user_id = cb.from.id;\n username = cb.from.username || null;\n first_name = cb.from.first_name || null;\n chat_id = cb.message && cb.message.chat ? cb.message.chat.id : null;\n message_id = cb.message ? cb.message.message_id : null;\n callback_query_id = cb.id;\n\n if (data.startsWith('agent:')) {\n kind = 'callback_agent';\n callback_payload = data.slice(6);\n } else if (data.startsWith('action:')) {\n kind = 'callback_action';\n callback_payload = data.slice(7);\n }\n} else if (msg) {\n telegram_user_id = msg.from.id;\n username = msg.from.username || null;\n first_name = msg.from.first_name || null;\n chat_id = msg.chat.id;\n message_id = msg.message_id;\n text = msg.text || null;\n\n if (text && text.startsWith('/')) {\n kind = 'command';\n const parts = text.split(/\\s+/);\n command = parts[0].split('@')[0].toLowerCase();\n command_args = parts.slice(1).join(' ').trim();\n } else if (text) {\n kind = 'text_input';\n }\n}\n\nreturn [{\n json: {\n kind, command, command_args, callback_payload, text,\n telegram_user_id, username, first_name,\n chat_id, message_id, callback_query_id,\n },\n}];"
},
"id": "parse-update",
"name": "Parse Update",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
420,
600
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "INSERT INTO users (id, username, first_name) VALUES ($1, $2, $3) ON DUPLICATE KEY UPDATE username = VALUES(username), first_name = VALUES(first_name)",
"options": {
"queryBatching": "single",
"queryReplacement": "={{ $json.telegram_user_id }},{{ $json.username }},{{ $json.first_name }}"
}
},
"id": "upsert-user",
"name": "Upsert User",
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.4,
"position": [
640,
600
],
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "INSERT IGNORE INTO user_sessions (user_id) VALUES ($1)",
"options": {
"queryBatching": "single",
"queryReplacement": "={{ [$('Parse Update').first().json.telegram_user_id] }}"
}
},
"id": "ensure-session",
"name": "Ensure Session",
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.4,
"position": [
860,
600
],
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT u.eleven_api_key, s.selected_eleven_agent_id, s.state FROM users u JOIN user_sessions s ON s.user_id = u.id WHERE u.id = $1",
"options": {
"queryBatching": "single",
"queryReplacement": "={{ [$('Parse Update').first().json.telegram_user_id] }}"
}
},
"id": "get-ctx",
"name": "Get Context",
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.4,
"position": [
1080,
600
],
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $('Parse Update').first().json.kind }}",
"rightValue": "command",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "command"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $('Parse Update').first().json.kind }}",
"rightValue": "callback_agent",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "callback_agent"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $('Parse Update').first().json.kind }}",
"rightValue": "callback_action",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "callback_action"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $('Parse Update').first().json.kind }}",
"rightValue": "text_input",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "text_input"
}
]
},
"options": {
"fallbackOutput": "none"
}
},
"id": "route-by-kind",
"name": "Route by Kind",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
1300,
600
]
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $('Parse Update').first().json.command }}",
"rightValue": "/start",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "/start"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $('Parse Update').first().json.command }}",
"rightValue": "/setkey",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "/setkey"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $('Parse Update').first().json.command }}",
"rightValue": "/agents",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "/agents"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $('Parse Update').first().json.command }}",
"rightValue": "/cancel",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "/cancel"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $('Parse Update').first().json.command }}",
"rightValue": "/help",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "/help"
}
]
},
"options": {
"fallbackOutput": "extra",
"renameFallbackOutput": "other"
}
},
"id": "route-by-command",
"name": "Route by Command",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
1520,
120
]
},
{
"parameters": {
"jsCode": "const ctx = $('Parse Update').first().json;\nconst row = $('Get Context').first().json;\nconst hasKey = !!(row && row.eleven_api_key);\n\nconst lines = [\n '\ud83d\udc4b \u042f \u043f\u043e\u043c\u043e\u0433\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u0430\u0448\u0438\u043c\u0438 \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u044b\u043c\u0438 \u0430\u0433\u0435\u043d\u0442\u0430\u043c\u0438 ElevenLabs:',\n '\u2014 \u043c\u0435\u043d\u044f\u0442\u044c prompt \u0438 welcome message,',\n '\u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0435\u043a\u0441\u0442 \u0438 URL \u0432 knowledge base.',\n '',\n];\nif (hasKey) {\n lines.push('/agents \u2014 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0430\u0448\u0438\u0445 \u0430\u0433\u0435\u043d\u0442\u043e\u0432');\n lines.push('/help \u2014 \u0441\u043f\u0440\u0430\u0432\u043a\u0430');\n} else {\n lines.push('\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u0448\u043b\u0438\u0442\u0435 \u0441\u0432\u043e\u0439 API-\u043a\u043b\u044e\u0447 ElevenLabs:');\n lines.push('<code>/setkey sk_xxx</code>');\n lines.push('');\n lines.push('\u041a\u043b\u044e\u0447 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043c\u043e\u0435\u0439 \u0431\u0430\u0437\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0432\u0430\u0448\u0435\u043c\u0443 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0443 ElevenLabs.');\n}\n\nreturn [{ json: { chat_id: ctx.chat_id, text: lines.join('\\n') } }];\n"
},
"id": "build-start",
"name": "Build /start",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1740,
-120
]
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $json.chat_id }}",
"text": "={{ $json.text }}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "send-start",
"name": "Send /start",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1960,
-120
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const ctx = $('Parse Update').first().json;\nconst key = (ctx.command_args || '').trim();\n\nif (!key) {\n return [{ json: { chat_id: ctx.chat_id, valid_format: false, msg: '\u26a0\ufe0f \u041f\u0440\u0438\u0448\u043b\u0438\u0442\u0435 \u043a\u043b\u044e\u0447 \u0442\u0430\u043a:\\n<code>/setkey sk_xxx</code>' } }];\n}\nif (key.length < 20) {\n return [{ json: { chat_id: ctx.chat_id, valid_format: false, msg: '\u26a0\ufe0f \u0421\u043b\u0438\u0448\u043a\u043e\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u043a\u043b\u044e\u0447 \u2014 \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 API-key ElevenLabs.' } }];\n}\nreturn [{ json: { chat_id: ctx.chat_id, valid_format: true, key } }];"
},
"id": "setkey-parse",
"name": "Parse /setkey",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1740,
80
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $json.valid_format }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
]
}
},
"id": "setkey-if-format",
"name": "IF /setkey format",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1960,
80
]
},
{
"parameters": {
"method": "GET",
"url": "https://api.elevenlabs.io/v1/user",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "xi-api-key",
"value": "={{ $json.key }}"
}
]
},
"options": {
"timeout": 10000,
"response": {
"response": {
"fullResponse": true,
"neverError": true
}
}
}
},
"id": "setkey-validate",
"name": "Validate Key via /v1/user",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2180,
0
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "loose",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $json.statusCode }}",
"rightValue": 400,
"operator": {
"type": "number",
"operation": "lt"
}
}
]
}
},
"id": "setkey-if-ok",
"name": "IF key accepted",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
2400,
0
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "UPDATE users SET eleven_api_key = $1 WHERE id = $2",
"options": {
"queryBatching": "single",
"queryReplacement": "={{ $('Parse /setkey').first().json.key }},{{ $('Parse Update').first().json.telegram_user_id }}"
}
},
"id": "setkey-save",
"name": "Save Key",
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.4,
"position": [
2620,
-80
],
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $('Parse Update').first().json.chat_id }}",
"text": "\u2705 \u041a\u043b\u044e\u0447 \u043f\u0440\u0438\u043d\u044f\u0442 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d. /agents \u2014 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0430\u0448\u0438\u0445 \u0430\u0433\u0435\u043d\u0442\u043e\u0432.",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "send-setkey-ok",
"name": "Send /setkey ok",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2840,
-80
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $('Parse Update').first().json.chat_id }}",
"text": "=\u274c ElevenLabs \u043e\u0442\u0432\u0435\u0440\u0433 \u043a\u043b\u044e\u0447 (\u043a\u043e\u0434 {{ $('Validate Key via /v1/user').first().json.statusCode }}). \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u0447\u0442\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u0438\u0437 Profile \u2192 API Keys.",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "send-setkey-bad",
"name": "Send /setkey bad",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2620,
100
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $json.chat_id }}",
"text": "={{ $json.msg }}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "send-setkey-format-err",
"name": "Send /setkey format err",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2180,
180
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const ctx = $('Parse Update').first().json;\nconst row = $('Get Context').first().json;\nconst hasKey = !!(row && row.eleven_api_key);\nreturn [{ json: { chat_id: ctx.chat_id, has_key: hasKey, api_key: hasKey ? row.eleven_api_key : null } }];"
},
"id": "agents-ctx",
"name": "Agents \u2014 check key",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1740,
300
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $json.has_key }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
]
}
},
"id": "agents-if-key",
"name": "IF has key",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1960,
300
]
},
{
"parameters": {
"method": "GET",
"url": "https://api.elevenlabs.io/v1/convai/agents",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "xi-api-key",
"value": "={{ $json.api_key }}"
}
]
},
"options": {
"timeout": 15000,
"response": {
"response": {
"fullResponse": true,
"neverError": true
}
}
}
},
"id": "agents-fetch",
"name": "Fetch Agents",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2180,
220
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"jsCode": "const ctx = $('Parse Update').first().json;\nconst resp = $json;\nconst code = resp.statusCode;\nconst body = resp.body || resp;\n\nif (code >= 400) {\n return [{ json: { chat_id: ctx.chat_id, text: `\u274c ElevenLabs \u0432\u0435\u0440\u043d\u0443\u043b ${code} \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0433\u0435\u043d\u0442\u043e\u0432. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043a\u043b\u044e\u0447 \u0443\u0441\u0442\u0430\u0440\u0435\u043b \u2014 /setkey <\u043d\u043e\u0432\u044b\u0439>.`, reply_markup: null } }];\n}\n\n// ElevenLabs Convai response shape: { agents: [{agent_id, name, ...}], has_more, next_cursor }\nconst agents = (body && Array.isArray(body.agents)) ? body.agents : [];\n\nif (agents.length === 0) {\n return [{ json: { chat_id: ctx.chat_id, text: '\u0423 \u0432\u0430\u0441 \u043f\u043e\u043a\u0430 \u043d\u0435\u0442 \u0430\u0433\u0435\u043d\u0442\u043e\u0432 \u0432 ElevenLabs. \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0430\u0433\u0435\u043d\u0442\u0430 \u0432 ElevenLabs Console \u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430.', reply_markup: null } }];\n}\n\nconst inline_keyboard = agents.map(a => [{ text: a.name || a.agent_id, callback_data: `agent:${a.agent_id}` }]);\nreturn [{ json: { chat_id: ctx.chat_id, text: '\ud83c\udf99 \u0412\u0430\u0448\u0438 \u0430\u0433\u0435\u043d\u0442\u044b:', reply_markup: { inline_keyboard } } }];"
},
"id": "agents-build",
"name": "Build Agents Keyboard",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2400,
220
]
},
{
"parameters": {
"method": "POST",
"url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({chat_id: $json.chat_id, text: $json.text, parse_mode: 'HTML', reply_markup: $json.reply_markup}) }}",
"options": {
"response": {
"response": {
"fullResponse": true,
"neverError": true
}
}
}
},
"id": "agents-send",
"name": "Send Agents",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2620,
220
]
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $('Parse Update').first().json.chat_id }}",
"text": "\ud83d\udd11 \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u0448\u043b\u0438\u0442\u0435 \u0441\u0432\u043e\u0439 ElevenLabs API \u043a\u043b\u044e\u0447:\n<code>/setkey sk_xxx</code>",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "agents-no-key",
"name": "Send no key (/agents)",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2180,
400
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "UPDATE user_sessions SET state = 'idle' WHERE user_id = $1",
"options": {
"queryBatching": "single",
"queryReplacement": "={{ [$('Parse Update').first().json.telegram_user_id] }}"
}
},
"id": "cancel-update",
"name": "Cancel: reset state",
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.4,
"position": [
1740,
500
],
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $('Parse Update').first().json.chat_id }}",
"text": "\ud83d\udd04 \u041e\u0442\u043c\u0435\u043d\u0435\u043d\u043e.",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "send-cancel",
"name": "Send /cancel",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1960,
500
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $('Parse Update').first().json.chat_id }}",
"text": "\ud83d\udcd6 <b>\u041a\u043e\u043c\u0430\u043d\u0434\u044b</b>\n/start \u2014 \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435\n/setkey <key> \u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0430\u0448 ElevenLabs API-\u043a\u043b\u044e\u0447\n/agents \u2014 \u043c\u043e\u0438 \u0430\u0433\u0435\u043d\u0442\u044b\n/cancel \u2014 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e\n/help \u2014 \u044d\u0442\u0430 \u0441\u043f\u0440\u0430\u0432\u043a\u0430\n\n<b>\u041a\u0430\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430:</b>\n1. /setkey sk_xxx \u2014 \u043e\u0434\u0438\u043d \u0440\u0430\u0437, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0432\u0430\u0448 \u043a\u043b\u044e\u0447\n2. /agents \u2192 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430 \u043a\u043d\u043e\u043f\u043a\u043e\u0439\n3. \u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435: Prompt / Welcome / KB\n4. \u041f\u0440\u0438\u0441\u043b\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u043c\n\n<b>\u041a\u0430\u043a \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0441 \u0430\u0433\u0435\u043d\u0442\u043e\u043c:</b>\n\u0421\u0430\u043c \u0440\u0430\u0437\u0433\u043e\u0432\u043e\u0440 \u0438\u0434\u0451\u0442 \u0432 ElevenLabs Console: \u0432\u0430\u0448 \u0430\u0433\u0435\u043d\u0442 \u2192 \u043a\u043d\u043e\u043f\u043a\u0430 <b>Test agent</b>. \u0411\u043e\u0442 \u043c\u0435\u043d\u044f\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0430\u0433\u0435\u043d\u0442\u0430, \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u043e\u0439 \u0440\u0430\u0437\u0433\u043e\u0432\u043e\u0440 \u0432\u0435\u0434\u0451\u0442\u0441\u044f \u0432 Console \u0438\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 \u0432\u0438\u0434\u0436\u0435\u0442/SDK ElevenLabs.",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "send-help",
"name": "Send /help",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1740,
700
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/answerCallbackQuery",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({callback_query_id: $('Parse Update').first().json.callback_query_id}) }}",
"options": {
"response": {
"response": {
"fullResponse": true,
"neverError": true
}
}
}
},
"id": "answer-cb-agent",
"name": "Answer CB (agent)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1520,
850
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "UPDATE user_sessions SET selected_eleven_agent_id = $1, state = 'idle' WHERE user_id = $2",
"options": {
"queryBatching": "single",
"queryReplacement": "={{ $('Parse Update').first().json.callback_payload }},{{ $('Parse Update').first().json.telegram_user_id }}"
}
},
"id": "set-selected-agent",
"name": "Set Selected Agent",
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.4,
"position": [
1740,
850
],
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $('Parse Update').first().json.chat_id }}",
"text": "=\u2705 \u0410\u0433\u0435\u043d\u0442 \u0432\u044b\u0431\u0440\u0430\u043d: <code>{{ $('Parse Update').first().json.callback_payload }}</code>\n\n\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435:",
"replyMarkup": "inlineKeyboard",
"inlineKeyboard": {
"rows": [
{
"row": {
"buttons": [
{
"text": "\u270f\ufe0f Prompt",
"additionalFields": {
"callback_data": "action:prompt"
}
},
{
"text": "\ud83d\udcac Welcome",
"additionalFields": {
"callback_data": "action:welcome"
}
}
]
}
},
{
"row": {
"buttons": [
{
"text": "\ud83d\udcda KB: \u0442\u0435\u043a\u0441\u0442",
"additionalFields": {
"callback_data": "action:kb_text"
}
},
{
"text": "\ud83d\udcda KB: URL",
"additionalFields": {
"callback_data": "action:kb_url"
}
}
]
}
}
]
},
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "send-action-menu",
"name": "Send Action Menu",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1960,
850
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/answerCallbackQuery",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({callback_query_id: $('Parse Update').first().json.callback_query_id}) }}",
"options": {
"response": {
"response": {
"fullResponse": true,
"neverError": true
}
}
}
},
"id": "answer-cb-action",
"name": "Answer CB (action)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1520,
1080
]
},
{
"parameters": {
"jsCode": "const ctx = $('Parse Update').first().json;\nconst session = $('Get Context').first().json;\nconst mode = ctx.callback_payload;\n\nconst modeConfig = {\n prompt: { state: 'await_prompt', text: '\u270f\ufe0f \u041f\u0440\u0438\u0448\u043b\u0438\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 <b>prompt</b> (1\u201310 000 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432).\\n/cancel \u2014 \u043e\u0442\u043c\u0435\u043d\u0430.' },\n welcome: { state: 'await_welcome', text: '\ud83d\udcac \u041f\u0440\u0438\u0448\u043b\u0438\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 <b>welcome message</b> (1\u20131 000 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432).\\n/cancel \u2014 \u043e\u0442\u043c\u0435\u043d\u0430.' },\n kb_text: { state: 'await_kb_text', text: '\ud83d\udcda \u041f\u0440\u0438\u0448\u043b\u0438\u0442\u0435 <b>\u0442\u0435\u043a\u0441\u0442</b> \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 knowledge base.\\n/cancel \u2014 \u043e\u0442\u043c\u0435\u043d\u0430.' },\n kb_url: { state: 'await_kb_url', text: '\ud83d\udcda \u041f\u0440\u0438\u0448\u043b\u0438\u0442\u0435 <b>URL</b> (https://...) \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 knowledge base.\\n/cancel \u2014 \u043e\u0442\u043c\u0435\u043d\u0430.' },\n};\n\nif (!session || !session.selected_eleven_agent_id) {\n return [{ json: { chat_id: ctx.chat_id, text: '\u26a0\ufe0f \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0430\u0433\u0435\u043d\u0442\u0430: /agents', valid: false } }];\n}\nconst cfg = modeConfig[mode];\nif (!cfg) {\n return [{ json: { chat_id: ctx.chat_id, text: '\u26a0\ufe0f \u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435.', valid: false } }];\n}\nreturn [{ json: {\n chat_id: ctx.chat_id,\n text: cfg.text,\n new_state: cfg.state,\n telegram_user_id: ctx.telegram_user_id,\n valid: true,\n} }];"
},
"id": "build-action-prompt",
"name": "Build Action Prompt",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1740,
1080
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $json.valid }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
]
}
},
"id": "if-valid-action",
"name": "IF action valid",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1960,
1080
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "UPDATE user_sessions SET state = $1 WHERE user_id = $2",
"options": {
"queryBatching": "single",
"queryReplacement": "={{ $json.new_state }},{{ $json.telegram_user_id }}"
}
},
"id": "set-await-state",
"name": "Set Await State",
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.4,
"position": [
2180,
1000
],
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $('Build Action Prompt').first().json.chat_id }}",
"text": "={{ $('Build Action Prompt').first().json.text }}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "send-action-prompt",
"name": "Send Action Prompt",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2400,
1000
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $json.chat_id }}",
"text": "={{ $json.text }}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "send-action-error",
"name": "Send Action Error",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2180,
1180
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "or",
"conditions": [
{
"leftValue": "={{ $('Get Context').first().json.state }}",
"rightValue": "await_prompt",
"operator": {
"type": "string",
"operation": "equals"
}
},
{
"leftValue": "={{ $('Get Context').first().json.state }}",
"rightValue": "await_welcome",
"operator": {
"type": "string",
"operation": "equals"
}
},
{
"leftValue": "={{ $('Get Context').first().json.state }}",
"rightValue": "await_kb_text",
"operator": {
"type": "string",
"operation": "equals"
}
},
{
"leftValue": "={{ $('Get Context').first().json.state }}",
"rightValue": "await_kb_url",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "await"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 2
},
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $('Get Context').first().json.state }}",
"rightValue": "processing",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "processing"
}
]
},
"options": {
"fallbackOutput": "extra",
"renameFallbackOutput": "idle"
}
},
"id": "route-by-state",
"name": "Route by State",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
1520,
1400
]
},
{
"parameters": {
"jsCode": "const ctx = $('Parse Update').first().json;\nconst session = $('Get Context').first().json;\nconst stateToMode = { await_prompt: 'prompt', await_welcome: 'welcome', await_kb_text: 'kb_text', await_kb_url: 'kb_url' };\nconst mode = stateToMode[session.state];\nreturn [{ json: {\n user_id: ctx.telegram_user_id,\n eleven_api_key: session.eleven_api_key,\n eleven_agent_id: session.selected_eleven_agent_id,\n mode,\n payload: ctx.text,\n chat_id: ctx.chat_id,\n} }];"
},
"id": "prepare-editor-call",
"name": "Prepare Editor Call",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1740,
1300
]
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "REPLACE_WITH_WF_EDITOR_ID",
"mode": "id"
},
"workflowInputs": {
"mappingMode": "passThrough"
},
"options": {}
},
"id": "exec-editor",
"name": "Execute wf_editor",
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.2,
"position": [
1960,
1300
]
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $('Parse Update').first().json.chat_id }}",
"text": "\u23f3 \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0435\u0449\u0451 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f. \u041f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434 \u0438\u043b\u0438 /cancel.",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "send-processing",
"name": "Send Processing",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1740,
1500
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const ctx = $('Parse Update').first().json;\nconst row = $('Get Context').first().json;\nconst hasKey = !!(row && row.eleven_api_key);\nconst text = hasKey\n ? '\u041d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e. \u041d\u0430\u0436\u043c\u0438\u0442\u0435 /agents, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430 \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435.'\n : '\ud83d\udd11 \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u0448\u043b\u0438\u0442\u0435 \u0441\u0432\u043e\u0439 API-\u043a\u043b\u044e\u0447:\\n<code>/setkey sk_xxx</code>';\nreturn [{ json: { chat_id: ctx.chat_id, text } }];"
},
"id": "idle-hint-build",
"name": "Build Idle Hint",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1740,
1700
]
},
{
"parameters": {
"operation": "sendMessage",
"chatId": "={{ $json.chat_id }}",
"text": "={{ $json.text }}",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"id": "send-idle-hint",
"name": "Send Idle Hint",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1960,
1700
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Telegram Trigger": {
"main": [
[
{
"node": "Parse Update",
"type": "main",
"index": 0
}
]
]
},
"Parse Update": {
"main": [
[
{
"node": "Upsert User",
"type": "main",
"index": 0
}
]
]
},
"Upsert User": {
"main": [
[
{
"node": "Ensure Session",
"type": "main",
"index": 0
}
]
]
},
"Ensure Session": {
"main": [
[
{
"node": "Get Context",
"type": "main",
"index": 0
}
]
]
},
"Get Context": {
"main": [
[
{
"node": "Route by Kind",
"type": "main",
"index": 0
}
]
]
},
"Route by Kind": {
"main": [
[
{
"node": "Route by Command",
"type": "main",
"index": 0
}
],
[
{
"node": "Answer CB (agent)",
"type": "main",
"index": 0
}
],
[
{
"node": "Answer CB (action)",
"type": "main",
"index": 0
}
],
[
{
"node": "Route by State",
"type": "main",
"index": 0
}
]
]
},
"Route by Command": {
"main": [
[
{
"node": "Build /start",
"type": "main",
"index": 0
}
],
[
{
"node": "Parse /setkey",
"type": "main",
"index": 0
}
],
[
{
"node": "Agents \u2014 check key",
"type": "main",
"index": 0
}
],
[
{
"node": "Cancel: reset state",
"type": "main",
"index": 0
}
],
[
{
"node": "Send /help",
"type": "main",
"index": 0
}
]
]
},
"Build /start": {
"main": [
[
{
"node": "Send /start",
"type": "main",
"index": 0
}
]
]
},
"Parse /setkey": {
"main": [
[
{
"node": "IF /setkey format",
"type": "main",
"index": 0
}
]
]
},
"IF /setkey format": {
"main": [
[
{
"node": "Validate Key via /v1/user",
"type": "main",
"index": 0
}
],
[
{
"node": "Send /setkey format err",
"type": "main",
"index": 0
}
]
]
},
"Validate Key via /v1/user": {
"main": [
[
{
"node": "IF key accepted",
"type": "main",
"index": 0
}
]
]
},
"IF key accepted": {
"main": [
[
{
"node": "Save Key",
"type": "main",
"index": 0
}
],
[
{
"node": "Send /setkey bad",
"type": "main",
"index": 0
}
]
]
},
"Save Key": {
"main": [
[
{
"node": "Send /setkey ok",
"type": "main",
"index": 0
}
]
]
},
"Agents \u2014 check key": {
"main": [
[
{
"node": "IF has key",
"type": "main",
"index": 0
}
]
]
},
"IF has key": {
"main": [
[
{
"node": "Fetch Agents",
"type": "main",
"index": 0
}
],
[
{
"node": "Send no key (/agents)",
"type": "main",
"index": 0
}
]
]
},
"Fetch Agents": {
"main": [
[
{
"node": "Build Agents Keyboard",
"type": "main",
"index": 0
}
]
]
},
"Build Agents Keyboard": {
"main": [
[
{
"node": "Send Agents",
"type": "main",
"index": 0
}
]
]
},
"Cancel: reset state": {
"main": [
[
{
"node": "Send /cancel",
"type": "main",
"index": 0
}
]
]
},
"Answer CB (agent)": {
"main": [
[
{
"node": "Set Selected Agent",
"type": "main",
"index": 0
}
]
]
},
"Set Selected Agent": {
"main": [
[
{
"node": "Send Action Menu",
"type": "main",
"index": 0
}
]
]
},
"Answer CB (action)": {
"main": [
[
{
"node": "Build Action Prompt",
"type": "main",
"index": 0
}
]
]
},
"Build Action Prompt": {
"main": [
[
{
"node": "IF action valid",
"type": "main",
"index": 0
}
]
]
},
"IF action valid": {
"main": [
[
{
"node": "Set Await State",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Action Error",
"type": "main",
"index": 0
}
]
]
},
"Set Await State": {
"main": [
[
{
"node": "Send Action Prompt",
"type": "main",
"index": 0
}
]
]
},
"Route by State": {
"main": [
[
{
"node": "Prepare Editor Call",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Processing",
"type": "main",
"index": 0
}
],
[
{
"node": "Build Idle Hint",
"type": "main",
"index": 0
}
]
]
},
"Prepare Editor Call": {
"main": [
[
{
"node": "Execute wf_editor",
"type": "main",
"index": 0
}
]
]
},
"Build Idle Hint": {
"main": [
[
{
"node": "Send Idle Hint",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"tags": [],
"versionId": "wfm-v3-init"
}
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.
mySqltelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
wf_main. Uses telegramTrigger, mySql, telegram, httpRequest. Event-driven trigger; 42 nodes.
Source: https://github.com/ocaflash/elevenlabs_bot/blob/b2ae902f5960b38fdfafc9d3446e653c9233c80e/workflows/wf_main.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.
N8N Complete Final. Uses telegramTrigger, dataTable, telegram, mqtt. Event-driven trigger; 58 nodes.
Pede Ai. Uses httpRequest, telegram, postgres, telegramTrigger. Event-driven trigger; 57 nodes.
TextMain. Uses telegramTrigger, stopAndError, telegram, httpRequest. Event-driven trigger; 56 nodes.
Pede Ai. Uses httpRequest, telegram, postgres, telegramTrigger. Event-driven trigger; 53 nodes.
📄 Documentation: Notion Guide