
Voice & Text Control for Home Assistant using Telegram, Whisper & Gemini
説明
Categories
🤖 AI & Machine Learning
Nodes Used
n8n-nodes-base.ifn8n-nodes-base.ifn8n-nodes-base.setn8n-nodes-base.setn8n-nodes-base.coden8n-nodes-base.coden8n-nodes-base.telegramn8n-nodes-base.telegramn8n-nodes-base.telegramn8n-nodes-base.stickyNote
Price無料
Views0
最終更新11/28/2025
workflow.json
{
"meta": {
"instanceId": "51c6a64ef13fda2e6aa96576c25d72519ca4bc44cea9da20af60a642b594d835",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "7e0b01ef-5cf7-4e9f-9aed-8870278982de",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"position": [
-1392,
-176
],
"webhookId": "ef275b2b-bfed-4650-99d2-d02b3510558d",
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"id": "0sqJKu6xk6XEHAcX",
"name": "HomeWhisper"
}
},
"typeVersion": 1.2
},
{
"id": "827393b8-ce03-4c88-8844-ac02930ef543",
"name": "Telegram Send",
"type": "n8n-nodes-base.telegram",
"position": [
1328,
-32
],
"webhookId": "2923625f-1ad1-43d3-9155-ad52a144c940",
"parameters": {
"text": "={{ $json.text }}",
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"additionalFields": {
"parse_mode": "HTML"
}
},
"credentials": {
"telegramApi": {
"id": "0sqJKu6xk6XEHAcX",
"name": "HomeWhisper"
}
},
"typeVersion": 1
},
{
"id": "15b61fb1-26d0-40e1-8760-d1a458600d37",
"name": "Reply Router",
"type": "n8n-nodes-base.if",
"position": [
768,
32
],
"parameters": {
"options": {
"ignoreCase": false
},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8e3b6656-fab8-49d5-9ed0-54bd8b6a8729",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('Process messages').item.json.source }}",
"rightValue": "telegram"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "cef7c350-5225-434e-b81d-27d9ede69b8e",
"name": "Telegram Message Beautifier",
"type": "n8n-nodes-base.code",
"position": [
1088,
-32
],
"parameters": {
"jsCode": "let text = $json.output;\n\n// 1. Zamień **coś** na <b>coś</b>\ntext = text.replace(/\\*\\*(.*?)\\*\\*/g, '<b>$1</b>');\n\n// 2. Zamień * <b>Coś:</b> ... na bullet z boldem\ntext = text.replace(/^\\*\\s+<b>([^<]+):<\\/b>/gm, '• <b>$1:</b>');\n\n// 3. Zamień * Coś: ... na bullet z boldem (gdy nie ma bolda)\ntext = text.replace(/^\\*\\s+([^:]+):/gm, '• <b>$1:</b>');\n\n// 4. Zamień `code` na <code>\ntext = text.replace(/`([^`]+)`/g, '<code>$1</code>');\n\n// 5. Zamień podwójne nowe linie na pojedyncze (żeby nie było za dużych przerw)\ntext = text.replace(/\\n{3,}/g, '\\n\\n');\n\n// 6. (Opcjonalnie) Zamień linki [tekst](url) na <a href=\"url\">tekst</a>\ntext = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\">$1</a>');\n\n// 7. Chunking\nconst chunkSize = 4096;\nconst chunks = [];\nfor (let i = 0; i < text.length; i += chunkSize) {\n chunks.push({ text: text.substring(i, i + chunkSize) });\n}\n\nreturn chunks;"
},
"typeVersion": 2
},
{
"id": "46595cbb-4be2-4561-90b5-d1d3b5602a25",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1088,
144
],
"parameters": {
"options": {},
"respondWith": "text",
"responseBody": "={{ $json.output }}"
},
"typeVersion": 1.4
},
{
"id": "b729b4fc-c986-4773-bef2-f49ab4a1b895",
"name": "Transcription to ChatInput",
"type": "n8n-nodes-base.set",
"position": [
-256,
-176
],
"parameters": {
"fields": {
"values": [
{
"name": "chatInput",
"stringValue": "={{ $json.text }}"
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "154315db-df92-449d-9930-94139e8012e9",
"name": "Get Voice File",
"type": "n8n-nodes-base.telegram",
"position": [
-544,
-176
],
"webhookId": "04226bd9-ad35-4792-993d-5ec2eecb519e",
"parameters": {
"fileId": "={{ $json.message.voice.file_id }}",
"resource": "file",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"id": "0sqJKu6xk6XEHAcX",
"name": "HomeWhisper"
}
},
"typeVersion": 1.1
},
{
"id": "0748b3dd-b6fc-4a12-b433-a7d09c65cc7f",
"name": "Voice or Text",
"type": "n8n-nodes-base.set",
"position": [
-992,
-64
],
"parameters": {
"fields": {
"values": [
{
"name": "text",
"stringValue": "={{ $json?.message?.text || \"\" }}"
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "d99898a9-6619-422d-928c-d371812c1f5e",
"name": "Speech to Text",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
-400,
-176
],
"parameters": {
"options": {},
"resource": "audio",
"operation": "transcribe"
},
"credentials": {
"openAiApi": {
"id": "7CgAvVK5FzY7W0vB",
"name": "OpenAi account"
}
},
"typeVersion": 1.3
},
{
"id": "acfc8962-6ae2-4ddb-9429-2bfc50e04eb2",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
-832,
-64
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a0bf9719-4272-46f6-ab3b-eda6f7b44fd8",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json.message.text }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "fafce53a-2570-4ae9-b92c-029485cf3890",
"name": "Process messages",
"type": "n8n-nodes-base.code",
"position": [
16,
32
],
"parameters": {
"jsCode": "// Helper: bezpieczne czytanie z innych nodów\nfunction safe(getter, fallback = undefined) {\n try {\n const v = getter();\n return v === undefined || v === null ? fallback : v;\n } catch (e) {\n return fallback;\n }\n}\n\n// Spróbuj pobrać oba źródła, ale bez crasha:\nconst tgMsg = safe(() => $('Telegram Trigger').item.json.message, null);\nconst chatEvt = safe(() => $('When chat message received').item.json, null);\n\n// Pick-first\nconst pick = (...arr) => arr.find(v => typeof v === 'string' && v.trim()) || '';\n\n// Tekst z różnych miejsc (STT -> chatInput, tekst, itd.)\nconst inputText = pick(\n $json.inputText,\n $json.chatInput,\n $json.text,\n $json.message?.text,\n tgMsg?.text,\n chatEvt?.message,\n chatEvt?.input,\n chatEvt?.text\n);\n\n// Źródło\nlet source = 'chat';\nif (tgMsg) source = 'telegram';\nelse if (chatEvt) source = 'n8n-chat';\n\n// SessionId\nlet sessionId = 'unknown';\nif (tgMsg) {\n sessionId = String(tgMsg.chat?.id ?? tgMsg.from?.id ?? 'telegram-unknown');\n} else if (chatEvt) {\n sessionId = String(\n chatEvt.sessionId ?? chatEvt.chatId ?? chatEvt.connectionId ?? chatEvt.userId ?? 'n8n-chat-unknown'\n );\n} else if ($json.chatId) {\n sessionId = String($json.chatId);\n}\n\n// Voice flag (na przyszłość)\nconst isVoice = Boolean(safe(() => $('Telegram Trigger').item.json.message.voice.file_id, null));\n\nreturn [{\n json: {\n inputText: inputText.trim(),\n source,\n sessionId,\n isVoice\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "55de43ac-f154-4025-9f31-78b8466a497f",
"name": "Bot Is typing",
"type": "n8n-nodes-base.telegram",
"position": [
-992,
-256
],
"webhookId": "6b14a2b6-91ff-45a5-af70-bd9696961512",
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"operation": "sendChatAction"
},
"credentials": {
"telegramApi": {
"id": "0sqJKu6xk6XEHAcX",
"name": "HomeWhisper"
}
},
"typeVersion": 1.2
},
{
"id": "58b26df3-00e6-48c6-bd1a-209dd6c63ec3",
"name": "Simple Memory1",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
-1312,
480
],
"parameters": {},
"typeVersion": 1.3
},
{
"id": "fa7b3918-2f19-4b32-896b-83fb8ea2b400",
"name": "Home assistant Connector",
"type": "@n8n/n8n-nodes-langchain.mcpClientTool",
"position": [
512,
272
],
"parameters": {
"include": "selected",
"options": {},
"endpointUrl": "http://192.168.1.69:8123/mcp_server/sse",
"includeTools": [
"GetLiveContext",
"HassTurnOn",
"HassTurnOff",
"HassLightSet",
"HassBroadcast"
],
"authentication": "bearerAuth"
},
"credentials": {
"httpBearerAuth": {
"id": "jU7PgSSiWQjSlEp7",
"name": "HA MCP"
}
},
"typeVersion": 1.1
},
{
"id": "b7a623d6-f689-4687-bc66-275b1f73a63a",
"name": "Home Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
304,
32
],
"parameters": {
"text": "={{ $json.inputText }}",
"options": {},
"promptType": "define"
},
"typeVersion": 2
},
{
"id": "60021ab2-33cb-46e1-87e0-3d7f9d1e56fe",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
368,
272
],
"parameters": {},
"typeVersion": 1.3
},
{
"id": "c51dc09b-ad53-4a1d-8b38-59a950d9d31c",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
224,
272
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "1BSwX5Mk7OVEOxL1",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "8c61f905-4040-44ff-aed9-3b36ecbc6daf",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
-1312,
272
],
"webhookId": "9521c056-a097-4f48-a0eb-7caccf132a4c",
"parameters": {
"public": true,
"options": {
"loadPreviousSession": "memory"
}
},
"typeVersion": 1.3
},
{
"id": "4117eb44-33aa-4d3c-b032-4de7a50f5b15",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1632,
208
],
"parameters": {
"width": 256,
"height": 224,
"content": "## When chat message received:\n\nCaptures messages from n8n’s built-in chat and feeds into normalization pipeline.\n"
},
"typeVersion": 1
},
{
"id": "d1904d79-7004-445e-bc8e-ef056163a464",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1696,
-208
],
"parameters": {
"content": "## Telegram Trigger:\nListens for incoming Telegram messages (text or voice).\n"
},
"typeVersion": 1
},
{
"id": "fb31fb1c-c1ae-49fa-abb4-f239ed349706",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1056,
-432
],
"parameters": {
"content": "## Bot Is typing:\nSends “typing…” action back to Telegram for better UX feedback."
},
"typeVersion": 1
},
{
"id": "90ddab99-91db-419f-8190-7d5bfd74fdb9",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1040,
80
],
"parameters": {
"color": 4,
"width": 400,
"content": "## Voice or Text:\nChecks if the message is voice → routes to STT; otherwise uses text directly.\n## If Voice Node:\nBranch: if text missing, route through speech transcription."
},
"typeVersion": 1
},
{
"id": "b5f91665-8eac-4ded-80cc-3bad4444d972",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-576,
-448
],
"parameters": {
"color": 4,
"width": 448,
"height": 240,
"content": "### Get Voice File:\nDownloads the voice message from Telegram for transcription.\n\n### Speech to Text:\nTranscribes voice input into text using OpenAI Whisper.\n\n### Transcription to ChatInput:\nMaps transcribed text into unified chatInput field."
},
"typeVersion": 1
},
{
"id": "d93fb3d9-06d2-43eb-8c46-0c133ab636c3",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-32,
-160
],
"parameters": {
"color": 4,
"content": "### Process messages:\nNormalizes inputText, detects source (chat/telegram), and builds sessionId."
},
"typeVersion": 1
},
{
"id": "d326f85d-61a1-4f29-8f52-207313b79a3a",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1040,
-208
],
"parameters": {
"content": "### Telegram Message Beautifier:\nFormats output: bold, bullets, inline code, links – splits into chunks."
},
"typeVersion": 1
},
{
"id": "dfb1166c-9e3f-4b58-8cbf-021ab731c0c0",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
288,
-160
],
"parameters": {
"content": "## Home Agent:\nCore AI agent that orchestrates LLM and Home Assistant actions."
},
"typeVersion": 1
},
{
"id": "c9f34a9e-b13b-43da-a45d-472b4ffb8a7a",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
464,
416
],
"parameters": {
"width": 208,
"height": 192,
"content": "## Home Assistant Connector:\n\nExecutes smart home actions: turn lights on/off, set brightness, broadcast messages via MCP.\n"
},
"typeVersion": 1
},
{
"id": "6f6e3028-9886-40dd-a17a-e82aa94f9747",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
688,
-160
],
"parameters": {
"content": "## Reply Router:\nRoutes response back to Telegram or n8n chat UI depending on origin.\n"
},
"typeVersion": 1
},
{
"id": "8e5c9b6c-8ad1-494e-a754-115f830d27bd",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1312,
160
],
"parameters": {
"width": 272,
"height": 240,
"content": "### Telegram Send:\nSends formatted reply back to Telegram in HTML parse mode.\n\n### Respond to Webhook:\nStreams responses back to the n8n chat frontend webhook."
},
"typeVersion": 1
},
{
"id": "5f8b5ae2-d736-40c0-9db6-daef3256f894",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1792,
-752
],
"parameters": {
"color": 3,
"width": 592,
"height": 448,
"content": "**Workflow Name:** Home Assistant Whisper\n\n**What it does:**\nThis workflow bridges natural conversation (via Telegram or n8n Chat) with Home Assistant. Users send commands—text or voice—and the system:\n* Transcribes voice using Whisper\n* Normalizes input, maintains session context\n* Uses Google Gemini + an AI agent to understand intent\n* Triggers smart home actions via MCP (turn lights on/off, adjust brightness, broadcast)\n* Formats and routes responses back to the correct channel—Telegram or n8n Chat—with polished markdown/HTML formatting.\n\n**Key highlights:**\n- Multi-channel (chat + voice)\n- Short-term memory for context\n- AI-powered intent understanding\n- Smart routing and beautified responses\n- Modular design—easy to extend or tweak"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"If": {
"main": [
[
{
"node": "Get Voice File",
"type": "main",
"index": 0
}
],
[
{
"node": "Process messages",
"type": "main",
"index": 0
}
]
]
},
"Home Agent": {
"main": [
[
{
"node": "Reply Router",
"type": "main",
"index": 0
}
]
]
},
"Reply Router": {
"main": [
[
{
"node": "Telegram Message Beautifier",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "Home Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Voice or Text": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Get Voice File": {
"main": [
[
{
"node": "Speech to Text",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory1": {
"ai_memory": [
[
{
"node": "When chat message received",
"type": "ai_memory",
"index": 0
}
]
]
},
"Speech to Text": {
"main": [
[
{
"node": "Transcription to ChatInput",
"type": "main",
"index": 0
}
]
]
},
"Process messages": {
"main": [
[
{
"node": "Home Agent",
"type": "main",
"index": 0
}
]
]
},
"Telegram Trigger": {
"main": [
[
{
"node": "Voice or Text",
"type": "main",
"index": 0
},
{
"node": "Bot Is typing",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Home Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Home assistant Connector": {
"ai_tool": [
[
{
"node": "Home Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Transcription to ChatInput": {
"main": [
[
{
"node": "Process messages",
"type": "main",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "Process messages",
"type": "main",
"index": 0
}
]
]
},
"Telegram Message Beautifier": {
"main": [
[
{
"node": "Telegram Send",
"type": "main",
"index": 0
}
]
]
}
}
}