{
  "name": "Voice Translator Bridge (Telegram \u2192 Slack) with GPT-4o-mini + Whisper",
  "nodes": [
    {
      "id": "92ef6daa-251b-4203-b7c3-aa64451e9973",
      "name": "Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "notes": "\ud83d\udce5 Telegram\u3067\u97f3\u58f0\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u53d7\u4fe1\u3057\u305f\u3089\u8d77\u52d5\u3059\u308b\u30c8\u30ea\u30ac\u30fc\u3002message\u30a4\u30d9\u30f3\u30c8\u3092\u76e3\u8996\u3002",
      "position": [
        -2192,
        -560
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "46355ee1-472a-45b8-9a30-bd2661b2edf6",
      "name": "Is Voice?",
      "type": "n8n-nodes-base.if",
      "notes": "\ud83c\udfa4 \u53d7\u4fe1\u30c7\u30fc\u30bf\u304c\u97f3\u58f0\u30e1\u30c3\u30bb\u30fc\u30b8\u304b\u3069\u3046\u304b\u5224\u5b9a\u3002voice\u8981\u7d20\u304c\u3042\u308b\u5834\u5408\u306e\u307f\u6b21\u3078\u9032\u3080\u3002",
      "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": "\ud83d\udcc4 Telegram\u30e1\u30c3\u30bb\u30fc\u30b8\u304b\u3089file_id\u3068\u9001\u4fe1\u8005\u60c5\u5831\u3092\u62bd\u51fa\u3002\u30e6\u30fc\u30b6\u30fc\u540d\u304c\u306a\u3051\u308c\u3070first_name\u3092\u4f7f\u7528\u3002",
      "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": "\ud83e\uddfe Telegram API\u304b\u3089\u97f3\u58f0\u30d5\u30a1\u30a4\u30eb\u306e\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\uff08file_path\uff09\u3092\u53d6\u5f97\u3002",
      "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": "\ud83d\udd17 \u5b9f\u969b\u306b\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3067\u304d\u308b\u30d5\u30a1\u30a4\u30ebURL\u3092\u7d44\u307f\u7acb\u3066\u3002",
      "position": [
        -1184,
        -560
      ],
      "parameters": {
        "functionCode": "// 1. Telegram\u306e\u97f3\u58f0\u30d5\u30a1\u30a4\u30eb\u306e\u76f8\u5bfe\u30d1\u30b9 (e.g. \"voice/file_0.oga\")\nconst filePath = items[0].json.result.file_path;\n\n// 2. Bot\u30c8\u30fc\u30af\u30f3\u306f Add Bot Token \u30ce\u30fc\u30c9\u304b\u3089\u53d6\u308b\nconst token = $items(\"Add Bot Token\")[0].json.bot_token;\n\n// 3. Telegram\u306e\u5b9f\u30d5\u30a1\u30a4\u30ebURL\u3092\u7d44\u307f\u7acb\u3066\n//    \u5f62\u5f0f: 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 \u3068 from_username \u306f Get File ID \u30ce\u30fc\u30c9\u306e\u5024\u3092\u305d\u306e\u307e\u307e\u6d41\u3059\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. \u5f8c\u7d9a\u30ce\u30fc\u30c9\uff08Download Voice File\uff09\u306b\u5fc5\u8981\u306a\u60c5\u5831\u3092\u8fd4\u3059\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": "\u2b07\ufe0f Telegram\u306e\u97f3\u58f0\u30c7\u30fc\u30bf\u3092\u30d0\u30a4\u30ca\u30ea\u3068\u3057\u3066\u53d6\u5f97\u3002",
      "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": "\ud83d\udcdd Whisper\u306e\u7d50\u679c(text)\u3092\u53d6\u308a\u51fa\u3057\u3066\u6574\u5f62\u3002",
      "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": "\ud83c\udf0f \u65e5\u672c\u8a9e/\u82f1\u8a9e\u3092\u3056\u3063\u304f\u308a\u5224\u5b9a\u3002\u6f22\u5b57\u30fb\u304b\u306a\u3092\u542b\u3081\u3070ja\u6271\u3044\u3002",
      "position": [
        -1952,
        -320
      ],
      "parameters": {
        "functionCode": "const text = $json.transcript_text || \"\";\nconst jaRegex = /[\u3041-\u3093\u30a1-\u30f3\u4e00-\u9fa0]/;\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": "\ud83d\udd01 OpenAI GPT-4o-mini\u3067\u7ffb\u8a33\uff08Whisper\u3068\u540c\u3058API\u30ad\u30fc\u3067\u5b8c\u7d50\uff09\u3002",
      "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": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "40a54c88-fed2-4388-a2ac-f1e824ecc900",
      "name": "Build Slack Message",
      "type": "n8n-nodes-base.function",
      "notes": "\ud83d\udcac Slack\u306b\u6295\u7a3f\u3059\u308b\u672c\u6587\u3092\u7d44\u307f\u7acb\u3066\u3002Bot\u6295\u7a3f\uff0bTelegram\u306e@\u30e6\u30fc\u30b6\u30fc\u540d\u4ed8\u304d\u3002",
      "position": [
        -704,
        -320
      ],
      "parameters": {
        "functionCode": "// === \u8a00\u8a9e\u30b3\u30fc\u30c9\u3092\u56fd\u65d7\u306b\u5909\u63db ===\nfunction flagFor(lang) {\n  if (lang === 'ja') return '\ud83c\uddef\ud83c\uddf5';\n  if (lang === 'en') return '\ud83c\uddfa\ud83c\uddf8';\n  return '\ud83c\udf10';\n}\n\n// Detect Language \u30ce\u30fc\u30c9\u304b\u3089\u8a00\u8a9e\u3092\u53d6\u5f97\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 \u30e6\u30fc\u30b6\u30fc\u540d\nconst username = $node[\"Get File ID\"].json.from_username || 'unknown';\n\n// Whisper or Detect Language \u306e\u539f\u6587\u30c6\u30ad\u30b9\u30c8\nconst original =\n  $node[\"Extract Transcript\"].json.text ||\n  $node[\"Detect Language\"].json.original_text ||\n  '(no transcript)';\n\n// \u7ffb\u8a33\u7d50\u679c\nconst translated =\n  $node[\"Translate (OpenAI)\"].json.choices[0].message.content ||\n  '(no translation)';\n\n// Slack\u306b\u6295\u7a3f\u3059\u308b\u672c\u6587\nconst text = `*${src} \u2192 ${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": "\ud83d\ude80 Slack Bot\u304c\u6307\u5b9a\u30c1\u30e3\u30f3\u30cd\u30eb\u306b\u7ffb\u8a33\u7d50\u679c\u3092\u6295\u7a3f\u3002\u6295\u7a3f\u8005\u306fBot\u3001\u672c\u6587\u306bTelegram\u540d\u3092\u8868\u793a\u3002",
      "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": {
          "name": "<your credential>"
        }
      },
      "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\" \u30d0\u30a4\u30ca\u30ea\u3092 \"audio\" \u306b\u30b3\u30d4\u30fc\u3057\u3001Whisper\u7528\u306b\u6e21\u3059\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": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "9b9e59f1-67fe-42ba-88b5-3a7259d4340b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -928,
        -976
      ],
      "parameters": {
        "height": 416,
        "content": "### \ud83c\udfaf Purpose  \nDownloads the actual `.oga` or `.mp3` file from Telegram.\n\n### \u2699\ufe0f Setup  \n- Method: `GET`\n- URL: `{{$json.file_url}}`\n- **Send Binary Data:** \u2705 (ON)\n\n### \ud83e\udde9 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": "### \ud83c\udfaf Purpose  \nConstructs the Telegram file URL for download.\n\n### \u2699\ufe0f Setup  \nUse an **Expression**:\n```\nhttps://api.telegram.org/file/bot{{$credentials.telegramApi.accessToken}}/{{$json.file_path}}\n```\n\n### \ud83e\udde9 Output  \n`file_url` \u2192 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": "### \ud83c\udfaf Purpose  \nStarts the workflow when a **voice message** is received in Telegram.\n\n### \u2699\ufe0f Setup  \n- Connect your **Telegram Bot Token** (Credential: `TELEGRAM_BOT_TOKEN`).\n- This node listens for incoming messages (`audio`, `voice`, or `text`).\n\n### \ud83e\udde9 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": "### \ud83c\udfaf Purpose  \nRetrieve the Telegram voice file's metadata.\n\n### \u2699\ufe0f Setup  \n- Input: `file_id` from the Trigger node  \n- Calls Telegram API `getFile` to obtain the `file_path`.\n\n### \ud83e\udde9 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": "### \ud83c\udfaf Purpose  \nPrepare binary audio data for the Whisper node.\n\n### \u2699\ufe0f Setup  \n- Input: `$binary.data`\n- Output: rename to `audio` (binary key expected by Whisper)\n\n### \ud83e\udde9 Output  \nBinary \u2192 `$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": "### \ud83c\udfaf Purpose  \nConvert voice to text using **OpenAI Whisper**.\n\n### \u2699\ufe0f Setup  \n- Credential: `OPENAI_API_KEY_HEADER`\n- Resource: `Audio`\n- Operation: `Transcribe a Recording`\n- Input Data Field Name: `audio`\n\n### \u26a0\ufe0f 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": "### \ud83c\udfaf Purpose  \nDetect source language from the transcription text.\n\n### \u2699\ufe0f Setup  \nSimple **IF or Code node** to detect \u201cja\u201d vs \u201cen\u201d.  \nUsed later for flag direction (\ud83c\uddef\ud83c\uddf5\u2192\ud83c\uddfa\ud83c\uddf8 or \ud83c\uddfa\ud83c\uddf8\u2192\ud83c\uddef\ud83c\uddf5)."
      },
      "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": "### \ud83c\udfaf Purpose  \nTranslate transcribed text using **GPT-4o-mini**.\n\n### \u2699\ufe0f 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### \ud83e\udde9 Output  \n`choices[0].message.content` \u2192 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": "### \ud83c\udfaf Purpose  \nFormats the translated message for Slack.\n\n### \u2699\ufe0f Example (Code node)\n```js\nconst src = $json.source_lang === 'ja' ? '\ud83c\uddef\ud83c\uddf5' : '\ud83c\uddfa\ud83c\uddf8';\nconst dst = $json.target_lang === 'ja' ? '\ud83c\uddef\ud83c\uddf5' : '\ud83c\uddfa\ud83c\uddf8';\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} \u2192 ${dst} (@${username})\\n> ${original}\\n\\n${translated}`;\nreturn [{ json: { slack_text: text } }];\n```\n\n### \ud83e\udde9 Output  \n`slack_text` \u2192 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": "### \ud83c\udfaf Purpose  \nPost the final translated message into Slack.\n\n### \u2699\ufe0f 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### \u2705 Tip  \nUse a test channel first (e.g., `#voice-bridge`) before production.\n"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "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
          }
        ]
      ]
    }
  }
}