This workflow follows the HTTP Request → Redis 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 Meditation Bot (Fixed with State)",
"nodes": [
{
"parameters": {
"updates": [
"message"
]
},
"id": "1",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1,
"position": [
250,
300
]
},
{
"parameters": {
"operation": "get",
"key": "={{$json.message.chat.id}}_state"
},
"id": "2",
"name": "Get User State",
"type": "n8n-nodes-base.redis",
"typeVersion": 1,
"position": [
450,
300
],
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const message = $('Telegram Trigger').first().json.message || {};\nconst stateNode = $('Get User State').first();\n\nlet state = {};\ntry {\n if (stateNode.json && stateNode.json.value) {\n state = JSON.parse(stateNode.json.value);\n }\n} catch (e) {\n state = {};\n}\n\nconst chatId = message.chat?.id;\nconst messageText = (message.text || '').toLowerCase().trim();\n\n// Fail-safe \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0448\u0430\u0433\u0430: \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 state, \u0441\u0447\u0438\u0442\u0430\u0435\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0441\u0438\u043c \u0438\u043c\u044f\nlet currentStep;\nif (state.step) {\n currentStep = state.step;\n} else if (messageText.startsWith('/start') || messageText.includes('\u0441\u0442\u0430\u0440\u0442') || messageText.includes('\u043c\u0435\u0434\u0438\u0442\u0430\u0446')) {\n currentStep = 'start';\n} else {\n currentStep = 'awaiting_name';\n}\n\nreturn {\n json: {\n chatId,\n messageText,\n currentStep,\n state\n }\n};"
},
"id": "3",
"name": "Parse State",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
650,
300
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.currentStep}}",
"value2": "start"
}
]
}
},
"id": "4",
"name": "Check Step: Start",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
850,
300
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.messageText}}",
"operation": "contains",
"value2": "\u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438"
}
]
}
},
"id": "5",
"name": "Check Meditation Request",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1050,
200
]
},
{
"parameters": {
"chatId": "={{$json.chatId}}",
"text": "\u041e\u0442\u043b\u0438\u0447\u043d\u043e! \u042f \u043f\u043e\u043c\u043e\u0433\u0443 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u044e \ud83e\uddd8\u200d\u2642\ufe0f\n\n\u041a\u0430\u043a \u0442\u0435\u0431\u044f \u0437\u043e\u0432\u0443\u0442?",
"additionalFields": {
"replyMarkup": "json",
"replyMarkupJson": "={{ JSON.stringify({ remove_keyboard: true }) }}"
}
},
"id": "6",
"name": "Ask Name",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
1250,
150
]
},
{
"parameters": {
"operation": "set",
"key": "={{$json.chatId}}_state",
"value": "={{ JSON.stringify({ step: 'awaiting_name' }) }}",
"ttl": 3600
},
"id": "7",
"name": "Save State: Awaiting Name",
"type": "n8n-nodes-base.redis",
"typeVersion": 1,
"position": [
1450,
150
]
},
{
"parameters": {
"chatId": "={{$json.chatId}}",
"text": "\u041f\u0440\u0438\u0432\u0435\u0442! \ud83d\udc4b\n\n\u042f \u0441\u043e\u0437\u0434\u0430\u044e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u0438 \u0441 \u0433\u043e\u043b\u043e\u0441\u043e\u043c.\n\n\u041d\u0430\u0436\u043c\u0438 \u043a\u043d\u043e\u043f\u043a\u0443 \u043d\u0438\u0436\u0435, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c! \ud83e\uddd8\u200d\u2642\ufe0f",
"additionalFields": {
"replyMarkup": "json",
"replyMarkupJson": "={{ JSON.stringify({ keyboard: [[{ text: '\u0425\u043e\u0447\u0443 \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u044e' }]], resize_keyboard: true, one_time_keyboard: true }) }}"
}
},
"id": "8",
"name": "Welcome Message",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
1250,
250
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.currentStep}}",
"value2": "awaiting_name"
}
]
}
},
"id": "9",
"name": "Check Step: Name",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
850,
500
]
},
{
"parameters": {
"jsCode": "const data = $input.first().json;\nconst message = $('Telegram Trigger').first().json.message;\n\nreturn {\n json: {\n chatId: data.chatId,\n userName: message.text\n }\n};"
},
"id": "10",
"name": "Extract Name",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1050,
500
]
},
{
"parameters": {
"chatId": "={{$json.chatId}}",
"text": "\u041f\u0440\u0438\u044f\u0442\u043d\u043e \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f, {{$json.userName}}! \ud83d\ude0a\n\n\u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0438, \u0447\u0442\u043e \u0445\u043e\u0447\u0435\u0448\u044c \u043f\u0440\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u0438?\n\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: \u0441\u043d\u044f\u0442\u044c \u0441\u0442\u0440\u0435\u0441\u0441, \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0441\u043e\u043d, \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044c..."
},
"id": "11",
"name": "Ask Goal",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
1250,
500
]
},
{
"parameters": {
"operation": "set",
"key": "={{$json.chatId}}_state",
"value": "={{ JSON.stringify({ step: 'awaiting_goal', userName: $json.userName }) }}",
"ttl": 3600
},
"id": "12",
"name": "Save State: Awaiting Goal",
"type": "n8n-nodes-base.redis",
"typeVersion": 1,
"position": [
1450,
500
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.currentStep}}",
"value2": "awaiting_goal"
}
]
}
},
"id": "13",
"name": "Check Step: Goal",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
850,
700
]
},
{
"parameters": {
"jsCode": "const data = $input.first().json;\nconst message = $('Telegram Trigger').first().json.message;\n\nreturn {\n json: {\n chatId: data.chatId,\n userName: data.state.userName,\n goal: message.text\n }\n};"
},
"id": "14",
"name": "Extract Goal",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1050,
700
]
},
{
"parameters": {
"method": "POST",
"url": "https://hubai.loe.gg/v1/chat/completions",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer sk-snQnp85cGcPTjEtjbKFixg"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"model\": \"gpt-4o-mini\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"\u0422\u044b \u043c\u043e\u0434\u0435\u0440\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u0439. \u0422\u0432\u043e\u044f \u0437\u0430\u0434\u0430\u0447\u0430 - \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0439 \u0446\u0435\u043b\u044c\u044e \u0434\u043b\u044f \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u0438. \u0412\u0430\u043b\u0438\u0434\u043d\u044b\u0435 \u0446\u0435\u043b\u0438: \u0440\u0430\u0431\u043e\u0442\u0430 \u0441\u043e \u0441\u0442\u0440\u0435\u0441\u0441\u043e\u043c, \u0442\u0440\u0435\u0432\u043e\u0433\u043e\u0439, \u0441\u043d\u043e\u043c, \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e, \u0446\u0435\u043b\u044f\u043c\u0438, \u043c\u0435\u0447\u0442\u0430\u043c\u0438, \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f\u043c\u0438, \u0437\u0434\u043e\u0440\u043e\u0432\u044c\u0435\u043c, \u044d\u043c\u043e\u0446\u0438\u044f\u043c\u0438. \u041d\u0415\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0435: \u043f\u0440\u043e\u0441\u044c\u0431\u044b \u043e \u043d\u0430\u0441\u0438\u043b\u0438\u0438, \u0445\u0443\u043b\u0438\u0433\u0430\u043d\u0441\u0442\u0432\u043e, \u043e\u0441\u043a\u043e\u0440\u0431\u043b\u0435\u043d\u0438\u044f, \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430, NSFW \u043a\u043e\u043d\u0442\u0435\u043d\u0442.\\n\\n\u041e\u0442\u0432\u0435\u0442\u044c \u0422\u041e\u041b\u042c\u041a\u041e 'valid' \u0438\u043b\u0438 'invalid'.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"\u041f\u0440\u043e\u0432\u0435\u0440\u044c \u0437\u0430\u043f\u0440\u043e\u0441: {{ $json.goal }}\"\n }\n ],\n \"temperature\": 0.3,\n \"max_tokens\": 10\n}",
"options": {}
},
"id": "23",
"name": "Validate Goal",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1250,
700
]
},
{
"parameters": {
"jsCode": "const response = $input.first().json;\nconst userData = $('Extract Goal').first().json;\n\nlet validationResult = '';\ntry {\n validationResult = response.choices[0].message.content.toLowerCase().trim();\n} catch (e) {\n validationResult = 'valid'; // \u041d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c\n}\n\nconst isValid = validationResult.includes('valid') && !validationResult.includes('invalid');\n\nreturn {\n json: {\n chatId: userData.chatId,\n userName: userData.userName,\n goal: userData.goal,\n isValid: isValid\n }\n};"
},
"id": "24",
"name": "Check Validation Result",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1450,
700
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json.isValid}}",
"value2": true
}
]
}
},
"id": "25",
"name": "Is Goal Valid?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1650,
700
]
},
{
"parameters": {
"chatId": "={{$json.chatId}}",
"text": "\u0418\u0437\u0432\u0438\u043d\u0438, \u043d\u043e \u044f \u043d\u0435 \u043c\u043e\u0433\u0443 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u044e \u043d\u0430 \u044d\u0442\u0443 \u0442\u0435\u043c\u0443 \ud83d\ude14\n\n\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0438\u043b\u0438 \u0446\u0435\u043b\u044c, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u0443\u044e \u0441:\n\u2022 \u0421\u043d\u044f\u0442\u0438\u0435\u043c \u0441\u0442\u0440\u0435\u0441\u0441\u0430 \u0438\u043b\u0438 \u0442\u0440\u0435\u0432\u043e\u0433\u0438\n\u2022 \u0423\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0435\u043c \u0441\u043d\u0430\n\u2022 \u041f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u0435\u043c \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438\n\u2022 \u0414\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0435\u043c \u0446\u0435\u043b\u0435\u0439 \u0438 \u043c\u0435\u0447\u0442\n\u2022 \u0420\u0430\u0431\u043e\u0442\u043e\u0439 \u0441 \u044d\u043c\u043e\u0446\u0438\u044f\u043c\u0438\n\n\u041d\u0430\u043f\u0438\u0448\u0438 \u0441\u0432\u043e\u044e \u0446\u0435\u043b\u044c \u0437\u0430\u043d\u043e\u0432\u043e \ud83d\ude4f"
},
"id": "26",
"name": "Reject Invalid Goal",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
1850,
800
]
},
{
"parameters": {
"chatId": "={{$json.chatId}}",
"text": "\u041e\u0442\u043b\u0438\u0447\u043d\u043e! \u0421\u043e\u0437\u0434\u0430\u044e \u0442\u0432\u043e\u044e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u044e... \u23f3"
},
"id": "15",
"name": "Processing Message",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
1850,
600
]
},
{
"parameters": {
"method": "POST",
"url": "https://hubai.loe.gg/v1/chat/completions",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer sk-snQnp85cGcPTjEtjbKFixg"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"model\": \"gpt-4o\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"\u0422\u044b \u043e\u043f\u044b\u0442\u043d\u044b\u0439 \u043c\u0430\u0441\u0442\u0435\u0440 \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u0438. \u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0439 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0442\u0435\u043a\u0441\u0442\u044b \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u0439. \u0421\u0442\u0438\u043b\u044c: \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u044b\u0439, \u043c\u044f\u0433\u043a\u0438\u0439, \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0449\u0438\u0439. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043d\u0430 '\u0442\u044b'.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"\u0421\u043e\u0437\u0434\u0430\u0439 \u0442\u0435\u043a\u0441\u0442 \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u0438 \u0434\u043b\u044f {{ $json.userName }}.\\n\\n\u0426\u0435\u043b\u044c: {{ $json.goal }}\\n\\n\u0422\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f:\\n- \u041a\u041e\u0420\u041e\u0422\u041a\u0410\u042f \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u044f \u043d\u0430 2-3 \u043c\u0438\u043d\u0443\u0442\u044b \u0447\u0442\u0435\u043d\u0438\u044f (\u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430!)\\n- \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430: \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435, \u0431\u044b\u0441\u0442\u0440\u0430\u044f \u0440\u0435\u043b\u0430\u043a\u0441\u0430\u0446\u0438\u044f, \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0446\u0435\u043b\u044c\u044e, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\\n- \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \u0438\u043c\u044f 1-2 \u0440\u0430\u0437\u0430\\n- \u0414\u043e\u0431\u0430\u0432\u044c \u043f\u0430\u0443\u0437\u044b: [\u043f\u0430\u0443\u0437\u0430 3 \u0441\u0435\u043a], [\u0433\u043b\u0443\u0431\u043e\u043a\u0438\u0439 \u0432\u0434\u043e\u0445]\\n- \u041d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435\\n- \u0422\u0435\u043a\u0441\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u044b\u043c \u0438 \u0440\u0430\u0441\u0441\u043b\u0430\u0431\u043b\u044f\u044e\u0449\u0438\u043c\\n- \u0411\u0435\u0437 \u043b\u0438\u0448\u043d\u0438\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432, \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u043a\u0441\u0442 \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u0438\\n- \u0412\u0410\u0416\u041d\u041e: \u0442\u0435\u043a\u0441\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u043c, \u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 400-500 \u0441\u043b\u043e\u0432\"\n }\n ],\n \"temperature\": 0.8,\n \"max_tokens\": 800\n}",
"options": {}
},
"id": "16",
"name": "Generate Meditation Text",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2050,
600
]
},
{
"parameters": {
"jsCode": "const response = $input.first().json;\nconst userData = $('Extract Goal').first().json;\n\nlet meditationText = '';\ntry {\n meditationText = response.choices[0].message.content;\n} catch (e) {\n throw new Error('\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u043e\u0442 OpenAI: ' + e.message);\n}\n\nreturn {\n json: {\n chatId: userData.chatId,\n userName: userData.userName,\n goal: userData.goal,\n meditationText: meditationText\n }\n};"
},
"id": "17",
"name": "Extract Meditation Text",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2250,
600
]
},
{
"parameters": {
"method": "POST",
"url": "https://hubai.loe.gg/v1/audio/speech",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer sk-snQnp85cGcPTjEtjbKFixg"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"model\": \"tts-1-hd\",\n \"voice\": \"nova\",\n \"input\": {{ JSON.stringify($json.meditationText) }},\n \"speed\": 0.85\n}",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"id": "18",
"name": "Generate Audio (TTS)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2450,
600
]
},
{
"parameters": {
"jsCode": "const userData = $('Extract Meditation Text').first().json;\nconst audioData = $input.first().binary.data;\n\nreturn {\n json: {\n chatId: userData.chatId,\n userName: userData.userName,\n goal: userData.goal,\n caption: `\u2728 \u0422\u0432\u043e\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u044f \u0433\u043e\u0442\u043e\u0432\u0430, ${userData.userName}! \ud83c\udfb5\\n\\n\ud83c\udfaf \u0426\u0435\u043b\u044c: ${userData.goal}\\n\\n\ud83c\udfa7 \u041d\u0430\u0439\u0434\u0438 \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e, \u043d\u0430\u0434\u0435\u043d\u044c \u043d\u0430\u0443\u0448\u043d\u0438\u043a\u0438 \u0438 \u043f\u043e\u0433\u0440\u0443\u0437\u0438\u0441\u044c \u0432 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0443.\\n\\n\u041f\u0440\u0438\u044f\u0442\u043d\u043e\u0439 \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u0438! \ud83e\uddd8\u200d\u2642\ufe0f`\n },\n binary: {\n audio: audioData\n }\n};"
},
"id": "19",
"name": "Prepare Final Message",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2650,
600
]
},
{
"parameters": {
"resource": "message",
"operation": "sendAudio",
"chatId": "={{$json.chatId}}",
"binaryData": true,
"binaryPropertyName": "audio",
"additionalFields": {
"caption": "={{$json.caption}}",
"title": "\u041f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u044f"
}
},
"id": "20",
"name": "Send Audio",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2850,
600
]
},
{
"parameters": {
"operation": "delete",
"key": "={{$json.chatId}}_state"
},
"id": "21",
"name": "Clear State",
"type": "n8n-nodes-base.redis",
"typeVersion": 1,
"position": [
3050,
600
]
},
{
"parameters": {
"chatId": "={{$json.chatId}}",
"text": "\u0425\u043e\u0447\u0435\u0448\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u044e? \u041d\u0430\u0436\u043c\u0438 \u043a\u043d\u043e\u043f\u043a\u0443 \u043d\u0438\u0436\u0435 \ud83d\ude0a",
"additionalFields": {
"replyMarkup": "json",
"replyMarkupJson": "={{ JSON.stringify({ keyboard: [[{ text: '\u0425\u043e\u0447\u0443 \u043c\u0435\u0434\u0438\u0442\u0430\u0446\u0438\u044e' }]], resize_keyboard: true, one_time_keyboard: true }) }}"
}
},
"id": "22",
"name": "Offer New Meditation",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
3250,
600
]
}
],
"connections": {
"Telegram Trigger": {
"main": [
[
{
"node": "Get User State",
"type": "main",
"index": 0
}
]
]
},
"Get User State": {
"main": [
[
{
"node": "Parse State",
"type": "main",
"index": 0
}
]
]
},
"Parse State": {
"main": [
[
{
"node": "Check Step: Start",
"type": "main",
"index": 0
}
]
]
},
"Check Step: Start": {
"main": [
[
{
"node": "Check Meditation Request",
"type": "main",
"index": 0
}
],
[
{
"node": "Check Step: Name",
"type": "main",
"index": 0
}
]
]
},
"Check Meditation Request": {
"main": [
[
{
"node": "Save State: Awaiting Name",
"type": "main",
"index": 0
}
],
[
{
"node": "Welcome Message",
"type": "main",
"index": 0
}
]
]
},
"Ask Name": {
"main": []
},
"Save State: Awaiting Name": {
"main": [
[
{
"node": "Ask Name",
"type": "main",
"index": 0
}
]
]
},
"Check Step: Name": {
"main": [
[
{
"node": "Extract Name",
"type": "main",
"index": 0
}
],
[
{
"node": "Check Step: Goal",
"type": "main",
"index": 0
}
]
]
},
"Extract Name": {
"main": [
[
{
"node": "Ask Goal",
"type": "main",
"index": 0
}
]
]
},
"Ask Goal": {
"main": [
[
{
"node": "Save State: Awaiting Goal",
"type": "main",
"index": 0
}
]
]
},
"Check Step: Goal": {
"main": [
[
{
"node": "Extract Goal",
"type": "main",
"index": 0
}
]
]
},
"Extract Goal": {
"main": [
[
{
"node": "Validate Goal",
"type": "main",
"index": 0
}
]
]
},
"Validate Goal": {
"main": [
[
{
"node": "Check Validation Result",
"type": "main",
"index": 0
}
]
]
},
"Check Validation Result": {
"main": [
[
{
"node": "Is Goal Valid?",
"type": "main",
"index": 0
}
]
]
},
"Is Goal Valid?": {
"main": [
[
{
"node": "Processing Message",
"type": "main",
"index": 0
}
],
[
{
"node": "Reject Invalid Goal",
"type": "main",
"index": 0
}
]
]
},
"Processing Message": {
"main": [
[
{
"node": "Generate Meditation Text",
"type": "main",
"index": 0
}
]
]
},
"Generate Meditation Text": {
"main": [
[
{
"node": "Extract Meditation Text",
"type": "main",
"index": 0
}
]
]
},
"Extract Meditation Text": {
"main": [
[
{
"node": "Generate Audio (TTS)",
"type": "main",
"index": 0
}
]
]
},
"Generate Audio (TTS)": {
"main": [
[
{
"node": "Prepare Final Message",
"type": "main",
"index": 0
}
]
]
},
"Prepare Final Message": {
"main": [
[
{
"node": "Send Audio",
"type": "main",
"index": 0
}
]
]
},
"Send Audio": {
"main": [
[
{
"node": "Clear State",
"type": "main",
"index": 0
}
]
]
},
"Clear State": {
"main": [
[
{
"node": "Offer New Meditation",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Telegram Meditation Bot (Fixed with State). Uses telegramTrigger, redis, telegram, httpRequest. Event-driven trigger; 26 nodes.
Source: https://gist.github.com/IlgizIlgiz/99005b42069ea23e7a7768de4f31839e — 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.
Telegram Wait. Uses stickyNote, httpRequest, redis, noOp. Event-driven trigger; 36 nodes.
Telegram Meditation Bot (Fixed with State). Uses telegramTrigger, redis, telegram, httpRequest. Event-driven trigger; 26 nodes.
Telegram Meditation Bot (Fixed with State). Uses telegramTrigger, redis, telegram, httpRequest. Event-driven trigger; 26 nodes.
Telegram Meditation Bot (Fixed with State). Uses telegramTrigger, redis, telegram, httpRequest. Event-driven trigger; 26 nodes.
Telegram Meditation Bot (Fixed with State). Uses telegramTrigger, redis, telegram, httpRequest. Event-driven trigger; 26 nodes.