AutomationFlowsAI & RAG › Generate an AI Youtube Trend Report with Gpt-4o, Google Sheets and Pdf.co

Generate an AI Youtube Trend Report with Gpt-4o, Google Sheets and Pdf.co

ByMilo Bravo @milobravo1 on n8n.io

Who is this for? AI creators, marketers, agencies, and researchers tracking YouTube trends who need weekly high-signal insights without 4+ hours manual research.

Cron / scheduled trigger★★★★★ complexityAI-powered30 nodesHTTP RequestOpenAIGoogle SheetsN8N Nodes PdfcoGmail
AI & RAG Trigger: Cron / scheduled Nodes: 30 Complexity: ★★★★★ AI nodes: yes Added:

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

This workflow follows the Gmail → Google Sheets 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": "2yjWLNgI8C0Xsdvk",
  "name": "AI YouTube Trend Intelligence Report TEMPLATE",
  "tags": [],
  "nodes": [
    {
      "id": "c966d5d6-91be-4d8a-a410-97bbd932c260",
      "name": "Weekly Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1008,
        800
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 7 * * 1"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "b3106b1c-1bb1-4131-9d7f-52c1227be8e2",
      "name": "Set Keywords",
      "type": "n8n-nodes-base.code",
      "position": [
        1232,
        800
      ],
      "parameters": {
        "jsCode": "const keywords = [\n  'AI automation 2025',\n  'AI agents workflow',\n  'n8n automation tutorial',\n  'ChatGPT automation',\n  'AI tools productivity',\n  'LLM workflow builder',\n  'no-code AI automation',\n  'Make automation AI',\n  'AI video creation',\n  'artificial intelligence business'\n];\nconst publishedAfter = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();\nreturn keywords.map(keyword => ({ json: { keyword, publishedAfter } }));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "ad050a78-3bc9-4534-afeb-bcc8000b9425",
      "name": "Search YouTube",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1520,
        800
      ],
      "parameters": {
        "url": "https://www.googleapis.com/youtube/v3/search",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "={{ $json.keyword }}"
            },
            {
              "name": "type",
              "value": "video"
            },
            {
              "name": "maxResults",
              "value": "50"
            },
            {
              "name": "order",
              "value": "viewCount"
            },
            {
              "name": "publishedAfter",
              "value": "={{ $json.publishedAfter }}"
            },
            {
              "name": "regionCode",
              "value": "US"
            },
            {
              "name": "part",
              "value": "snippet"
            }
          ]
        }
      },
      "credentials": {
        "httpQueryAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "8a109781-1977-4c9b-8c3c-b49af46c2ef7",
      "name": "Flatten Videos",
      "type": "n8n-nodes-base.code",
      "position": [
        1680,
        800
      ],
      "parameters": {
        "jsCode": "const keywordItems = $('Set Keywords').all();\nconst searchResultItems = $input.all();\nconst allVideos = [];\nconst seenIds = new Set();\n\nfor (let i = 0; i < searchResultItems.length; i++) {\n  const keyword = keywordItems[i]?.json?.keyword || ('keyword_' + i);\n  const responseItems = searchResultItems[i]?.json?.items || [];\n  for (const video of responseItems) {\n    const videoId = video.id?.videoId;\n    if (!videoId || seenIds.has(videoId)) continue;\n    seenIds.add(videoId);\n    allVideos.push({\n      json: {\n        videoId,\n        keyword,\n        title: video.snippet?.title || 'Unknown Title',\n        channelId: video.snippet?.channelId || '',\n        channelTitle: video.snippet?.channelTitle || '',\n        publishedAt: video.snippet?.publishedAt || '',\n        thumbnail: video.snippet?.thumbnails?.high?.url ||\n                   video.snippet?.thumbnails?.medium?.url ||\n                   ('https://img.youtube.com/vi/' + videoId + '/hqdefault.jpg')\n      }\n    });\n  }\n}\nif (allVideos.length === 0) return [{ json: { videoId: '_placeholder', keyword: 'none' } }];\nreturn allVideos;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "201072e9-278b-4340-932e-e65f5c1a4884",
      "name": "Prep ID Batches",
      "type": "n8n-nodes-base.code",
      "position": [
        1904,
        800
      ],
      "parameters": {
        "jsCode": "const BATCH_SIZE = 50;\nconst allIds = $input.all()\n  .filter(item => item.json.videoId && item.json.videoId !== '_placeholder')\n  .map(item => item.json.videoId);\nconst uniqueIds = [...new Set(allIds)];\nconst batches = [];\nfor (let i = 0; i < uniqueIds.length; i += BATCH_SIZE) {\n  batches.push({\n    json: {\n      videoIdBatch: uniqueIds.slice(i, i + BATCH_SIZE).join(','),\n      batchNum: Math.floor(i / BATCH_SIZE) + 1\n    }\n  });\n}\nif (batches.length === 0) return [{ json: { videoIdBatch: '', batchNum: 0 } }];\nreturn batches;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "120b67e6-37af-45ce-9fde-d75e44fa5f48",
      "name": "Get Video Stats",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2128,
        800
      ],
      "parameters": {
        "url": "https://www.googleapis.com/youtube/v3/videos",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "id",
              "value": "={{ $json.videoIdBatch }}"
            },
            {
              "name": "part",
              "value": "statistics,snippet,contentDetails"
            },
            {
              "name": "maxResults",
              "value": "50"
            }
          ]
        }
      },
      "credentials": {
        "httpQueryAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "683eecbf-6b8d-4f30-8f72-bec5a42d83b6",
      "name": "Rank Videos",
      "type": "n8n-nodes-base.code",
      "position": [
        2352,
        800
      ],
      "parameters": {
        "jsCode": "const allDetails = [];\nconst seenIds = new Set();\n\nfor (const item of $input.all()) {\n  for (const video of (item.json.items || [])) {\n    if (seenIds.has(video.id)) continue;\n    seenIds.add(video.id);\n    const views = parseInt(video.statistics?.viewCount || '0');\n    const likes = parseInt(video.statistics?.likeCount || '0');\n    const comments = parseInt(video.statistics?.commentCount || '0');\n    const engagementRate = views > 0 ? parseFloat(((likes + comments) / views * 100).toFixed(3)) : 0;\n    allDetails.push({\n      videoId: video.id,\n      title: video.snippet?.title || '',\n      channelId: video.snippet?.channelId || '',\n      channelTitle: video.snippet?.channelTitle || '',\n      publishedAt: video.snippet?.publishedAt || '',\n      thumbnail: video.snippet?.thumbnails?.high?.url ||\n                 video.snippet?.thumbnails?.medium?.url ||\n                 ('https://img.youtube.com/vi/' + video.id + '/hqdefault.jpg'),\n      tags: (video.snippet?.tags || []).slice(0, 10),\n      description: (video.snippet?.description || '').substring(0, 300),\n      views, likes, comments, engagementRate,\n      duration: video.contentDetails?.duration || ''\n    });\n  }\n}\n\n// Relevance filtering: check if video contains relevant keywords\nconst relevanceKeywords = [\n  'automation', 'ai agent', 'workflow', 'n8n', 'make.com', 'zapier',\n  'agentic', 'orchestration', 'llm', 'chatbot', 'business automation',\n  'no-code', 'low-code'\n];\n\nconst filteredDetails = allDetails.filter(video => {\n  const searchText = (\n    video.title.toLowerCase() + ' ' +\n    video.description.toLowerCase() + ' ' +\n    video.tags.join(' ').toLowerCase()\n  );\n  return relevanceKeywords.some(keyword => searchText.includes(keyword));\n});\n\n// Use filtered videos if we have enough, otherwise fall back to all\nconst videosToRank = filteredDetails.length >= 10 ? filteredDetails : allDetails;\n\nvideosToRank.sort((a, b) => b.views - a.views);\nconst top50 = videosToRank.slice(0, 50);\nconst top10 = top50.slice(0, 10);\n\nconst searchVideos = $('Flatten Videos').all();\nconst videoKeywordMap = {};\nfor (const item of searchVideos) {\n  if (item.json.videoId) videoKeywordMap[item.json.videoId] = item.json.keyword || 'other';\n}\nfor (const v of top50) v.keyword = videoKeywordMap[v.videoId] || 'other';\n\nconst channelMap = {};\nfor (const v of top50) {\n  if (!channelMap[v.channelId]) {\n    channelMap[v.channelId] = { channelId: v.channelId, channelTitle: v.channelTitle, videoCount: 0, totalViews: 0, topVideo: null };\n  }\n  channelMap[v.channelId].videoCount++;\n  channelMap[v.channelId].totalViews += v.views;\n  if (!channelMap[v.channelId].topVideo || v.views > channelMap[v.channelId].topVideo.views) {\n    channelMap[v.channelId].topVideo = { title: v.title, views: v.views, videoId: v.videoId };\n  }\n}\nconst topChannels = Object.values(channelMap).sort((a, b) => b.totalViews - a.totalViews).slice(0, 10);\n\nconst keywordCounts = {};\nfor (const v of videosToRank) {\n  const kw = videoKeywordMap[v.videoId] || 'other';\n  keywordCounts[kw] = (keywordCounts[kw] || 0) + 1;\n}\n\nconst reportDate = new Date().toLocaleDateString('en-US', {\n  weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'\n});\n\nreturn [{ json: { top10Videos: top10, top50Videos: top50, topChannels, keywordCounts, totalVideosAnalyzed: videosToRank.length, reportDate } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "1552648b-4a9f-467c-b476-7d245f1c9216",
      "name": "Prep AI Prompt",
      "type": "n8n-nodes-base.code",
      "position": [
        2576,
        800
      ],
      "parameters": {
        "jsCode": "// Reads ranked video data from Rank Videos node\n// Passes spreadsheetUrl (from Finalize Spreadsheet) through to downstream nodes\nconst data = $('Rank Videos').first().json;\nconst spreadsheetUrl = $json.spreadsheetUrl || '';\n\n// Defensive: ensure we always have objects/arrays\nconst top50Videos = Array.isArray(data.top50Videos) ? data.top50Videos : [];\nconst topChannels = Array.isArray(data.topChannels) ? data.topChannels : [];\nconst keywordCounts = data.keywordCounts && typeof data.keywordCounts === 'object'\n  ? data.keywordCounts\n  : {};\n\nconst top20 = top50Videos.slice(0, 20);\nconst totalVideosAnalyzed = Number(data.totalVideosAnalyzed || 0);\n\nconst videoSummary = top20.map((v, i) =>\n  (i + 1) + '. \"' + (v.title || 'Untitled') + '\" by ' + (v.channelTitle || 'Unknown') +\n  ' | Views: ' + Number(v.views || 0).toLocaleString() +\n  ' | Engagement: ' + (v.engagementRate ?? 'N/A') + '%' +\n  ' | Published: ' + (v.publishedAt ? new Date(v.publishedAt).toLocaleDateString() : 'N/A') +\n  ' | Tags: ' + (Array.isArray(v.tags) ? v.tags : []).slice(0, 5).join(', ')\n).join('\\n');\n\nconst channelSummary = topChannels.slice(0, 5).map(c =>\n  '- ' + (c.channelTitle || 'Unknown') + ': ' +\n  Number(c.videoCount || 0) + ' videos, ' +\n  Number(c.totalViews || 0).toLocaleString() + ' combined views'\n).join('\\n');\n\nconst kwSummary = Object.entries(keywordCounts)\n  .sort((a, b) => b[1] - a[1])\n  .map(([k, v]) => k + ': ' + v + ' videos')\n  .join(', ');\n\nconst prompt = [\n  'You are an expert AI/YouTube content strategist. Analyze this data from the past 7 days in the AI & automation niche.',\n  '',\n  'TOP 20 TRENDING VIDEOS:',\n  videoSummary,\n  '',\n  'TOP CHANNELS THIS WEEK:',\n  channelSummary,\n  '',\n  'VIDEO COUNT BY KEYWORD: ' + kwSummary,\n  'TOTAL VIDEOS ANALYZED: ' + totalVideosAnalyzed,\n  '',\n  'Respond with ONLY valid JSON (no markdown code blocks) in this exact structure:',\n  '{',\n  '  \"executiveSummary\": [\"bullet1\",\"bullet2\",\"bullet3\",\"bullet4\",\"bullet5\"],',\n  '  \"trendingTopics\": [{\"topic\":\"Name\",\"description\":\"Why trending and what angle creators take\",\"examples\":[\"title1\",\"title2\",\"title3\"]}],',\n  '  \"contentRecommendations\": [{\"title\":\"Video Title Idea\",\"rationale\":\"Why this would perform well\",\"targetKeywords\":[\"kw1\",\"kw2\",\"kw3\"]}],',\n  '  \"spaceSentiment\": \"2-3 sentence overview of the AI content space mood this week\",',\n  '  \"channelInsights\": \"3-4 sentences on what top channels are doing right\"',\n  '}',\n  '',\n  'Include EXACTLY 5 trendingTopics and EXACTLY 6 contentRecommendations.',\n  'Base ALL analysis on the actual data provided. No generic filler content.',\n  'Each executiveSummary bullet should be 20-40 words of actionable insight.'\n].join('\\n');\n\nreturn [{ json: { prompt, spreadsheetUrl } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "1d14b200-2927-4d25-8a84-947bfd1a68cf",
      "name": "Analyze Trends with AI",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        2800,
        800
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5.2",
          "cachedResultName": "GPT-5.2"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "content": "={{ $json.prompt }}"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "d64ffc0a-590c-460b-8392-d55f06766de3",
      "name": "Setup Guide",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        672
      ],
      "parameters": {
        "width": 912,
        "height": 576,
        "content": "---\n## Setup Guide\nFollow these steps to get started:\n1. **Set up the Trend Finder Form**\n   Customize the form fields (Topic Name, Last How Many Days) in the **Form Trigger** node. This is how users input their niche and time range for trend analysis.\n\n2. **Connect your [YouTube Data API](https://developers.google.com/youtube/v3)**\n   Add your YouTube OAuth2 credentials in the **Get many videos** node and replace `Your Project API Key` in the **Get Data** HTTP Request node with your actual YouTube API key.\n\n3. **Link your [Google Sheets](https://docs.google.com/spreadsheets/) account**\n   Connect your Google Sheets OAuth2 credentials in both the **Create spreadsheet** and **Append row in sheet** nodes to automatically generate trend reports.\n\n4. **Configure the Engagement Rate Filter**\n   Adjust the engagement rate threshold (currently set to 2%) in the **Engagement Rate Check** node based on your quality standards.\n\n5. **Customize Video Filters**\n   Modify the conditions in the **If** node to filter videos by minimum views (currently 1000+), time range, and exclude hashtag-heavy titles.\n\n6. **Set Regional Preferences**\n   Update the `regionCode` parameter in the **Get many videos** node (currently \"US\") to target specific geographic regions.\n\nOnce all connections are set, your workflow will **analyze YouTube trends, filter high-engagement videos, and generate automated spreadsheet reports** \ud83d\ude80\n---"
      },
      "typeVersion": 1
    },
    {
      "id": "55ce5757-e8af-409a-ac80-4f5e467b78de",
      "name": "Create Analytics Spreadsheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1680,
        1152
      ],
      "parameters": {
        "title": "YouTube Analytics 2026",
        "options": {},
        "resource": "spreadsheet"
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "a3f94dd3-39b1-4f00-9eb7-bd544d6c9bdf",
      "name": "Finalize Spreadsheet",
      "type": "n8n-nodes-base.code",
      "position": [
        3472,
        1152
      ],
      "parameters": {
        "jsCode": "// runOnceForAllItems\n// Consolidates back to single item with spreadsheet URL\nconst spreadsheetId = $('Create Analytics Spreadsheet').first().json.spreadsheetId;\nconst spreadsheetUrl = 'https://docs.google.com/spreadsheets/d/' + spreadsheetId;\nreturn [{ json: { spreadsheetUrl, spreadsheetId } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "ade95937-ccf1-4b8e-888c-c954b0064171",
      "name": "Setup Tabs",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1904,
        1152
      ],
      "parameters": {
        "url": "=https://sheets.googleapis.com/v4/spreadsheets/{{ $json.spreadsheetId }}:batchUpdate",
        "method": "POST",
        "options": {},
        "jsonBody": "{\"requests\":[{\"updateSheetProperties\":{\"properties\":{\"sheetId\":0,\"title\":\"Channel stats\"},\"fields\":\"title\"}},{\"addSheet\":{\"properties\":{\"sheetId\":1001,\"title\":\"Top Videos\"}}},{\"addSheet\":{\"properties\":{\"sheetId\":1002,\"title\":\"Weekly Summary\"}}},{\"updateCells\":{\"rows\":[{\"values\":[{\"userEnteredValue\":{\"stringValue\":\"Date\"}},{\"userEnteredValue\":{\"stringValue\":\"Channel ID\"}},{\"userEnteredValue\":{\"stringValue\":\"Title\"}},{\"userEnteredValue\":{\"stringValue\":\"Subscribers\"}},{\"userEnteredValue\":{\"stringValue\":\"Total Views\"}},{\"userEnteredValue\":{\"stringValue\":\"Avg Views\"}},{\"userEnteredValue\":{\"stringValue\":\"Engagement %\"}},{\"userEnteredValue\":{\"stringValue\":\"Top Keyword\"}},{\"userEnteredValue\":{\"stringValue\":\"Top Keyword 2\"}}]}],\"fields\":\"userEnteredValue\",\"start\":{\"sheetId\":0,\"rowIndex\":0,\"columnIndex\":0}}},{\"updateCells\":{\"rows\":[{\"values\":[{\"userEnteredValue\":{\"stringValue\":\"Date\"}},{\"userEnteredValue\":{\"stringValue\":\"Channel ID\"}},{\"userEnteredValue\":{\"stringValue\":\"Title\"}},{\"userEnteredValue\":{\"stringValue\":\"Subscribers\"}},{\"userEnteredValue\":{\"stringValue\":\"Total Views\"}},{\"userEnteredValue\":{\"stringValue\":\"Avg Views\"}},{\"userEnteredValue\":{\"stringValue\":\"Engagement %\"}},{\"userEnteredValue\":{\"stringValue\":\"Top Keyword\"}},{\"userEnteredValue\":{\"stringValue\":\"Top Keyword 2\"}},{\"userEnteredValue\":{\"stringValue\":\"Published Days\"}},{\"userEnteredValue\":{\"stringValue\":\"Uploads\"}},{\"userEnteredValue\":{\"stringValue\":\"Engagement Rate\"}},{\"userEnteredValue\":{\"stringValue\":\"Tags\"}}]}],\"fields\":\"userEnteredValue\",\"start\":{\"sheetId\":1001,\"rowIndex\":0,\"columnIndex\":0}}},{\"updateCells\":{\"rows\":[{\"values\":[{\"userEnteredValue\":{\"stringValue\":\"Date\"}},{\"userEnteredValue\":{\"stringValue\":\"Channel ID\"}},{\"userEnteredValue\":{\"stringValue\":\"Title\"}},{\"userEnteredValue\":{\"stringValue\":\"Subscribers\"}},{\"userEnteredValue\":{\"stringValue\":\"Total Views\"}},{\"userEnteredValue\":{\"stringValue\":\"Avg Views\"}},{\"userEnteredValue\":{\"stringValue\":\"Engagement %\"}},{\"userEnteredValue\":{\"stringValue\":\"Top Keyword\"}},{\"userEnteredValue\":{\"stringValue\":\"Top Keyword 2\"}},{\"userEnteredValue\":{\"stringValue\":\"Published Days\"}},{\"userEnteredValue\":{\"stringValue\":\"Uploads\"}},{\"userEnteredValue\":{\"stringValue\":\"Engagement Rate\"}},{\"userEnteredValue\":{\"stringValue\":\"Content Table\"}}]}],\"fields\":\"userEnteredValue\",\"start\":{\"sheetId\":1002,\"rowIndex\":0,\"columnIndex\":0}}}]}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleSheetsOAuth2Api"
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d8008525-452d-427a-ab28-10adcfa47402",
      "name": "Prep Channel Stats",
      "type": "n8n-nodes-base.code",
      "position": [
        2128,
        1152
      ],
      "parameters": {
        "jsCode": "const data = $('Rank Videos').first().json;\nconst spreadsheetId = $('Create Analytics Spreadsheet').first().json.spreadsheetId;\nconst topChannels = data.topChannels || [];\nconst top50 = data.top50Videos || [];\nconst reportDate = data.reportDate || new Date().toLocaleDateString();\n\nconst channelKeywords = {};\nconst channelEngagement = {};\nfor (const v of top50) {\n  const cid = v.channelId;\n  if (!channelKeywords[cid]) channelKeywords[cid] = {};\n  const kw = v.keyword || 'other';\n  channelKeywords[cid][kw] = (channelKeywords[cid][kw] || 0) + 1;\n  if (!channelEngagement[cid]) channelEngagement[cid] = { total: 0, count: 0 };\n  channelEngagement[cid].total += (v.engagementRate || 0);\n  channelEngagement[cid].count++;\n}\n\nreturn topChannels.map(c => {\n  const kwMap = channelKeywords[c.channelId] || {};\n  const sorted = Object.entries(kwMap).sort((a, b) => b[1] - a[1]);\n  const avgViews = c.videoCount > 0 ? Math.round(c.totalViews / c.videoCount) : 0;\n  const eng = channelEngagement[c.channelId];\n  const avgEng = eng && eng.count > 0 ? parseFloat((eng.total / eng.count).toFixed(2)) : 0;\n  return {\n    json: {\n      spreadsheetId,\n      \"Date\": reportDate,\n      \"Channel ID\": c.channelId,\n      \"Title\": c.channelTitle,\n      \"Subscribers\": \"\",\n      \"Total Views\": c.totalViews,\n      \"Avg Views\": avgViews,\n      \"Engagement %\": avgEng,\n      \"Top Keyword\": sorted[0] ? sorted[0][0] : \"\",\n      \"Top Keyword 2\": sorted[1] ? sorted[1][0] : \"\"\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "40a7ad17-48e2-48d1-a6ef-d3799fd8cc9d",
      "name": "Append Channel Stats",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2352,
        1152
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Channel ID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Channel ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Subscribers",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Subscribers",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total Views",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Total Views",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Avg Views",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Avg Views",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Engagement %",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Engagement %",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Top Keyword",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Top Keyword",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Top Keyword 2",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Top Keyword 2",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {
          "cellFormat": "USER_ENTERED"
        },
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Channel stats"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.spreadsheetId }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "75930448-0cbd-42c4-9fe5-0d7510519ebe",
      "name": "Prep Top Videos",
      "type": "n8n-nodes-base.code",
      "position": [
        2576,
        1152
      ],
      "parameters": {
        "jsCode": "const data = $('Rank Videos').first().json;\nconst spreadsheetId = $('Create Analytics Spreadsheet').first().json.spreadsheetId;\nconst top50 = data.top50Videos || [];\nconst topChannels = data.topChannels || [];\nconst reportDate = data.reportDate || new Date().toLocaleDateString();\n\nconst channelVideoCount = {};\nfor (const c of topChannels) channelVideoCount[c.channelId] = c.videoCount || 0;\n\nconst now = new Date();\nreturn top50.map(v => {\n  const publishedDays = v.publishedAt\n    ? Math.floor((now - new Date(v.publishedAt)) / (1000 * 60 * 60 * 24))\n    : \"\";\n  const tags = Array.isArray(v.tags) ? v.tags : [];\n  const kw2 = tags.find(t => t.toLowerCase() !== (v.keyword || '').toLowerCase()) || (tags[1] || \"\");\n  return {\n    json: {\n      spreadsheetId,\n      \"Date\": reportDate,\n      \"Channel ID\": v.channelId,\n      \"Title\": v.title,\n      \"Subscribers\": \"\",\n      \"Total Views\": v.views,\n      \"Avg Views\": v.views,\n      \"Engagement %\": v.engagementRate,\n      \"Top Keyword\": v.keyword || \"\",\n      \"Top Keyword 2\": kw2,\n      \"Published Days\": publishedDays,\n      \"Uploads\": channelVideoCount[v.channelId] || \"\",\n      \"Engagement Rate\": v.engagementRate,\n      \"Tags\": tags.join(\", \")\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "7e2d7973-94d9-4208-aa4d-78d9e177c39b",
      "name": "Append Top Videos",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2800,
        1152
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Channel ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Channel ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Subscribers",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Subscribers",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total Views",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total Views",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Avg Views",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Avg Views",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Engagement %",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Engagement %",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Top Keyword",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Top Keyword",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Top Keyword 2",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Top Keyword 2",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Published Days",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Published Days",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Uploads",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Uploads",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Engagement Rate",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Engagement Rate",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tags",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Tags",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1001,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1VZQNM_VW2A11R9FTyHf9S0zqewcTRuW9dZmoMqa4zEg/edit#gid=1001",
          "cachedResultName": "Top Videos"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.spreadsheetId }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "34260714-96b0-49be-81f0-26c6290d3d1c",
      "name": "Prep Weekly Summary",
      "type": "n8n-nodes-base.code",
      "position": [
        3024,
        1152
      ],
      "parameters": {
        "jsCode": "const data = $('Rank Videos').first().json;\nconst spreadsheetId = $('Create Analytics Spreadsheet').first().json.spreadsheetId;\nconst top50 = data.top50Videos || [];\nconst reportDate = data.reportDate || new Date().toLocaleDateString();\nconst now = new Date();\n\nconst kwStats = {};\nfor (const v of top50) {\n  const kw = v.keyword || 'other';\n  if (!kwStats[kw]) kwStats[kw] = { views: 0, engagement: 0, count: 0, publishedDays: 0, titles: [] };\n  kwStats[kw].views += (v.views || 0);\n  kwStats[kw].engagement += (v.engagementRate || 0);\n  kwStats[kw].count++;\n  if (v.publishedAt) kwStats[kw].publishedDays += Math.floor((now - new Date(v.publishedAt)) / (1000 * 60 * 60 * 24));\n  kwStats[kw].titles.push(v.title);\n}\n\nconst sortedKw = Object.entries(kwStats).sort((a, b) => b[1].views - a[1].views);\nconst topKw1 = sortedKw[0] ? sortedKw[0][0] : \"\";\nconst topKw2 = sortedKw[1] ? sortedKw[1][0] : \"\";\n\nreturn sortedKw.map(([kw, stats]) => {\n  const avgViews = stats.count > 0 ? Math.round(stats.views / stats.count) : 0;\n  const avgEng = stats.count > 0 ? parseFloat((stats.engagement / stats.count).toFixed(2)) : 0;\n  const avgDays = stats.count > 0 ? Math.round(stats.publishedDays / stats.count) : 0;\n  return {\n    json: {\n      spreadsheetId,\n      \"Date\": reportDate,\n      \"Channel ID\": \"\",\n      \"Title\": kw,\n      \"Subscribers\": \"\",\n      \"Total Views\": stats.views,\n      \"Avg Views\": avgViews,\n      \"Engagement %\": avgEng,\n      \"Top Keyword\": topKw1,\n      \"Top Keyword 2\": topKw2,\n      \"Published Days\": avgDays,\n      \"Uploads\": stats.count,\n      \"Engagement Rate\": avgEng,\n      \"Content Table\": stats.titles.slice(0, 3).join(\" | \")\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "f4a8a8ba-b6b3-406c-99d0-72146f3ce831",
      "name": "Append Weekly Summary",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3248,
        1152
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Channel ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Channel ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Subscribers",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Subscribers",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total Views",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total Views",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Avg Views",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Avg Views",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Engagement %",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Engagement %",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Top Keyword",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Top Keyword",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Top Keyword 2",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Top Keyword 2",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Published Days",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Published Days",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Uploads",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Uploads",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Engagement Rate",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Engagement Rate",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Content Table",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Content Table",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1002,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1VZQNM_VW2A11R9FTyHf9S0zqewcTRuW9dZmoMqa4zEg/edit#gid=1002",
          "cachedResultName": "Weekly Summary"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.spreadsheetId }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "5a6bc2b0-8371-4d83-ae78-72eec3300058",
      "name": "Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "width": 912,
        "height": 620,
        "content": "# AI YouTube Trend Intelligence Report\n\n### **What it does:**\nAutomatically discovers, ranks, and analyzes the top-performing AI & automation YouTube videos each week, delivering a branded PDF report and Google Sheets dashboard to your inbox.\n\n### **Why it matters:**\nSaves 4+ hours of manual research per week by surfacing trending topics, high-engagement content patterns, and actionable content recommendations for AI/automation creators.\n\n### **How it works:**\n- Searches YouTube Data API across 10 AI/automation keywords for the past 7 days\n- Fetches detailed statistics and deduplicates ~500 videos\n- Ranks by views, calculates engagement rates, and filters for relevance\n- Exports top channels, videos, and keyword stats to a new Google Sheet\n- Sends the ranked data to an AI model for trend analysis and content recommendations\n- Generates a branded HTML report with charts, converts to PDF, and emails it\n\n### **Setup steps:**\n1. Add your **YouTube Data API v3** key as an HTTP Query Auth credential\n2. Connect **Google Sheets OAuth2** for the spreadsheet export\n3. Connect **OpenAI API** credential for the AI analysis node\n4. Connect **PDF.co** credential for HTML-to-PDF conversion\n5. Connect **Gmail OAuth2** and update the recipient email in \"Send Report Email\"\n6. Test with a manual execution before enabling the weekly schedule"
      },
      "typeVersion": 1
    },
    {
      "id": "dc8e53dc-324f-4d48-b472-c27801cd44e1",
      "name": "Contact & Attribution",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4048,
        0
      ],
      "parameters": {
        "width": 700,
        "height": 1268,
        "content": "## Was this helpful? Get in touch!\n\n[![clic](https://vptkuqoipqbebipqjnqw.supabase.co/storage/v1/object/public/Milo%20Bravo/seeAxWUupcOOXY5tntexZ_video.gif)](https://tally.so/r/EkKGgB)\n\nI really hope this automation helped you. Your feedback is incredibly valuable and helps me create better resources for business and the n8n community.\n\n### **Have Feedback, a Question, or a Project Idea?**\n\nI've streamlined the way we connect. It all starts with one simple form that takes less than 10 seconds. After that, you'll chat with my AI assistant who will gather the key details and pass them directly on to me.\n\n####  **[Start the conversation here](https://tally.so/r/EkKGgB)**\n\n*   **Give Feedback:** Share your thoughts on this template\u2014whether you found a typo, encountered an unexpected error, have a suggestion, or just want to say thanks!\n\n*   **n8n Consulting:** Have a complex business challenge or need a custom workflow built from scratch? Let's partner on a powerful automation solution tailored to your specific needs.\n\n*   **Join your team:** We can work together to get you launched with confidence.\n\n---\n\nHappy Automating!\n[Milo Bravo](https://linkedin.com/in/MiloBravo/) | BRaiA Labs | Automation & BI Systems + AI Integration\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ecb358b0-a948-4563-9fa0-0616ce63bc8c",
      "name": "Section 1 - Trigger & Keywords",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        944,
        672
      ],
      "parameters": {
        "color": 3,
        "width": 492,
        "height": 304,
        "content": "## 1. Trigger & Keywords\n\nWeekly cron fires every Monday at 7 AM. The Code node defines 10 AI/automation search keywords and calculates the 7-day lookback date."
      },
      "typeVersion": 1
    },
    {
      "id": "ee932d5f-b05c-46d8-8542-31f99f5554c4",
      "name": "Section 2 - YouTube Data Fetch",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1456,
        672
      ],
      "parameters": {
        "color": 5,
        "width": 816,
        "height": 304,
        "content": "## 2. YouTube Data Fetch\n\nSearches the YouTube Data API v3 for each keyword (50 results each), deduplicates videos, batches IDs in groups of 50, and fetches full statistics including views, likes, comments, and duration."
      },
      "typeVersion": 1
    },
    {
      "id": "921b7267-5d6c-4bbf-8bf3-aafe69eb2d22",
      "name": "Section 3 - Rank & AI Analysis",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2288,
        672
      ],
      "parameters": {
        "color": 2,
        "width": 780,
        "height": 304,
        "content": "## 3. Rank & AI Analysis\n\nRanks all videos by views, calculates engagement rates, extracts top channels and keyword distribution. Sends the top 20 videos to an AI model for trend analysis, topic detection, and content recommendations."
      },
      "typeVersion": 1
    },
    {
      "id": "415f05d9-f708-43fb-92c9-2c61c81db5c7",
      "name": "Section 4 - PDF Report & Email",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3104,
        672
      ],
      "parameters": {
        "color": 4,
        "width": 872,
        "height": 304,
        "content": "## 4. PDF Report & Email\n\nGenerates a branded HTML report with charts (QuickChart.io), converts to PDF via PDF.co, downloads the file, and emails it as an attachment with a Google Sheets link."
      },
      "typeVersion": 1
    },
    {
      "id": "c40b6120-1e80-4aa1-8d07-75ce6b4a3767",
      "name": "Section 5 - Google Sheets Export",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1552,
        1056
      ],
      "parameters": {
        "color": 6,
        "width": 2100,
        "height": 272,
        "content": "## 5. Google Sheets Export\n\nCreates a new \"YouTube Analytics 2026\" spreadsheet with three tabs (Channel Stats, Top Videos, Weekly Summary), populates each with ranked data, then passes the spreadsheet URL back to the main pipeline."
      },
      "typeVersion": 1
    },
    {
      "id": "d253f0d1-8222-4669-aeba-a31d5c4557ae",
      "name": "PDFco Api",
      "type": "n8n-nodes-pdfco.PDFco Api",
      "position": [
        3344,
        800
      ],
      "parameters": {
        "html": "={{ $json.html }}",
        "operation": "URL/HTML to PDF",
        "convertType": "htmlToPDF",
        "advancedOptions": {
          "margins": "0",
          "paperSize": "Letter"
        }
      },
      "credentials": {
        "pdfcoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3193346a-e211-445e-89ee-bf49930353c6",
      "name": "Build HTML Report1",
      "type": "n8n-nodes-base.code",
      "position": [
        3168,
        800
      ],
      "parameters": {
        "jsCode": "const videoData = $('Rank Videos').first().json;\nconst top10 = videoData.top10Videos || [];\nconst topChannels = videoData.topChannels || [];\nconst keywordCounts = videoData.keywordCounts || {};\nconst reportDate = videoData.reportDate || new Date().toLocaleDateString();\nconst totalVideosAnalyzed = videoData.totalVideosAnalyzed || 0;\nconst top50 = videoData.top50Videos || [];\n\n// Logo embedded as base64 data URI\nconst logoDataUri = 'data:image/png;base64,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

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

Who is this for? AI creators, marketers, agencies, and researchers tracking YouTube trends who need weekly high-signal insights without 4+ hours manual research.

Source: https://n8n.io/workflows/13659/ — 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

Stop wasting billable hours on manual time-tracking. AutoTimesheet Pro uses AI to collect emails, meetings, and GitHub work, then writes a clean timesheet straight into Google Sheets. Perfect for deve

Google Calendar, Gmail, GitHub +3
AI & RAG

Imagine a dedicated financial expert tirelessly working behind the scenes, sifting through every transaction, every investment move, and every accounting entry. That's exactly what this automated syst

HTTP Request, Google Sheets, OpenAI +3
AI & RAG

Automatically logs time to Jira every night from a Google Sheet. No manual worklog entries needed — just fill in your sheet and the workflow handles the rest at 10 PM.

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

This template automates overnight system health monitoring for DevOps and IT operations teams. It checks your internal services and APIs on a schedule, logs all results to Google Sheets, and sends AI-

HTTP Request, OpenAI, Gmail +1
AI & RAG

This workflow automates the daily generation of viral short-form video content ideas tailored for founders and business leaders. It scrapes fresh AI-related news and trends from various topics, synthe

OpenAI, HTTP Request, Google Sheets +1