AutomationFlowsAI & RAG › Classify Youtube Videos & Generate Email Summaries with Gpt-4 and Gmail

Classify Youtube Videos & Generate Email Summaries with Gpt-4 and Gmail

ByKai Hölters @ezn8n on n8n.io

Monitor YouTube channels, fetch stats, classify videos as viral (≥ 1000 likes) or normal, and auto‑generate LinkedIn/email summaries with GPT‑4. Deliver via Gmail or SMTP. Clear node names, examples, and auditable fields.

Event trigger★★★★☆ complexityAI-powered22 nodesRSS Feed ReadHTTP RequestOpenAIGmail
AI & RAG Trigger: Event Nodes: 22 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #9616 — we link there as the canonical source.

This workflow follows the Gmail → HTTP Request 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 →

Download .json
{
  "id": "VQ7jb5c4TZoVOkoA",
  "name": "YouTube Trend Detector",
  "tags": [],
  "nodes": [
    {
      "id": "2ebed9fe-6a86-4783-85a6-50245bb70355",
      "name": "Manual Run",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1184,
        -432
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3247d7a3-49f7-46a5-bcf1-b147fc9ccf60",
      "name": "Note: Channel IDs",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -832,
        -592
      ],
      "parameters": {
        "width": 320,
        "height": 128,
        "content": "\u26a0\ufe0f IMPORTANT: Provide the YouTube Channel IDs in the Set node (field: ChannelID). After changes, run a manual test (Execute)."
      },
      "typeVersion": 1
    },
    {
      "id": "a6754603-4ee1-4e60-a7ce-6ee43ef47b15",
      "name": "Note: API Key",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        -384
      ],
      "parameters": {
        "width": 360,
        "height": 128,
        "content": "\ud83d\udd10 IMPORTANT: Do not hardcode API keys. Use the credential named \"YouTube_API_Key\" (field: apiKey)."
      },
      "typeVersion": 1
    },
    {
      "id": "5940a68e-25c0-407f-a14e-0e4b22e12962",
      "name": "Note: Threshold",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        -512
      ],
      "parameters": {
        "width": 360,
        "height": 192,
        "content": "\ud83d\udcca Classification: Videos with >= 1000 likes = \"viral\". Adjust by changing constant THRESHOLD in the classification Function node."
      },
      "typeVersion": 1
    },
    {
      "id": "d7c6e66d-08b7-4582-8d13-a40689790dbb",
      "name": "Note: OpenAI",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        800,
        -480
      ],
      "parameters": {
        "width": 360,
        "height": 128,
        "content": "\ud83e\udd16 OpenAI: Ensure credential \"OpenAi account\" exists. You can tweak tone/length of the prompts for LinkedIn/email."
      },
      "typeVersion": 1
    },
    {
      "id": "5016c1d0-90a8-467f-bb76-974f7f51961b",
      "name": "Note: Email",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1648,
        -320
      ],
      "parameters": {
        "width": 420,
        "height": 144,
        "content": "\u2709\ufe0f Email delivery: Use Gmail OAuth (credential: \"Gmail account\") or any SMTP (credential: \"SMTP_Default\"). Always send a test first!"
      },
      "typeVersion": 1
    },
    {
      "id": "4bb30693-3225-4cda-bfcc-a3b9c3e6be98",
      "name": "Set Channel IDs",
      "type": "n8n-nodes-base.set",
      "position": [
        -944,
        -432
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "59e97f03-827a-4a07-a7c6-ab432379489f",
              "name": "ChannelID",
              "type": "array",
              "value": "[\"UC8T5gQ4U4GbI2h8kYCkEcvg\",\"UCkZ3fSYruC0IXv6p34BHciQ\",\"UCP0SLk271Ov781xSxG__7mA\",\"UCM2u6Uvi5XBBlh5GDv4otsg\"]"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "2eb9d77e-544d-499f-bf7b-1fd488170151",
      "name": "Split Channels",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -736,
        -432
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "ChannelID"
      },
      "typeVersion": 1
    },
    {
      "id": "80d0dbab-a261-438f-99b6-3193806606cd",
      "name": "Fetch Latest Videos (RSS)",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        -544,
        -432
      ],
      "parameters": {
        "url": "=https://www.youtube.com/feeds/videos.xml?channel_id={{ $json.ChannelID }}",
        "options": {
          "customFields": ""
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "2852c6a7-c775-4dc8-8410-8a9d9d062cbf",
      "name": "Filter: Published in Last 72h",
      "type": "n8n-nodes-base.if",
      "position": [
        -336,
        -432
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3b3d83aa-b305-4682-9626-846b963c920b",
              "operator": {
                "type": "dateTime",
                "operation": "after"
              },
              "leftValue": "={{ new Date($json.pubDate) }}",
              "rightValue": "={{ new Date(Date.now() - 72*60*60*1000).toISOString() }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "be48b1d0-0cca-4921-a58c-51c9fddeecc7",
      "name": "Get Video Stats (YouTube API)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -32,
        -224
      ],
      "parameters": {
        "url": "https://www.googleapis.com/youtube/v3/videos",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "id",
              "value": "={{ $json.link.includes('shorts') ? $json.link.split('/shorts/')[1] : $json.link.split('v=')[1].split('&')[0] }}"
            },
            {
              "name": "part",
              "value": "snippet,statistics"
            }
          ]
        }
      },
      "credentials": {
        "httpQueryAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0e868e00-221a-415c-9528-92df62c3a96d",
      "name": "Classify by Likes (Code)",
      "type": "n8n-nodes-base.code",
      "position": [
        320,
        -288
      ],
      "parameters": {
        "jsCode": "// Classify YouTube videos by like count\nconst THRESHOLD = 1000;\n\nfunction extractNumberFrom(...candidates) {\n  for (const v of candidates) {\n    if (v === undefined || v === null) continue;\n    if (typeof v === 'number' && Number.isFinite(v)) return v;\n    if (typeof v === 'string') {\n      const digits = v.replace(/\\D/g, '');\n      if (digits.length > 0) return parseInt(digits, 10);\n    }\n  }\n  return null;\n}\n\nfunction processVideo(video) {\n  const v = JSON.parse(JSON.stringify(video));\n  const likeCount = extractNumberFrom(v?.statistics?.likeCount);\n  const videoId = v?.id || null;\n\n  let classification = 'unknown';\n  let needsStatsFetch = false;\n\n  if (likeCount === null) {\n    needsStatsFetch = true;\n  } else if (likeCount >= THRESHOLD) {\n    classification = 'viral';\n  } else {\n    classification = 'normal';\n  }\n\n  return {\n    json: {\n      videoId,\n      title: v?.snippet?.title ?? null,\n      likeCount,\n      classification,\n      needsStatsFetch,\n      original: v\n    }\n  };\n}\n\nconst allResults = [];\nfor (const item of items) {\n  const payload = item.json || {};\n  if (Array.isArray(payload.items)) {\n    for (const video of payload.items) allResults.push(processVideo(video));\n  } else if (payload.kind && payload.kind.includes('youtube#video')) {\n    allResults.push(processVideo(payload));\n  }\n}\nreturn allResults;"
      },
      "typeVersion": 2
    },
    {
      "id": "13658cae-f478-44b8-95d5-f19162619a29",
      "name": "Branch: Normal",
      "type": "n8n-nodes-base.switch",
      "position": [
        544,
        -528
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Normal Video",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "f09c902d-b305-4c2e-b274-a39de158f7c7",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.classification }}",
                    "rightValue": "normal"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Viral Video",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "feca5977-333f-4e27-b47c-0315592fafb9",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.classification }}",
                    "rightValue": "viral"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "44b9d667-e6e5-46fb-9a2f-605790e2829d",
      "name": "Branch: Viral",
      "type": "n8n-nodes-base.switch",
      "position": [
        544,
        -336
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Normal Video",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "f09c902d-b305-4c2e-b274-a39de158f7c7",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.classification }}",
                    "rightValue": "normal"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Viral Video",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "feca5977-333f-4e27-b47c-0315592fafb9",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.classification }}",
                    "rightValue": "viral"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "ebd22026-27b2-4f94-a7b6-1bcf82f7dc4d",
      "name": "Write Post (Normal)",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        800,
        -608
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "GPT-4.1-MINI"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a social media strategist. Your job is to turn technical news into concise, professional LinkedIn posts. Style: clear, analytical, discussion-oriented. Output only the final post text."
            },
            {
              "role": "user",
              "content": "=TASK: Create an informative LinkedIn post about the video below.\n\nVIDEO TITLE:\n{{ $json.title }}\n\nCLASSIFICATION:\n{{ $json.classification }}\n\nVIDEO SUMMARY (from description):\n\"\"\"\n{{ $json.original.snippet.description }}\n\"\"\"\n\nINSTRUCTIONS:\n1) Start with a question that captures the core topic (e.g., \"Did you know how\u2026?\").\n2) Extract the 2\u20133 most important facts as bullet points.\n3) Explain who benefits (1\u20132 sentences).\n4) Invite discussion with a closing question.\n5) Add 4\u20135 specific hashtags."
            }
          ]
        },
        "simplify": false
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "d0b32894-7c5b-49ef-8172-f684be68c1e8",
      "name": "Write Post (Viral)",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        816,
        -336
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "GPT-4.1-MINI"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a social media strategist. Your job is to turn technical news into concise, professional LinkedIn posts. Style: clear, analytical, discussion-oriented. Output only the final post text."
            },
            {
              "role": "user",
              "content": "=TASK: Create a LinkedIn post using the precise data below.\n\nVIDEO TITLE:\n{{ $json.title }}\n\nRELEVANCE:\n{{ $json.classification }}\n\nVIDEO SUMMARY (from description):\n\"\"\"\n{{ $json.original.snippet.description }}\n\"\"\"\n\nINSTRUCTIONS:\n1) Strong hook question referencing title and relevance.\n2) 3 key takeaways as bullets.\n3) Short professional angle (1\u20132 sentences) for engineers.\n4) Open question as CTA.\n5) 4\u20135 relevant hashtags."
            }
          ]
        },
        "simplify": false
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "e88b848f-b6e5-4461-85ec-87598dd568a7",
      "name": "Aggregate Posts for Briefing",
      "type": "n8n-nodes-base.code",
      "position": [
        1136,
        -480
      ],
      "parameters": {
        "jsCode": "// Collect all post texts from previous steps and aggregate into one string\nconst allPosts = [];\nfor (const item of items) {\n  const content = item.json?.choices?.[0]?.message?.content;\n  if (content) allPosts.push(content);\n}\nconst combinedText = allPosts.join('\\n\\n---\\n\\n');\nreturn [{ json: { weekly_summary_input: combinedText } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "8fcdb1d5-914d-4d6d-b4d2-4178665851f6",
      "name": "Generate Weekly Briefing (HTML)",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1344,
        -480
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5",
          "cachedResultName": "GPT-5"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "=You act as Head of Intelligence for system integrators & AI engineers. Goal: a weekly, lossless, compact email briefing as valid HTML (Gmail-robust); no raw-dump.\n\nNon-negotiables: No loss, signal over noise, zero hallucination, strict HTML output. Include audit: entity index, evidence snippets (\u2264160 chars), SHA-256 input hash. 600px centered table layout, system fonts, no external assets. Exactly one <h1>, 4\u20135 deep dives, strategy section, coverage log. Output must start with <!DOCTYPE html>."
            },
            {
              "role": "user",
              "content": "=Create the internal \"AI News Weekly Briefing\" as a single Gmail-robust HTML document from the raw text below.\n\nRAW INPUT\n\"\"\"\n{{ $json.weekly_summary_input }}\n\"\"\"\n\nLANGUAGE: English (EN)\n\nSTRUCTURE: <h1> lead trend; <p><em>intro</em></p>; 4\u20135 <h2> deep dives (90\u2013140 words, \u22652 bolded terms from input); <hr>; <h2>Strategic Outlook</h2>; <h2>Coverage Log</h2> with input hash, entity index, and 2-column evidence table.\n\nGate: If output does not begin with <!DOCTYPE html>, regenerate until valid."
            }
          ]
        },
        "simplify": false
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "0aef6b05-0ffa-447a-b398-f644c74bb928",
      "name": "Send Weekly Briefing (Gmail)",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1696,
        -480
      ],
      "parameters": {
        "sendTo": "",
        "message": "={{ $json.choices[0].message.content }}",
        "options": {},
        "subject": "Weekly AI Briefing"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "2c070188-35a8-41da-a39c-ac2e03a828cf",
      "name": "Note: Setup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1152,
        -256
      ],
      "parameters": {
        "width": 420,
        "height": 224,
        "content": "Title: Setup \u2014 Your YouTube Channels\nEnter the Channel IDs (UC\u2026) you want to monitor in the Set node. You can copy the ID from the channel URL or the About section."
      },
      "typeVersion": 1
    },
    {
      "id": "b029dbaf-7ffb-49d5-bb59-3feb6d7b658c",
      "name": "Note: YouTube API",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        -32
      ],
      "parameters": {
        "width": 420,
        "height": 176,
        "content": "Title: API-Key Configuration\nEnsure a valid YouTube Data API v3 credential exists. The request uses part=snippet,statistics to retrieve both title/description and likes. Classification fails without statistics."
      },
      "typeVersion": 1
    },
    {
      "id": "5825dbd0-cc4c-46aa-befa-1c57a8f3fdcd",
      "name": "Note: Logic",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        528,
        -160
      ],
      "parameters": {
        "width": 420,
        "height": 288,
        "content": "Title: Logic \u2014 What counts as \"viral\"?\nRouting is based on the classification from the previous step. Threshold currently at 1000 likes (see Classify by Likes). Separate prompts emphasize urgency (viral) vs. information (normal)."
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "c43875bf-454d-44b9-b43d-f3d7ae08cd95",
  "connections": {
    "Manual Run": {
      "main": [
        [
          {
            "node": "Set Channel IDs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Branch: Viral": {
      "main": [
        [],
        [
          {
            "node": "Write Post (Viral)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Branch: Normal": {
      "main": [
        [
          {
            "node": "Write Post (Normal)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Channels": {
      "main": [
        [
          {
            "node": "Fetch Latest Videos (RSS)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Channel IDs": {
      "main": [
        [
          {
            "node": "Split Channels",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write Post (Viral)": {
      "main": [
        [
          {
            "node": "Aggregate Posts for Briefing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write Post (Normal)": {
      "main": [
        [
          {
            "node": "Aggregate Posts for Briefing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classify by Likes (Code)": {
      "main": [
        [
          {
            "node": "Branch: Viral",
            "type": "main",
            "index": 0
          },
          {
            "node": "Branch: Normal",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Latest Videos (RSS)": {
      "main": [
        [
          {
            "node": "Filter: Published in Last 72h",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Posts for Briefing": {
      "main": [
        [
          {
            "node": "Generate Weekly Briefing (HTML)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter: Published in Last 72h": {
      "main": [
        [
          {
            "node": "Get Video Stats (YouTube API)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get Video Stats (YouTube API)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Video Stats (YouTube API)": {
      "main": [
        [
          {
            "node": "Classify by Likes (Code)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Weekly Briefing (HTML)": {
      "main": [
        [
          {
            "node": "Send Weekly Briefing (Gmail)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Monitor YouTube channels, fetch stats, classify videos as viral (≥ 1000 likes) or normal, and auto‑generate LinkedIn/email summaries with GPT‑4. Deliver via Gmail or SMTP. Clear node names, examples, and auditable fields.

Source: https://n8n.io/workflows/9616/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Domain Outbound Machine is an n8n workflow designed to fully automate the domain sales process: lead generation, email extraction, personalized outreach, and automated email sending. It also stores ex

Google Sheets, HTTP Request, Gmail +1
AI & RAG

This workflow is for eCommerce researchers, affiliate marketers, and anyone who needs to compare product listings across sites like Amazon. It’s perfect for quickly identifying top product picks based

Form Trigger, HTTP Request, OpenAI +2
AI & RAG

This workflow delivers a complete, enterprise-grade Gmail automation system designed for high-volume teams. It classifies incoming emails, applies labels, generates AI-powered responses, and routes me

Gmail, OpenAI, Telegram +3
AI & RAG

Social Media Audio Extractor. Uses telegramTrigger, telegram, openAi, httpRequest. Event-driven trigger; 31 nodes.

Telegram Trigger, Telegram, OpenAI +2
AI & RAG

Baby Chaganti. Uses httpRequest, googleDrive, youTube, openAi. Event-driven trigger; 23 nodes.

HTTP Request, Google Drive, YouTube +1