AutomationFlowsAI & RAG › Extract Video Metadata & Auto-upload to Youtube with Gpt-4o SEO Optimization

Extract Video Metadata & Auto-upload to Youtube with Gpt-4o SEO Optimization

Bymasahiro hanawa @masahiro on n8n.io

Automatically process video files, extract metadata, generate AI-optimized titles/descriptions/tags, and upload directly to YouTube with proper categorization and thumbnail handling. YouTube Node Integration: Direct video upload to YouTube with full metadata Binary Data…

Webhook trigger★★★★☆ complexityAI-powered27 nodesAgentOpenAI ChatYouTubeGoogle SheetsGmail
AI & RAG Trigger: Webhook Nodes: 27 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → Gmail 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
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "1e3e0c7f-0833-45a3-ae5d-b9a890c88236",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1136,
        -432
      ],
      "parameters": {
        "width": 380,
        "height": 592,
        "content": "## Video Metadata Extraction & YouTube Auto-Upload with AI\n\n### Overview\nAutomatically process video files, extract metadata, generate AI-optimized titles/descriptions/tags, and upload directly to YouTube with proper categorization.\n\n### Key Features\n- **YouTube Node Integration**: Direct video upload with full metadata\n- **AI-Powered SEO**: Engaging titles, descriptions, and tags\n- **Binary Data Handling**: Video and thumbnail processing\n- **Category Auto-Selection**: AI determines optimal category\n\n### Required Credentials\n- YouTube OAuth2\n- OpenAI API\n- Gmail\n- Google Sheets"
      },
      "typeVersion": 1
    },
    {
      "id": "d6c9469a-4b69-4c83-a3f5-64ffd4adf19a",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -672,
        -256
      ],
      "parameters": {
        "color": 7,
        "width": 300,
        "content": "### Step 1: Video Intake & Validation\n- Receives video via webhook with binary data\n- Validates file type and size\n- Extracts initial file metadata\n- Stores binary for processing"
      },
      "typeVersion": 1
    },
    {
      "id": "970fe35d-06cd-4e53-a71c-f9f73103fc34",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -176,
        -352
      ],
      "parameters": {
        "color": 7,
        "width": 360,
        "height": 140,
        "content": "### Step 2: Metadata Extraction & Analysis\n- Analyzes video binary for technical properties\n- Extracts duration, resolution, codec info\n- Prepares content summary for AI processing"
      },
      "typeVersion": 1
    },
    {
      "id": "5e737370-c0a6-4349-a920-f78df7a1a5ad",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        -368
      ],
      "parameters": {
        "color": 7,
        "width": 360,
        "content": "### Step 3: AI Content Generation\n- Generates SEO-optimized title\n- Creates engaging description with keywords\n- Suggests relevant tags for discoverability\n- Determines optimal YouTube category"
      },
      "typeVersion": 1
    },
    {
      "id": "34f2813d-1f4a-4ed1-8b53-7c8dccb6229e",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1552,
        -400
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "content": "### Step 4: YouTube Upload & Post-Processing\n- Uploads video to YouTube with metadata\n- Sets thumbnail if provided\n- Adds to playlist if specified\n- Logs upload and sends notifications"
      },
      "typeVersion": 1
    },
    {
      "id": "d229b645-5969-4068-8a11-90f87ab7d31a",
      "name": "Video Upload Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -672,
        -64
      ],
      "parameters": {
        "path": "video-upload",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "6959a03d-8e0f-456f-93a5-827cd50b49f9",
      "name": "Initialize Upload Session",
      "type": "n8n-nodes-base.set",
      "position": [
        -448,
        -64
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1",
              "name": "uploadId",
              "type": "string",
              "value": "={{ 'VID-' + $now.format('yyyyMMddHHmmss') }}"
            },
            {
              "id": "2",
              "name": "timestamp",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            },
            {
              "id": "3",
              "name": "projectName",
              "type": "string",
              "value": "={{ $json.body?.projectName || 'Untitled Video' }}"
            },
            {
              "id": "4",
              "name": "targetAudience",
              "type": "string",
              "value": "={{ $json.body?.targetAudience || 'general' }}"
            },
            {
              "id": "5",
              "name": "language",
              "type": "string",
              "value": "={{ $json.body?.language || 'en' }}"
            },
            {
              "id": "6",
              "name": "playlistId",
              "type": "string",
              "value": "={{ $json.body?.playlistId || '' }}"
            },
            {
              "id": "7",
              "name": "publishTime",
              "type": "string",
              "value": "={{ $json.body?.publishTime || '' }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "69c0d902-15ee-4d5f-9c47-d49b3a6339c9",
      "name": "Validate Binary Data",
      "type": "n8n-nodes-base.if",
      "position": [
        -224,
        -64
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "leftValue": "={{ $binary.data !== undefined }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "b8c0dc13-95ef-40d4-b24d-7e95c30db5e7",
      "name": "Extract Video Metadata",
      "type": "n8n-nodes-base.code",
      "position": [
        0,
        -160
      ],
      "parameters": {
        "jsCode": "const binary = $input.first().binary;\n\nif (!binary || !binary.data) {\n  throw new Error('No video binary data found');\n}\n\nconst videoData = binary.data;\nconst metadata = {\n  fileName: videoData.fileName || 'video.mp4',\n  mimeType: videoData.mimeType || 'video/mp4',\n  fileSize: videoData.fileSize || 0,\n  fileExtension: (videoData.fileName || '').split('.').pop() || 'mp4'\n};\n\n// Validate file type\nconst validTypes = ['video/mp4', 'video/quicktime', 'video/x-msvideo', 'video/webm', 'video/x-matroska'];\nconst validExtensions = ['mp4', 'mov', 'avi', 'webm', 'mkv'];\n\nif (!validTypes.includes(metadata.mimeType) && !validExtensions.includes(metadata.fileExtension.toLowerCase())) {\n  throw new Error(`Invalid video format: ${metadata.mimeType}`);\n}\n\n// File size check (128GB max for YouTube)\nconst maxSize = 128 * 1024 * 1024 * 1024;\nif (metadata.fileSize > maxSize) {\n  throw new Error(`File too large: ${metadata.fileSize} bytes (max: 128GB)`);\n}\n\nconst inputData = $('Initialize Upload Session').first().json;\n\nreturn [{\n  json: {\n    ...inputData,\n    videoMetadata: metadata,\n    validationStatus: 'passed'\n  },\n  binary: binary\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "f26036a2-06bd-44b0-97b6-96b26683f3c9",
      "name": "Error Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        0,
        32
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ error: 'No video file provided', uploadId: $('Initialize Upload Session').first().json.uploadId }) }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "cd7302f7-b9e3-4a16-b1e0-f223cff756cf",
      "name": "Prepare AI Context",
      "type": "n8n-nodes-base.code",
      "position": [
        224,
        -160
      ],
      "parameters": {
        "jsCode": "const inputData = $input.first().json;\nconst videoMeta = inputData.videoMetadata || {};\n\n// Prepare content context for AI\nconst contentContext = {\n  projectName: inputData.projectName,\n  fileName: videoMeta.fileName,\n  fileType: videoMeta.mimeType,\n  targetAudience: inputData.targetAudience,\n  language: inputData.language,\n  estimatedDuration: videoMeta.fileSize ? Math.round(videoMeta.fileSize / (1024 * 1024 * 5)) + ' minutes (estimated)' : 'unknown'\n};\n\nreturn [{\n  json: {\n    ...inputData,\n    contentContext: contentContext\n  },\n  binary: $input.first().binary\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "26a610ee-cf28-4e3f-879d-441bf54a3795",
      "name": "AI Metadata Generator",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        448,
        -160
      ],
      "parameters": {
        "text": "=Generate YouTube video metadata optimized for SEO and engagement.\n\nVideo Information:\n- Project Name: {{ $json.contentContext.projectName }}\n- File Name: {{ $json.contentContext.fileName }}\n- Target Audience: {{ $json.contentContext.targetAudience }}\n- Language: {{ $json.contentContext.language }}\n- Estimated Duration: {{ $json.contentContext.estimatedDuration }}\n\nGenerate:\n1. An engaging, SEO-optimized title (max 100 characters)\n2. A comprehensive description (300-500 words) with:\n   - Hook in first 2 lines\n   - Key points/chapters\n   - Call to action\n   - Relevant keywords naturally integrated\n3. 10-15 relevant tags for discoverability\n4. The most appropriate YouTube category from: Film & Animation, Autos & Vehicles, Music, Pets & Animals, Sports, Travel & Events, Gaming, People & Blogs, Comedy, Entertainment, News & Politics, Howto & Style, Education, Science & Technology, Nonprofits & Activism\n\nReturn JSON with keys: title, description, tags (array), category, categoryId",
        "options": {
          "systemMessage": "You are a YouTube SEO expert. Generate metadata that maximizes discoverability and engagement. Always output valid JSON."
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "d1e2fd19-6b8e-4bd0-80f3-1ebd7408b849",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        520,
        64
      ],
      "parameters": {
        "model": "gpt-4o",
        "options": {
          "temperature": 0.7
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "88276679-cb7c-412e-9b37-28990a78957a",
      "name": "Parse AI Metadata",
      "type": "n8n-nodes-base.code",
      "position": [
        800,
        -160
      ],
      "parameters": {
        "jsCode": "const inputData = $input.first().json;\nconst aiOutput = inputData.output || '{}';\n\nlet aiMetadata = {};\ntry {\n  const jsonMatch = aiOutput.match(/\\{[\\s\\S]*\\}/);\n  if (jsonMatch) {\n    aiMetadata = JSON.parse(jsonMatch[0]);\n  }\n} catch (e) {\n  aiMetadata = {\n    title: inputData.contentContext.projectName || 'Untitled Video',\n    description: 'Video uploaded via automation.',\n    tags: ['video', 'content'],\n    category: 'Science & Technology',\n    categoryId: '28'\n  };\n}\n\n// Map category names to YouTube category IDs\nconst categoryMap = {\n  'Film & Animation': '1',\n  'Autos & Vehicles': '2',\n  'Music': '10',\n  'Pets & Animals': '15',\n  'Sports': '17',\n  'Travel & Events': '19',\n  'Gaming': '20',\n  'People & Blogs': '22',\n  'Comedy': '23',\n  'Entertainment': '24',\n  'News & Politics': '25',\n  'Howto & Style': '26',\n  'Education': '27',\n  'Science & Technology': '28',\n  'Nonprofits & Activism': '29'\n};\n\nconst categoryId = categoryMap[aiMetadata.category] || aiMetadata.categoryId || '28';\n\n// Get original context data\nconst contextData = $('Prepare AI Context').first().json;\n\nreturn [{\n  json: {\n    ...contextData,\n    youtubeMetadata: {\n      title: aiMetadata.title?.substring(0, 100) || 'Untitled',\n      description: aiMetadata.description || '',\n      tags: Array.isArray(aiMetadata.tags) ? aiMetadata.tags.slice(0, 15) : [],\n      category: aiMetadata.category || 'Science & Technology',\n      categoryId: categoryId\n    }\n  },\n  binary: $('Prepare AI Context').first().binary\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "e35c9454-1d53-40b5-b974-534312a1fad4",
      "name": "Check Scheduled Publish",
      "type": "n8n-nodes-base.if",
      "position": [
        1024,
        -160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.publishTime }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "b695f39b-ad3d-4cac-8739-d3cd88352088",
      "name": "Set Scheduled Settings",
      "type": "n8n-nodes-base.set",
      "position": [
        1248,
        -256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1",
              "name": "privacyStatus",
              "type": "string",
              "value": "private"
            },
            {
              "id": "2",
              "name": "publishAt",
              "type": "string",
              "value": "={{ $json.publishTime }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "ed1e0f0f-7110-4895-a47a-5277c5022d20",
      "name": "Set Immediate Publish",
      "type": "n8n-nodes-base.set",
      "position": [
        1248,
        -64
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1",
              "name": "privacyStatus",
              "type": "string",
              "value": "public"
            },
            {
              "id": "2",
              "name": "publishAt",
              "type": "string",
              "value": ""
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "4ad35d0d-ea86-4eb0-bed4-65eb79325fbe",
      "name": "Merge Publish Settings",
      "type": "n8n-nodes-base.merge",
      "position": [
        1472,
        -160
      ],
      "parameters": {
        "mode": "chooseBranch"
      },
      "typeVersion": 3
    },
    {
      "id": "e3757a3a-abc9-46f0-8461-a0b2a430a8b8",
      "name": "YouTube Upload Video",
      "type": "n8n-nodes-base.youTube",
      "position": [
        1696,
        -160
      ],
      "parameters": {
        "title": "={{ $json.youtubeMetadata.title }}",
        "options": {
          "tags": "={{ $json.youtubeMetadata.tags.join(',') }}",
          "description": "={{ $json.youtubeMetadata.description }}",
          "privacyStatus": "={{ $json.privacyStatus }}",
          "defaultLanguage": "={{ $json.language }}",
          "notifySubscribers": true
        },
        "resource": "video",
        "operation": "upload",
        "categoryId": "={{ $json.youtubeMetadata.categoryId }}"
      },
      "typeVersion": 1
    },
    {
      "id": "6c544b87-14c0-40a3-bf2b-991c4f61908a",
      "name": "Process Upload Result",
      "type": "n8n-nodes-base.code",
      "position": [
        1920,
        -160
      ],
      "parameters": {
        "jsCode": "const uploadResult = $input.first().json;\nconst inputData = $('Merge Publish Settings').first().json;\n\nconst videoId = uploadResult.id || uploadResult.videoId || 'unknown';\nconst videoUrl = `https://youtu.be/${videoId}`;\n\nreturn [{\n  json: {\n    uploadId: inputData.uploadId,\n    videoId: videoId,\n    videoUrl: videoUrl,\n    title: inputData.youtubeMetadata.title,\n    description: inputData.youtubeMetadata.description,\n    tags: inputData.youtubeMetadata.tags,\n    category: inputData.youtubeMetadata.category,\n    categoryId: inputData.youtubeMetadata.categoryId,\n    privacyStatus: inputData.privacyStatus,\n    publishAt: inputData.publishAt || 'immediate',\n    playlistId: inputData.playlistId,\n    uploadStatus: 'completed',\n    uploadedAt: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "0b3392a7-c0d0-4013-b4b2-ece91b0ceb08",
      "name": "Check Playlist Add",
      "type": "n8n-nodes-base.if",
      "position": [
        2144,
        -160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.playlistId }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "769604dc-af5c-4de0-9d10-976cc5491770",
      "name": "Add to Playlist",
      "type": "n8n-nodes-base.youTube",
      "position": [
        2368,
        -232
      ],
      "parameters": {
        "options": {},
        "videoId": "={{ $json.videoId }}",
        "resource": "playlistItem",
        "playlistId": "={{ $json.playlistId }}"
      },
      "typeVersion": 1
    },
    {
      "id": "91137f30-a418-42f3-ae1f-e64f8e6e52c7",
      "name": "Merge Playlist Result",
      "type": "n8n-nodes-base.merge",
      "position": [
        2592,
        -160
      ],
      "parameters": {
        "mode": "chooseBranch"
      },
      "typeVersion": 3
    },
    {
      "id": "7471d2e4-631e-4357-97c0-9c2a7ecb3f2f",
      "name": "Log Upload to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2816,
        -256
      ],
      "parameters": {
        "columns": {
          "value": {
            "Title": "={{ $json.title }}",
            "Status": "={{ $json.uploadStatus }}",
            "Category": "={{ $json.category }}",
            "Video ID": "={{ $json.videoId }}",
            "Upload ID": "={{ $json.uploadId }}",
            "Video URL": "={{ $json.videoUrl }}",
            "Playlist ID": "={{ $json.playlistId }}",
            "Uploaded At": "={{ $json.uploadedAt }}",
            "Privacy Status": "={{ $json.privacyStatus }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "VideoUploads"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "84c6d2df-4408-49ab-b27c-59f53b6d2957",
      "name": "Send Upload Notification",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3040,
        -256
      ],
      "parameters": {
        "sendTo": "=content-team@company.com",
        "message": "=Video Upload Confirmation\n\nUpload ID: {{ $json.uploadId }}\n\nVideo Details:\n- Title: {{ $json.title }}\n- Video URL: {{ $json.videoUrl }}\n- Category: {{ $json.category }}\n- Privacy: {{ $json.privacyStatus }}\n- Publish: {{ $json.publishAt }}\n\nTags: {{ $json.tags.join(', ') }}\n\nDescription:\n{{ $json.description }}\n\n---\nUploaded at: {{ $json.uploadedAt }}",
        "options": {},
        "subject": "=Video Uploaded: {{ $json.title }}"
      },
      "typeVersion": 2.1
    },
    {
      "id": "60e1dd52-e5c6-4068-9f3a-8fe4664961cd",
      "name": "Success Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        3264,
        -256
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: true, uploadId: $json.uploadId, videoId: $json.videoId, videoUrl: $json.videoUrl, title: $json.title, category: $json.category, uploadStatus: $json.uploadStatus }) }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "70889b67-2572-46c7-ad85-43dbe6087a13",
      "name": "Generate Upload Summary",
      "type": "n8n-nodes-base.code",
      "position": [
        2816,
        -64
      ],
      "parameters": {
        "jsCode": "// Aggregate all uploaded items for summary\nconst items = $input.all();\n\nconst summary = {\n  totalUploads: items.length,\n  successCount: items.filter(i => i.json.uploadStatus === 'completed').length,\n  videos: items.map(i => ({\n    videoId: i.json.videoId,\n    title: i.json.title,\n    url: i.json.videoUrl\n  })),\n  generatedAt: new Date().toISOString()\n};\n\nreturn [{ json: summary }];"
      },
      "typeVersion": 2
    }
  ],
  "connections": {
    "Add to Playlist": {
      "main": [
        [
          {
            "node": "Merge Playlist Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Metadata Generator",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Metadata": {
      "main": [
        [
          {
            "node": "Check Scheduled Publish",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Playlist Add": {
      "main": [
        [
          {
            "node": "Add to Playlist",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge Playlist Result",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Prepare AI Context": {
      "main": [
        [
          {
            "node": "AI Metadata Generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Upload to Sheets": {
      "main": [
        [
          {
            "node": "Send Upload Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Binary Data": {
      "main": [
        [
          {
            "node": "Extract Video Metadata",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Error Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Video Upload Webhook": {
      "main": [
        [
          {
            "node": "Initialize Upload Session",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "YouTube Upload Video": {
      "main": [
        [
          {
            "node": "Process Upload Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Metadata Generator": {
      "main": [
        [
          {
            "node": "Parse AI Metadata",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Playlist Result": {
      "main": [
        [
          {
            "node": "Log Upload to Sheets",
            "type": "main",
            "index": 0
          },
          {
            "node": "Generate Upload Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Upload Result": {
      "main": [
        [
          {
            "node": "Check Playlist Add",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Immediate Publish": {
      "main": [
        [
          {
            "node": "Merge Publish Settings",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Extract Video Metadata": {
      "main": [
        [
          {
            "node": "Prepare AI Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Publish Settings": {
      "main": [
        [
          {
            "node": "YouTube Upload Video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Scheduled Settings": {
      "main": [
        [
          {
            "node": "Merge Publish Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Scheduled Publish": {
      "main": [
        [
          {
            "node": "Set Scheduled Settings",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set Immediate Publish",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Upload Notification": {
      "main": [
        [
          {
            "node": "Success Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Initialize Upload Session": {
      "main": [
        [
          {
            "node": "Validate Binary Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

Automatically process video files, extract metadata, generate AI-optimized titles/descriptions/tags, and upload directly to YouTube with proper categorization and thumbnail handling. YouTube Node Integration: Direct video upload to YouTube with full metadata Binary Data…

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

This n8n automation workflow automates the creation, scripting, production, and posting of YouTube videos. It leverages AI (OpenAI), image generation (PIAPI), video rendering (Shotstack), and platform

Agent, OpenAI Chat, Airtable Tool +7
AI & RAG

Enhance your support, onboarding, and internal knowledge workflows with an intelligent RAG-powered chatbot that responds using live data stored in Google Sheets. 🤖📚 Built for teams that rely on struct

Chat Trigger, Output Parser Structured, Memory Buffer Window +6
AI & RAG

leads. Uses supabase, gmail, formTrigger, httpRequest. Webhook trigger; 62 nodes.

Supabase, Gmail, Form Trigger +13
AI & RAG

This workflow automates the creation, rendering, approval, and posting of TikTok-style POV (Point of View) videos to Instagram, with cross-posting to Facebook and YouTube. It eliminates manual video p

OpenAI Chat, Output Parser Item List, HTTP Request +10
AI & RAG

Faceless YouTube Generator. Uses httpRequest, limit, googleDrive, googleSheets. Webhook trigger; 49 nodes.

HTTP Request, Google Drive, Google Sheets +7