语音翻译桥接 (Telegram → Slack),集成GPT-4o-mini和Whisper
高级
这是一个Personal Productivity, Multimodal AI领域的自动化工作流,包含 24 个节点。主要使用 If, Set, Code, Function, HttpRequest 等节点。 语音翻译桥接 (Telegram → Slack),集成GPT-4o-mini和Whisper
前置要求
- •可能需要目标 API 的认证凭证
- •Telegram Bot Token
- •OpenAI API Key
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"name": "Voice Translator Bridge (Telegram → Slack) with GPT-4o-mini + Whisper",
"nodes": [
{
"id": "92ef6daa-251b-4203-b7c3-aa64451e9973",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"notes": "📥 Telegramで音声メッセージを受信したら起動するトリガー。messageイベントを監視。",
"position": [
-2192,
-560
],
"webhookId": "8052efdf-3111-4357-8f76-11509f3bc4f1",
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"id": "",
"name": "TELEGRAM_BOT_CRED"
}
},
"typeVersion": 1
},
{
"id": "46355ee1-472a-45b8-9a30-bd2661b2edf6",
"name": "Is Voice?",
"type": "n8n-nodes-base.if",
"notes": "🎤 受信データが音声メッセージかどうか判定。voice要素がある場合のみ次へ進む。",
"position": [
-1952,
-560
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json[\"message\"][\"voice\"] !== undefined ? \"voice\" : \"other\"}}",
"value2": "voice"
}
]
}
},
"typeVersion": 1
},
{
"id": "ff56e185-727a-4aed-af00-dbc583e62078",
"name": "Get File ID",
"type": "n8n-nodes-base.set",
"notes": "📄 Telegramメッセージからfile_idと送信者情報を抽出。ユーザー名がなければfirst_nameを使用。",
"position": [
-1760,
-656
],
"parameters": {
"values": {
"string": [
{
"name": "file_id",
"value": "={{$json[\"message\"][\"voice\"][\"file_id\"]}}"
},
{
"name": "chat_id",
"value": "={{$json[\"message\"][\"chat\"][\"id\"]}}"
},
{
"name": "from_username",
"value": "={{$json[\"message\"][\"from\"][\"username\"] || $json[\"message\"][\"from\"][\"first_name\"] || \"unknown\"}}"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 1
},
{
"id": "714c4a56-f886-47a9-97bf-85099f70b35d",
"name": "Telegram getFile",
"type": "n8n-nodes-base.httpRequest",
"notes": "🧾 Telegram APIから音声ファイルのファイルパス(file_path)を取得。",
"position": [
-1440,
-656
],
"parameters": {
"url": "=https://api.telegram.org/bot{{$json[\"bot_token\"]}}/getFile?file_id={{$json[\"file_id\"]}}",
"options": {}
},
"typeVersion": 1
},
{
"id": "8c523645-2952-45ce-9e3a-a3850084b858",
"name": "Build File URL",
"type": "n8n-nodes-base.function",
"notes": "🔗 実際にダウンロードできるファイルURLを組み立て。",
"position": [
-1184,
-560
],
"parameters": {
"functionCode": "// 1. Telegramの音声ファイルの相対パス (e.g. \"voice/file_0.oga\")\nconst filePath = items[0].json.result.file_path;\n\n// 2. Botトークンは Add Bot Token ノードから取る\nconst token = $items(\"Add Bot Token\")[0].json.bot_token;\n\n// 3. Telegramの実ファイルURLを組み立て\n// 形式: https://api.telegram.org/file/bot<BOT_TOKEN>/<file_path>\nconst fileUrl = `https://api.telegram.org/file/bot${token}/${filePath}`;\n\n// 4. chat_id と from_username は Get File ID ノードの値をそのまま流す\nconst chat_id = $items(\"Get File ID\")[0].json.chat_id;\nconst from_username = $items(\"Get File ID\")[0].json.from_username;\n\n// 5. 後続ノード(Download Voice File)に必要な情報を返す\nreturn [\n {\n json: {\n file_url: fileUrl,\n chat_id,\n from_username\n }\n }\n];\n"
},
"typeVersion": 1
},
{
"id": "00727b12-217a-4169-925d-f0988c608a3c",
"name": "Download Voice File",
"type": "n8n-nodes-base.httpRequest",
"notes": "⬇️ Telegramの音声データをバイナリとして取得。",
"position": [
-864,
-560
],
"parameters": {
"url": "={{$json[\"file_url\"]}}",
"options": {},
"responseFormat": "file"
},
"typeVersion": 1
},
{
"id": "dc8c842b-675f-4423-a86b-358fa479c256",
"name": "Extract Transcript",
"type": "n8n-nodes-base.set",
"notes": "📝 Whisperの結果(text)を取り出して整形。",
"position": [
-2192,
-320
],
"parameters": {
"values": {
"string": [
{
"name": "transcript_text",
"value": "={{$json.text}}"
},
{
"name": "from_username",
"value": "={{$items(\"Build File URL\")[0].json.from_username}}"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 1
},
{
"id": "148b8a46-4a3a-4574-932e-ec84c3e01a8d",
"name": "Detect Language",
"type": "n8n-nodes-base.function",
"notes": "🌏 日本語/英語をざっくり判定。漢字・かなを含めばja扱い。",
"position": [
-1952,
-320
],
"parameters": {
"functionCode": "const text = $json.transcript_text || \"\";\nconst jaRegex = /[ぁ-んァ-ン一-龠]/;\nconst isJa = jaRegex.test(text);\nreturn [{ json: { original_text: text, source_lang: isJa ? 'ja' : 'en', target_lang: isJa ? 'en' : 'ja', from_username: $json.from_username } }];"
},
"typeVersion": 1
},
{
"id": "0096f37e-8157-46e5-af36-67c5397389a4",
"name": "Translate (OpenAI)",
"type": "n8n-nodes-base.httpRequest",
"notes": "🔁 OpenAI GPT-4o-miniで翻訳(Whisperと同じAPIキーで完結)。",
"position": [
-1360,
-320
],
"parameters": {
"url": "https://api.openai.com/v1/chat/completions",
"options": {},
"requestMethod": "POST",
"authentication": "headerAuth",
"jsonParameters": true,
"bodyParametersJson": "={\n \"model\": \"gpt-4o-mini\",\n \"temperature\": 0.2,\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a translation engine. Translate exactly, preserving meaning and tone. Output ONLY the translated text.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Source language: {{$json.source_lang}}\\nTarget language: {{$json.target_lang}}\\nText:\\n{{$json.original_text}}\"\n }\n ]\n}\n",
"queryParametersJson": "=",
"headerParametersJson": "={\n \"Authorization\": \"Bearer {{$credentials.httpHeaderAuth.headerValue}}\",\n \"Content-Type\": \"application/json\"\n}\n"
},
"credentials": {
"httpHeaderAuth": {
"id": "",
"name": "OPENAI_HEADER_AUTH"
}
},
"typeVersion": 1
},
{
"id": "40a54c88-fed2-4388-a2ac-f1e824ecc900",
"name": "Build Slack Message",
"type": "n8n-nodes-base.function",
"notes": "💬 Slackに投稿する本文を組み立て。Bot投稿+Telegramの@ユーザー名付き。",
"position": [
-704,
-320
],
"parameters": {
"functionCode": "// === 言語コードを国旗に変換 ===\nfunction flagFor(lang) {\n if (lang === 'ja') return '🇯🇵';\n if (lang === 'en') return '🇺🇸';\n return '🌐';\n}\n\n// Detect Language ノードから言語を取得\nconst sourceLang = $node[\"Detect Language\"].json.source_lang || 'en';\nconst targetLang = $node[\"Detect Language\"].json.target_lang || 'en';\n\nconst src = flagFor(sourceLang);\nconst dst = flagFor(targetLang);\n\n// Telegram ユーザー名\nconst username = $node[\"Get File ID\"].json.from_username || 'unknown';\n\n// Whisper or Detect Language の原文テキスト\nconst original =\n $node[\"Extract Transcript\"].json.text ||\n $node[\"Detect Language\"].json.original_text ||\n '(no transcript)';\n\n// 翻訳結果\nconst translated =\n $node[\"Translate (OpenAI)\"].json.choices[0].message.content ||\n '(no translation)';\n\n// Slackに投稿する本文\nconst text = `*${src} → ${dst}* (@${username})\n> ${original}\n\n${translated}\n`;\n\nreturn [{ json: { slack_text: text } }];\n"
},
"typeVersion": 1
},
{
"id": "5c36ed2c-cf48-4162-abc4-9ed8c7dc6f0b",
"name": "Post to Slack",
"type": "n8n-nodes-base.httpRequest",
"notes": "🚀 Slack Botが指定チャンネルに翻訳結果を投稿。投稿者はBot、本文にTelegram名を表示。",
"position": [
-224,
-320
],
"parameters": {
"url": "https://slack.com/api/chat.postMessage",
"options": {},
"requestMethod": "POST",
"authentication": "headerAuth",
"bodyParametersUi": {
"parameter": [
{
"name": "channel",
"value": "{{YOUR_SLACK_CHANNEL_ID}}"
},
{
"name": "text",
"value": "={{$json.slack_text}}"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"id": "",
"name": "SLACK_BOT_TOKEN_HEADER"
}
},
"typeVersion": 1
},
{
"id": "5c36c02a-46ac-4d67-bc28-de11f7c9f258",
"name": "Add Bot Token",
"type": "n8n-nodes-base.set",
"position": [
-1600,
-560
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "83ae047b-fdd8-4061-b10a-82921ae9201c",
"name": "bot_token",
"type": "string",
"value": "{{YOUR_TELEGRAM_BOT_TOKEN}}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "29bb8262-a2a3-4a28-a5b6-a8c4013a5179",
"name": "Prepare Whisper Input1",
"type": "n8n-nodes-base.code",
"position": [
-544,
-560
],
"parameters": {
"jsCode": "// \"data\" バイナリを \"audio\" にコピーし、Whisper用に渡す\nreturn [\n {\n json: { ...$json },\n binary: { audio: $binary.data }\n }\n];"
},
"typeVersion": 2
},
{
"id": "160f0494-e66c-4da0-8ae4-bfad272bfdc8",
"name": "Transcribe a recording",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
-240,
-560
],
"parameters": {
"options": {},
"resource": "audio",
"operation": "transcribe",
"binaryPropertyName": "audio"
},
"credentials": {
"openAiApi": {
"id": "",
"name": "OPENAI_API_KEY_HEADER"
}
},
"typeVersion": 1.8
},
{
"id": "9b9e59f1-67fe-42ba-88b5-3a7259d4340b",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-928,
-976
],
"parameters": {
"height": 416,
"content": "### 🎯 Purpose \nDownloads the actual `.oga` or `.mp3` file from Telegram.\n\n### ⚙️ Setup \n- Method: `GET`\n- URL: `{{$json.file_url}}`\n- **Send Binary Data:** ✅ (ON)\n\n### 🧩 Output \nBinary data under `$binary.data`\n"
},
"typeVersion": 1
},
{
"id": "c6ac3585-a699-4713-b816-00a05f735f3b",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1248,
-976
],
"parameters": {
"color": 5,
"width": 256,
"height": 416,
"content": "### 🎯 Purpose \nConstructs the Telegram file URL for download.\n\n### ⚙️ Setup \nUse an **Expression**:\n```\nhttps://api.telegram.org/file/bot{{$credentials.telegramApi.accessToken}}/{{$json.file_path}}\n```\n\n### 🧩 Output \n`file_url` → used in **Download Voice File**\n"
},
"typeVersion": 1
},
{
"id": "475b3e8a-34f4-4687-b58e-7474792ec14f",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2304,
-944
],
"parameters": {
"color": 4,
"width": 320,
"height": 384,
"content": "### 🎯 Purpose \nStarts the workflow when a **voice message** is received in Telegram.\n\n### ⚙️ Setup \n- Connect your **Telegram Bot Token** (Credential: `TELEGRAM_BOT_TOKEN`).\n- This node listens for incoming messages (`audio`, `voice`, or `text`).\n\n### 🧩 Output \nContains:\n- `message.from.username`\n- `message.voice.file_id`\n- Optional `message.text`"
},
"typeVersion": 1
},
{
"id": "c2ccfb01-1eae-4577-9cf8-bf5ebdb5c2db",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1760,
-976
],
"parameters": {
"color": 4,
"width": 416,
"height": 320,
"content": "### 🎯 Purpose \nRetrieve the Telegram voice file's metadata.\n\n### ⚙️ Setup \n- Input: `file_id` from the Trigger node \n- Calls Telegram API `getFile` to obtain the `file_path`.\n\n### 🧩 Output \n`file_path` (used to build the actual download URL)"
},
"typeVersion": 1
},
{
"id": "23fca2a8-99ee-49b4-9129-dfc38e23225e",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-608,
-976
],
"parameters": {
"color": 2,
"width": 224,
"height": 416,
"content": "### 🎯 Purpose \nPrepare binary audio data for the Whisper node.\n\n### ⚙️ Setup \n- Input: `$binary.data`\n- Output: rename to `audio` (binary key expected by Whisper)\n\n### 🧩 Output \nBinary → `$binary.audio`"
},
"typeVersion": 1
},
{
"id": "a762b0c7-2b17-4380-8947-cea69841b5ba",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-304,
-976
],
"parameters": {
"color": 3,
"height": 416,
"content": "### 🎯 Purpose \nConvert voice to text using **OpenAI Whisper**.\n\n### ⚙️ Setup \n- Credential: `OPENAI_API_KEY_HEADER`\n- Resource: `Audio`\n- Operation: `Transcribe a Recording`\n- Input Data Field Name: `audio`\n\n### ⚠️ Note \nMax file size = 25 MB.\n"
},
"typeVersion": 1
},
{
"id": "eae1d9fa-9cec-4209-b7d8-f11246380512",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2032,
-176
],
"parameters": {
"color": 6,
"width": 272,
"height": 432,
"content": "### 🎯 Purpose \nDetect source language from the transcription text.\n\n### ⚙️ Setup \nSimple **IF or Code node** to detect “ja” vs “en”. \nUsed later for flag direction (🇯🇵→🇺🇸 or 🇺🇸→🇯🇵)."
},
"typeVersion": 1
},
{
"id": "fb850072-380e-4b4a-bed1-d141814e7fe3",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1648,
-176
],
"parameters": {
"color": 7,
"width": 688,
"height": 624,
"content": "### 🎯 Purpose \nTranslate transcribed text using **GPT-4o-mini**.\n\n### ⚙️ Setup \n- Request Method: POST \n- URL: `https://api.openai.com/v1/chat/completions` \n- Headers:\n ```json\n {\n \"Authorization\": \"Bearer {{$credentials.OPENAI_API_KEY_HEADER}}\",\n \"Content-Type\": \"application/json\"\n }\n ```\n- Body (JSON/RAW):\n ```json\n {\n \"model\": \"gpt-4o-mini\",\n \"temperature\": 0.2,\n \"messages\": [\n { \"role\": \"system\", \"content\": \"You are a translation engine. Translate accurately and clearly.\" },\n { \"role\": \"user\", \"content\": \"Source language: {{$json.source_lang}}\\nTarget language: {{$json.target_lang}}\\nText:\\n{{$json.text}}\" }\n ]\n }\n ```\n\n### 🧩 Output \n`choices[0].message.content` → translated text\n"
},
"typeVersion": 1
},
{
"id": "c8bd3ff0-7181-4611-a1a8-c901fc62795f",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-832,
-176
],
"parameters": {
"color": 3,
"width": 368,
"height": 432,
"content": "### 🎯 Purpose \nFormats the translated message for Slack.\n\n### ⚙️ Example (Code node)\n```js\nconst src = $json.source_lang === 'ja' ? '🇯🇵' : '🇺🇸';\nconst dst = $json.target_lang === 'ja' ? '🇯🇵' : '🇺🇸';\nconst username = $node[\"Get File ID\"].json.from_username || 'unknown';\nconst original = $node[\"Extract Transcript\"].json.text || '(no transcript)';\nconst translated = $node[\"Translate (OpenAI)\"].json.choices[0].message.content || '(no translation)';\n\nconst text = `${src} → ${dst} (@${username})\\n> ${original}\\n\\n${translated}`;\nreturn [{ json: { slack_text: text } }];\n```\n\n### 🧩 Output \n`slack_text` → sent to next node\n"
},
"typeVersion": 1
},
{
"id": "287d070d-c5df-458b-8c33-00c9b4215a03",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-352,
-176
],
"parameters": {
"color": 4,
"width": 368,
"height": 496,
"content": "### 🎯 Purpose \nPost the final translated message into Slack.\n\n### ⚙️ Setup \n- Authentication: `Header Auth` \n- Credential: `SLACK_BOT_TOKEN_HEADER` \n- URL: `https://slack.com/api/chat.postMessage` \n- JSON Body:\n ```json\n {\n \"channel\": \"C09NT81DQU\",\n \"text\": \"{{$json.slack_text}}\"\n }\n ```\n\n### ✅ Tip \nUse a test channel first (e.g., `#voice-bridge`) before production.\n"
},
"typeVersion": 1
}
],
"active": true,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "7924fc16-4594-4c87-b564-5b7eaaa5dd1e",
"connections": {
"Is Voice?": {
"main": [
[
{
"node": "Get File ID",
"type": "main",
"index": 0
}
]
]
},
"Get File ID": {
"main": [
[
{
"node": "Add Bot Token",
"type": "main",
"index": 0
}
]
]
},
"Add Bot Token": {
"main": [
[
{
"node": "Telegram getFile",
"type": "main",
"index": 0
}
]
]
},
"Build File URL": {
"main": [
[
{
"node": "Download Voice File",
"type": "main",
"index": 0
}
]
]
},
"Detect Language": {
"main": [
[
{
"node": "Translate (OpenAI)",
"type": "main",
"index": 0
}
]
]
},
"Telegram Trigger": {
"main": [
[
{
"node": "Is Voice?",
"type": "main",
"index": 0
}
]
]
},
"Telegram getFile": {
"main": [
[
{
"node": "Build File URL",
"type": "main",
"index": 0
}
]
]
},
"Extract Transcript": {
"main": [
[
{
"node": "Detect Language",
"type": "main",
"index": 0
}
]
]
},
"Translate (OpenAI)": {
"main": [
[
{
"node": "Build Slack Message",
"type": "main",
"index": 0
}
]
]
},
"Build Slack Message": {
"main": [
[
{
"node": "Post to Slack",
"type": "main",
"index": 0
}
]
]
},
"Download Voice File": {
"main": [
[
{
"node": "Prepare Whisper Input1",
"type": "main",
"index": 0
}
]
]
},
"Prepare Whisper Input1": {
"main": [
[
{
"node": "Transcribe a recording",
"type": "main",
"index": 0
}
]
]
},
"Transcribe a recording": {
"main": [
[
{
"node": "Extract Transcript",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 个人效率, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
基于URL使用AI、Telegram和多平台发布自动生成社交媒体帖子
基于URL使用AI、Telegram和多平台发布自动生成社交媒体帖子
If
Set
Code
+11
42 节点Karol
内容创作
使用 OpenAI 自动检测需处理邮件并通过 Flow 在 Teams 发送提醒
使用 OpenAI 自动检测需处理邮件并通过 Flow 在 Teams 发送提醒消息
If
Set
Code
+4
11 节点Eumentis
个人效率
导出 n8n
使用LINE和OpenAI Vision从图片记录食物卡路里到Google Sheets
If
Set
Code
+9
17 节点kote2
个人效率
每日WhatsApp摘要与群组级别控制
WhatsApp群组摘要工作流
If
Set
Code
+13
39 节点Luís Philipe Trindade
个人效率
使用OpenAI和WordPress自动化SEO博客文章创建与发布
使用OpenAI和WordPress自动化SEO博客文章创建与发布
If
Set
Code
+11
22 节点Khaisa Studio
内容创作
自动职位列表提取与发布模板
自动职位列表提取与发布模板
If
Set
Code
+14
53 节点Khairul Muhtadin
人力资源
工作流信息
难度等级
高级
节点数量24
分类2
节点类型8
作者
Tomohiro Goto
@taooCreative Technologist blending design and automation to make work a little more fun. Exploring how AI and workflow tools like n8n can bring creativity into everyday work.
外部链接
在 n8n.io 查看 →
分享此工作流