AutomationFlowsAI & RAG › Transcribe YouTube Videos & Create GEO Summaries in Notion

Transcribe YouTube Videos & Create GEO Summaries in Notion

Original n8n title: Transcribe Youtube Videos & Create Geo Summaries with Whisper and Gpt-4o-mini in Notion

ByRahul Joshi @rahul08 on n8n.io

Automate your YouTube research workflow by extracting audio from any video, transcribing it with Whisper AI, and generating structured GEO (Goal–Execution–Outcome) summaries using GPT-4o-mini. 🎥🤖 This template transforms unstructured video content into actionable, searchable…

Cron / scheduled trigger★★★★☆ complexityAI-powered20 nodesHTTP RequestNotionYouTubeOpenAIOpenAI ChatMemory Buffer WindowOutput Parser StructuredAgent
AI & RAG Trigger: Cron / scheduled Nodes: 20 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → 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": "dxZQhOkZXNNFtuHM",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Transform YouTube transcripts to AI-generated GEO summaries in Notion",
  "tags": [],
  "nodes": [
    {
      "id": "c0e9b7f9-0ab3-4275-9fbe-266e602052f8",
      "name": "Sticky Note - Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1936,
        -720
      ],
      "parameters": {
        "width": 420,
        "height": 528,
        "content": "## \ud83c\udfa5 YouTube \u2192 GEO Summary Automation\n\n### How it works\nThis workflow extracts audio from YouTube videos, transcribes the content using OpenAI Whisper, and generates structured GEO summaries (Goal-Execution-Outcome) through AI analysis. The final summary is saved to a Notion database with organized metadata, making video content searchable and actionable.\n\n### Setup steps\n1. Connect **YouTube OAuth2**, **OpenAI API**, and **Notion** credentials\n2. Replace the RapidAPI key placeholder in \"HTTP - Get YouTube Audio\" node\n3. Update the Notion database ID in the final node to match your workspace\n4. Configure the Schedule Trigger interval (default: hourly)\n5. Replace the hardcoded video ID with a dynamic input or playlist source\n6. Test with a single video before enabling the schedule"
      },
      "typeVersion": 1
    },
    {
      "id": "8002b504-7541-4197-a29b-4f060e30f7f9",
      "name": "Sticky Note - Fetch",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1936,
        -176
      ],
      "parameters": {
        "color": 2,
        "width": 712,
        "height": 380,
        "content": "## \ud83d\udce5 Video Fetch & Metadata\nRetrieves video details from YouTube API and prepares metadata like title, description, thumbnail, and publish date for downstream processing."
      },
      "typeVersion": 1
    },
    {
      "id": "bac21e13-bdb7-4334-961b-50f065cfae3e",
      "name": "Sticky Note - Audio",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1200,
        -176
      ],
      "parameters": {
        "color": 2,
        "width": 880,
        "height": 560,
        "content": "## \ud83c\udfa7 Audio Download & Transcription\nDownloads audio from YouTube using RapidAPI, converts it to text via OpenAI Whisper, and filters out empty transcripts before merging with metadata."
      },
      "typeVersion": 1
    },
    {
      "id": "8e850fb3-c485-4efa-9333-4eb5f600e237",
      "name": "Sticky Note - AI",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -288,
        -192
      ],
      "parameters": {
        "color": 2,
        "width": 676,
        "height": 608,
        "content": "## \ud83e\udd16 AI Analysis & GEO Extraction\nUses GPT-4o-mini with structured output parsing to analyze the transcript and generate Goal, Execution, Outcome, and Keywords in JSON format."
      },
      "typeVersion": 1
    },
    {
      "id": "b11022ae-7f4b-4319-b60b-662a18f455bc",
      "name": "Sticky Note - Storage",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        416,
        -192
      ],
      "parameters": {
        "color": 2,
        "width": 472,
        "height": 428,
        "content": "## \ud83d\udcbe Data Storage\nParses the AI-generated JSON and creates a new page in Notion with formatted GEO content and video metadata."
      },
      "typeVersion": 1
    },
    {
      "id": "d571f5f8-5546-4036-ba2e-19bda81d5e75",
      "name": "Sticky Note - Security",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        256
      ],
      "parameters": {
        "color": 3,
        "width": 320,
        "height": 180,
        "content": "## \ud83d\udd10 Credentials & Security\n**Required credentials:**\n- YouTube OAuth2\n- OpenAI API key\n- Notion API integration\n- RapidAPI key (replace placeholder)\n\n\u26a0\ufe0f Remove all personal tokens before sharing this template."
      },
      "typeVersion": 1
    },
    {
      "id": "126d7e25-da79-47d6-a9f0-9511f462c22b",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1808,
        32
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "5a992308-5d1d-4ee6-a0c8-44c2b9fea494",
      "name": "Set - Prepare Video Metadata",
      "type": "n8n-nodes-base.set",
      "position": [
        -1360,
        32
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "field1",
              "name": "videoId",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "field2",
              "name": "title",
              "type": "string",
              "value": "={{$json.snippet.title}}"
            },
            {
              "id": "field3",
              "name": "description",
              "type": "string",
              "value": "={{$json.snippet.description}}"
            },
            {
              "id": "field4",
              "name": "publishedAt",
              "type": "string",
              "value": "={{$json.snippet.publishedAt}}"
            },
            {
              "id": "field5",
              "name": "thumbnailUrl",
              "type": "string",
              "value": "={{$json.snippet.thumbnails.default.url}}"
            },
            {
              "id": "field6",
              "name": "videoUrl",
              "type": "string",
              "value": "=https://www.youtube.com/watch?v={{$json.id.videoId}}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "56c1c33b-2b75-4367-98a3-6ed6c751a4f1",
      "name": "HTTP - Download Audio File",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -912,
        96
      ],
      "parameters": {
        "url": "={{ $json.file }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "8a4192d9-e1e2-4171-ab9c-4eb241e1f716",
      "name": "IF - Skip if No Transcript",
      "type": "n8n-nodes-base.if",
      "position": [
        -464,
        96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition1",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{$json.text}}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "dde57237-e117-4e8c-a427-acddade93e03",
      "name": "Merge - Attach Metadata + Transcript",
      "type": "n8n-nodes-base.merge",
      "position": [
        -240,
        32
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3
    },
    {
      "id": "30b4d2a5-0eb8-4223-acb6-e0dd2954ff44",
      "name": "Function - Parse GEO JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        464,
        32
      ],
      "parameters": {
        "jsCode": "// Get the input data\nconst inputData = $input.all();\n\n// Process each item\nreturn inputData.map(item => {\n  const output = item.json.output;\n  \n  return {\n    json: {\n    \n      \n      // Goals as rich text or multi-line text\n      Goals: output.goal.join('\\n\u2022 '),\n      \n      // Execution steps as rich text or multi-line text\n      Execution: output.execution.join('\\n\u2022 '),\n      \n      // Outcomes as rich text or multi-line text\n      Outcomes: output.outcome.join('\\n\u2022 '),\n      \n      // Keywords as multi-select or text\n      Keywords: output.keywords,\n      \n      // Alternative: If you want all goals in one formatted string\n      GoalsFormatted: '\u2022 ' + output.goal.join('\\n\u2022 '),\n      ExecutionFormatted: '\u2022 ' + output.execution.join('\\n\u2022 '),\n      OutcomesFormatted: '\u2022 ' + output.outcome.join('\\n\u2022 '),\n      \n      // Keywords as comma-separated string (if Notion expects text)\n      KeywordsText: output.keywords.join(', ')\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "9a92e535-79e3-44fd-b307-0426d7fb13ea",
      "name": "Notion - Create GEO Summary Page",
      "type": "n8n-nodes-base.notion",
      "position": [
        688,
        32
      ],
      "parameters": {
        "title": "={{ $('Merge - Attach Metadata + Transcript').item.json.title }}",
        "options": {},
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "[Your Database ID]",
          "cachedResultUrl": "https://www.notion.so/example",
          "cachedResultName": "YouTube GEO"
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Goal|rich_text",
              "textContent": "={{ $json.GoalsFormatted }}"
            },
            {
              "key": "Execution|rich_text",
              "textContent": "={{ $json.ExecutionFormatted }}"
            },
            {
              "key": "Outcomes|rich_text",
              "textContent": "={{ $json.OutcomesFormatted }}"
            },
            {
              "key": "Keywords|rich_text",
              "textContent": "={{ $json.KeywordsText }}"
            }
          ]
        }
      },
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "b01bfd5d-aab7-4b32-9708-8656bd11ca22",
      "name": "HTTP - Get YouTube Audio",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1136,
        96
      ],
      "parameters": {
        "url": "=https://youtube-video-fast-downloader-24-7.p.rapidapi.com/download_audio/{{ $json.videoId }}?quality=140\n",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "videoId",
              "value": "={{ $json.videoId }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "x-rapidapi-host",
              "value": "youtube-video-fast-downloader-24-7.p.rapidapi.com"
            },
            {
              "name": "x-rapidapi-key",
              "value": "[Your RapidAPI Key]"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "49b97a02-564b-42ff-94fc-9c1614956689",
      "name": "YouTube - Fetch Video Details",
      "type": "n8n-nodes-base.youTube",
      "position": [
        -1584,
        32
      ],
      "parameters": {
        "options": {},
        "resource": "video",
        "operation": "get"
      },
      "credentials": {
        "youTubeOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "71f6a34a-3c35-48f9-aaf7-0760e75893dc",
      "name": "OpenAI - Transcribe Audio (Whisper)",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        -688,
        96
      ],
      "parameters": {
        "options": {},
        "resource": "audio",
        "operation": "transcribe"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "2915c932-68ee-4f84-a23c-6dda7c213449",
      "name": "OpenAI Chat Model - GPT-4o-mini",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -16,
        256
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "827a05fc-f985-4e58-baf6-6e1d438736ae",
      "name": "Memory - Conversation Buffer",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        128,
        256
      ],
      "parameters": {
        "sessionKey": "GEO-session",
        "sessionIdType": "customKey"
      },
      "typeVersion": 1.3
    },
    {
      "id": "2bd27d1a-f1d3-4ac7-8525-ebf4857380c6",
      "name": "Output Parser - Structured JSON",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        256,
        256
      ],
      "parameters": {
        "jsonSchemaExample": "{ \n  \"goal\": [\n    \"Automate the creation of client proposals\",\n    \"Eliminate manual formatting and writing\",\n    \"Personalize proposals using existing CRM data\"\n  ],\n  \"execution\": [\n    \"Workflow triggers on demand or scheduled\",\n    \"Fetches lead data from Google Sheets\",\n    \"Filters only proposal-ready leads\",\n    \"GPT-4o generates custom proposal text\",\n    \"Proposal formatted into HTML email\",\n    \"Saved directly as Gmail draft\"\n  ],\n  \"outcome\": [\n    \"Significant time saved per proposal\",\n    \"Consistent, professional output\",\n    \"Higher proposal quality and personalization\",\n    \"Faster pipeline from lead to send\"\n  ],\n  \"keywords\": [\n    \"n8n workflow\",\n    \"business proposals\",\n    \"GPT-4 automation\",\n    \"sales automation\",\n    \"Google Sheets integration\",\n    \"Gmail automation\"\n  ]\n}\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "7f8a6b79-7c25-417a-8861-d8c6f6112003",
      "name": "AI Agent - GEO Analyzer",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        48,
        32
      ],
      "parameters": {
        "text": "=Video Metadata:\nID: {{ $json.videoId }}\nTitle: {{ $json.title }}\nDescription: {{ $json.description }}\nPublished At: {{ $json.publishedAt }}\nDuration (seconds): {{ $json.usage.seconds }}\n\nThumbnail: {{ $json.thumbnailUrl }}\nURL: {{ $json.videoUrl }}\n\nTranscript:\n{{ $json.text }}\n\nInstructions:\nFrom this video data, generate a structured GEO summary in JSON.\n\nUse this format:\n\n{\n  \"goal\": [],\n  \"execution\": [],\n  \"outcome\": [],\n  \"keywords\": []\n}\n\nRules for each:\n- \"goal\": What is the video trying to solve, teach, or achieve?\n- \"execution\": The step-by-step process, workflow, method, or strategy shown\n- \"outcome\": The transformation, final result, or benefit for the viewer\n- \"keywords\": Output 5\u201310 SEO keywords relevant to the content\n\nEach field must contain 2\u20135 bullet points.\nDo not repeat video title or description.\nBe accurate, concise, and factual.\n",
        "options": {
          "systemMessage": "=You are an expert YouTube content analyst AI. Your job is to analyze video content and produce structured GEO summaries that are clear, useful, and easy to rank.\n\nFollow these rules:\n- Never hallucinate\n- Never invent details not present in the text\n- Use only facts from the provided transcription and metadata\n- Be concise, insightful, and analytical\n- Do NOT repeat metadata\n- Do NOT include filler text or intros\n- Always output in exact JSON using the required keys\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "734242db-4f6a-4c34-a2ca-3cf344f2b998",
  "connections": {
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "YouTube - Fetch Video Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent - GEO Analyzer": {
      "main": [
        [
          {
            "node": "Function - Parse GEO JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP - Get YouTube Audio": {
      "main": [
        [
          {
            "node": "HTTP - Download Audio File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function - Parse GEO JSON": {
      "main": [
        [
          {
            "node": "Notion - Create GEO Summary Page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP - Download Audio File": {
      "main": [
        [
          {
            "node": "OpenAI - Transcribe Audio (Whisper)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF - Skip if No Transcript": {
      "main": [
        [
          {
            "node": "Merge - Attach Metadata + Transcript",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Memory - Conversation Buffer": {
      "ai_memory": [
        [
          {
            "node": "AI Agent - GEO Analyzer",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Set - Prepare Video Metadata": {
      "main": [
        [
          {
            "node": "Merge - Attach Metadata + Transcript",
            "type": "main",
            "index": 0
          },
          {
            "node": "HTTP - Get YouTube Audio",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "YouTube - Fetch Video Details": {
      "main": [
        [
          {
            "node": "Set - Prepare Video Metadata",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model - GPT-4o-mini": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent - GEO Analyzer",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Output Parser - Structured JSON": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent - GEO Analyzer",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI - Transcribe Audio (Whisper)": {
      "main": [
        [
          {
            "node": "IF - Skip if No Transcript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge - Attach Metadata + Transcript": {
      "main": [
        [
          {
            "node": "AI Agent - GEO Analyzer",
            "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

Automate your YouTube research workflow by extracting audio from any video, transcribing it with Whisper AI, and generating structured GEO (Goal–Execution–Outcome) summaries using GPT-4o-mini. 🎥🤖 This template transforms unstructured video content into actionable, searchable…

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

Title: Create daily AI news digest and send to Telegram

HTTP Request, Agent, OpenAI Chat +5
AI & RAG

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

Mailgun, OpenAI, OpenAI Chat +8
AI & RAG

⚠️ DISCLAIMER: This workflow uses the AnySite LinkedIn community node, which is only available on self-hosted n8n instances. It will not work on n8n.cloud.

OpenAI Chat, Output Parser Structured, Google Sheets +6
AI & RAG

Complete PostgreSQL-backed system: Keyword scoring → AI research → Multi-part content generation → fal.ai Nano Banana image generation → WordPress publishing

WordPress, OpenAI, Perplexity +8
AI & RAG

We’ve released Version 4 of our AI Powered Blog Automation workflow. We heard your complains and made a complete redesign built for serious content creators.

RSS Feed Read, OpenAI Chat, Text Classifier +6