{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "811c6105-ea89-443f-a030-ea05cb5c917e",
      "name": "Send Working on it Message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        112,
        -160
      ],
      "parameters": {
        "text": "Found it! \ud83c\udfac fetching transcript and generating audio... this may take a minute.",
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "cdc0417e-b7be-4c54-9834-074b6e502918",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1744,
        64
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"genre\": \"The detected genre (e.g., 'True Crime', 'Cooking', 'Tech News')\",\n  \"title\": \"A catchy, click-worthy title for this episode\",\n  \"summary\": \"A short, punchy 2-sentence caption for a Telegram post.\",\n  \"script\": \"The full podcast script text for the Text-to-Speech engine. Do not include speaker labels (like 'Host:'). Just the spoken text.\"\n}\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "5f4600db-3bdc-4be6-8f29-49c3ede4c46f",
      "name": "Check for Transcript Error",
      "type": "n8n-nodes-base.if",
      "position": [
        720,
        -160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "350a77ba-a9bc-4f68-ab4d-f722f70721be",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.results[0].content.error ? true : false }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "7ab7dbf3-32c8-4de5-9c69-2b28901f8105",
      "name": "Send Error Message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        112,
        64
      ],
      "parameters": {
        "text": "\u274c That doesn't look like a valid YouTube video link. Please send a link like youtube.com/watch?v=... or youtu.be/...",
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "b4d2ab66-5951-4612-b154-0a99844c0806",
      "name": "Send Transcript Failed Message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1104,
        -432
      ],
      "parameters": {
        "text": "=\u26a0\ufe0f **Transcript Failed**\nI couldn't extract text from this video. It might not have captions available.\n**Reason:**\n{{ $json.results[0].content.error.message }}",
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "parse_mode": "Markdown",
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "9a768193-4d86-45f6-a8e6-40ab72b67e34",
      "name": "Send Text Summary",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2976,
        -144
      ],
      "parameters": {
        "text": "=<b>{{ $('AI Summarizer').item.json.output.title }}</b>\n\n#{{ $('AI Summarizer').item.json.output.genre.replace(/ /g, '') }}\n\n<blockquote>{{ $('AI Summarizer').item.json.output.summary }}</blockquote>\n",
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "parse_mode": "HTML",
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c91b2215-c84d-4289-a3c9-bd0be3e5e99d",
      "name": "Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -928,
        -48
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {
          "userIds": "66336158"
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "fe4f3779-421b-4059-a97b-a5fd5c881142",
      "name": "Check: Is Valid URL?",
      "type": "n8n-nodes-base.if",
      "position": [
        -160,
        -48
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "5b79df44-ef8d-4983-923b-be8a08ca90ec",
              "operator": {
                "type": "string",
                "operation": "regex"
              },
              "leftValue": "={{ $('Telegram Trigger').item.json.message.text }}",
              "rightValue": "(?:https?:\\/\\/)?(?:www\\.)?(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/)[a-zA-Z0-9_-]{11}(?:[?&].*)?$"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "32f07420-e432-4fa7-927e-622ec069bd96",
      "name": "Decodo (Fetch Transcript)",
      "type": "@decodo/n8n-nodes-decodo.decodo",
      "position": [
        496,
        -160
      ],
      "parameters": {
        "video_id": "={{ $('Telegram Trigger').item.json.message.text.match(/(?:youtu\\.be\\/|youtube\\.com\\/(?:.*v=|.*\\/|shorts\\/))([a-zA-Z0-9_-]{11})/)[1] }}",
        "operation": "youtube_transcript",
        "language_code": "en"
      },
      "credentials": {
        "decodoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e4659ed6-073b-4a15-a04b-5cd36828f66e",
      "name": "Code: Format Transcript",
      "type": "n8n-nodes-base.code",
      "position": [
        1120,
        -144
      ],
      "parameters": {
        "jsCode": "const content = $input.first().json.results?.[0]?.content;\n\n// Safety check: Ensure content is actually an array (valid transcript)\n// If it's an object (error) or null, return empty text.\nif (!Array.isArray(content)) {\n    return [{ json: { transcript: \"\" } }];\n}\n\nconst fullText = content.map(item => {\n    return item.transcriptSegmentRenderer?.snippet?.runs?.[0]?.text || \"\";\n}).join(' ');\n\nreturn [{ json: { transcript: fullText } }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "ac225b4f-5923-4415-94b6-7652d3dc6640",
      "name": "AI Summarizer",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1584,
        -144
      ],
      "parameters": {
        "text": "=**Input Transcript:**\n{{ $json.transcript }}\n",
        "options": {
          "systemMessage": "=You are an expert Audio Summarizer. Your goal is to convert raw video transcripts into clear, concise, and easy-to-listen-to summaries.\n\n**CRITICAL INSTRUCTION:**\nYou MUST write the entire summary, title, and script in **{{ $('Config').item.json.output_language }}**.\n\n**Phase 1: Analyze the Content**\nDetermine the core subject matter (e.g., Cooking, Tech, History, News) and adopt a tone that fits:\n* **Educational:** Clear, instructional, and logical.\n* **News/Business:** Professional, objective, and direct.\n* **Story/Entertainment:** Engaging but descriptive.\n\n**Phase 2: Critical Content Extraction**\n**Do not miss the main point.** Identify the central argument, key facts, or the most valuable takeaway. The summary must deliver the value of the video without the fluff.\n\n**Phase 3: Script Guidelines**\n1.  **The Opening:** You MUST start the script with the phrase: \"This is a summary of the video...\" followed by the main topic or title.\n2.  **No Visual Cues:** The listener cannot see the video. Do NOT use phrases like \"as you can see\" or \"in this chart.\" Rephrase them verbally.\n3.  **Direct & Clean:** Remove filler words, speaker labels, and conversational tangents. Just deliver the information.\n4.  **Strict Length:** The script must be **less than 300 words**.\n\n**Output Schema (Strict JSON):**\nYou must output a single valid JSON object. Do not wrap it in markdown code blocks. Use this exact structure:\n{\n  \"genre\": \"The detected genre (e.g., 'True Crime', 'Cooking', 'Tech News')\",\n  \"title\": \"A descriptive title for the file\",\n  \"summary\": \"A short, punchy 2-sentence text caption for Telegram.\",\n  \"script\": \"The full text for the Text-to-Speech engine to read. Start with 'This is a summary of the video...'.\"\n}\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "retryOnFail": true,
      "typeVersion": 3
    },
    {
      "id": "1450bc79-d17f-4b03-9f63-06ae4d4ea174",
      "name": "OpenAI TTS (Create Audio)",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        2240,
        -144
      ],
      "parameters": {
        "input": "={{ $json.output.script }}",
        "options": {},
        "resource": "audio"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "9e310f82-0404-419d-bc26-6143de3955e1",
      "name": "Send Audio Summary",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2752,
        -144
      ],
      "parameters": {
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "operation": "sendAudio",
        "binaryData": true,
        "additionalFields": {
          "fileName": "Summary"
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8f926a5f-2b5c-44bb-b33f-3be5620b8553",
      "name": "Config",
      "type": "n8n-nodes-base.set",
      "position": [
        -592,
        -48
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9477bd4a-b727-4ee2-80b3-4622dfae6230",
              "name": "output_language",
              "type": "string",
              "value": "English"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a1a28a7f-6126-4fa3-967c-201d63d36da5",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1504,
        -368
      ],
      "parameters": {
        "width": 496,
        "height": 624,
        "content": "## \ud83c\udf99\ufe0f Generate YouTube Audio Summaries: Decodo & OpenAI\n\nThis powerful workflow automates the process of converting any YouTube video URL into a concise, spoken **Audio Summary (MP3)**. It leverages **Decodo** for transcript extraction, **OpenAI** for summary scripting, and for high-quality Text-to-Speech, all delivered via **Telegram**.\n\n**Core Functions:**\n* **Generate:** Creates the final Audio Summary and clean metadata.\n* **Extract:** Pulls full transcripts from YouTube videos via Decodo.\n* **Summarize:** OpenAI converts the text into a clear, objective audio script (configurable language).\n* **Deliver:** Sends the audio file + structured metadata (Genre, Summary) to Telegram.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e16ff831-54be-494c-a1fc-00d3096d33da",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -736,
        -368
      ],
      "parameters": {
        "color": 4,
        "width": 384,
        "height": 624,
        "content": "## \u2699\ufe0f Configuration\nDouble-click the Config node to set your settings:\n* **`output_language`**: (e.g., 'English', 'Spanish', 'German'). The AI and Audio Engine will automatically adapt to this language."
      },
      "typeVersion": 1
    },
    {
      "id": "2eaf9450-2fa8-405c-927b-8f702493cf39",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -256,
        -368
      ],
      "parameters": {
        "color": 4,
        "width": 576,
        "height": 624,
        "content": "## \ud83d\udee1\ufe0f Input Validation\n* **Regex Check:** Ensures the user sent a valid YouTube URL.\n* **UX:** Sends a \"Working on it...\" message so the user knows the bot is processing.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ccf8ce46-930b-4e29-b721-4eec2e8a6e4d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        416,
        -368
      ],
      "parameters": {
        "color": 4,
        "width": 480,
        "height": 624,
        "content": "## \ud83d\udce5 Transcript Extraction\n* **Decodo:** Fetches the raw JSON transcript from the video.\n* **Setup:** Double-click to enter your API Key. (See the **80% OFF** deal nearby to get started!).\n* **Error Check:** If a video has no captions (or is a music video), the **If Node** catches the error and notifies the user instead of breaking the workflow.\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "85ded5ea-4765-4be3-aece-5e38498a7b96",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        976,
        -176
      ],
      "parameters": {
        "color": 4,
        "width": 384,
        "height": 432,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## \ud83d\udcdd Formatting\nThis Code node flattens the deep JSON structure from Decodo into a clean text string that the AI can read.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4b19df1d-3633-4ffb-9be9-19b82ba836af",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1440,
        -368
      ],
      "parameters": {
        "color": 4,
        "width": 528,
        "height": 624,
        "content": "## \ud83e\udde0 AI Summarization (OpenAI)\n* **Model:** Uses **OpenAI gpt-4o-mini** for its large context window (capable of reading long videos).\n* **Structure:** The System Prompt instructs the AI to act as an \"Audio Summarizer\" and output clean JSON containing the Title, Genre, Summary, and Audio Script."
      },
      "typeVersion": 1
    },
    {
      "id": "a93bea12-cad8-418f-9510-abb4e9f59be0",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2048,
        -368
      ],
      "parameters": {
        "color": 4,
        "width": 480,
        "height": 624,
        "content": "## \ud83c\udf99\ufe0f Audio Generation\n* **OpenAI TTS:** Converts the text script into a high-quality MP3 file.\n* **Model:** Uses `tts-1` for fast generation."
      },
      "typeVersion": 1
    },
    {
      "id": "279fb0ff-17a8-4e93-a16c-d37a8d9eaf89",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2608,
        -368
      ],
      "parameters": {
        "color": 4,
        "width": 624,
        "height": 624,
        "content": "## \u2708\ufe0f  Delivery\nSends two messages back to the user:\n1.  **Audio:** The generated MP3 file.\n2.  **Text:** A formatted HTML summary with the video title, genre tag, and link.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "cf847ab7-cd6e-4604-9d2c-fbe06c787c6c",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        416,
        -608
      ],
      "parameters": {
        "color": 3,
        "width": 480,
        "height": 208,
        "content": "## \ud83c\udf81 Exclusive 80% Discount!\n\nGet **80% OFF** the **23k Advanced Scraping API** plan at Decodo using this workflow.\n\n**Coupon Code:** `ATTAN8N`\n\n\ud83d\udc49 [**Click here to Sign Up & Claim**](https://visit.decodo.com/c/6679292/3071239/17480)\n"
      },
      "typeVersion": 1
    },
    {
      "id": "09b1767c-0c92-48a1-8dcb-cfdc038cea5d",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1568,
        64
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    }
  ],
  "connections": {
    "Config": {
      "main": [
        [
          {
            "node": "Check: Is Valid URL?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Summarizer": {
      "main": [
        [
          {
            "node": "OpenAI TTS (Create Audio)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Summarizer",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Send Text Summary": {
      "main": [
        []
      ]
    },
    "Send Audio Summary": {
      "main": [
        [
          {
            "node": "Send Text Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check: Is Valid URL?": {
      "main": [
        [
          {
            "node": "Send Working on it Message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Error Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: Format Transcript": {
      "main": [
        [
          {
            "node": "AI Summarizer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "AI Summarizer",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Decodo (Fetch Transcript)": {
      "main": [
        [
          {
            "node": "Check for Transcript Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI TTS (Create Audio)": {
      "main": [
        [
          {
            "node": "Send Audio Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for Transcript Error": {
      "main": [
        [
          {
            "node": "Send Transcript Failed Message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Code: Format Transcript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Working on it Message": {
      "main": [
        [
          {
            "node": "Decodo (Fetch Transcript)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}