AutomationFlowsAI & RAG › Generate UGC AI Video Ads from Google Sheets

Generate UGC AI Video Ads from Google Sheets

Original n8n title: Ads Factory: Generate Unlimited Length Ugc AI Video Pipeline

ByGhufran Barcha @ghufranbarcha on n8n.io

This n8n workflow turns a script and character/setting description from Google Sheets into a complete stitched UGC-style video ad, fully automated from intake to final delivery.

Cron / scheduled trigger★★★★★ complexityAI-powered61 nodesGoogle SheetsHTTP RequestOpenRouter ChatOutput Parser StructuredStop And ErrorAgentOpenAIGoogle Drive
AI & RAG Trigger: Cron / scheduled Nodes: 61 Complexity: ★★★★★ AI nodes: yes Added:

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

This workflow follows the Agent → Execute Workflow Trigger 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
{
  "nodes": [
    {
      "id": "d89322eb-8d39-4e43-81a6-5c5e851ba92b",
      "name": "Get Video Ideas",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -7808,
        480
      ],
      "parameters": {
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultUrl": "",
          "cachedResultName": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc/edit?usp=drivesdk",
          "cachedResultName": "Ads Factory:  Tax Relief -  Final AI Videos (n8n)"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 5000
    },
    {
      "id": "6994d18f-8ffb-4f78-9f24-ff172b73fca7",
      "name": "HTTP Request12",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -7552,
        1728
      ],
      "parameters": {
        "url": "https://api.kie.ai/api/v1/veo/generate",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"prompt\": {{ JSON.stringify($json.SCRIPT.parseJson()) }},\n  \"imageUrls\": [\"{{ $json['IMAGE URL'] }}\",\"{{ $json['IMAGE URL'] }}\" ],\n  \"model\": \"veo3_fast\",\n  \"aspect_ratio\": \"Auto\",\n  \"generationType\": \"FIRST_AND_LAST_FRAMES_2_VIDEO\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "retryOnFail": true,
      "typeVersion": 4.3,
      "waitBetweenTries": 5000
    },
    {
      "id": "8652d395-55d2-42a9-a379-68c14272c501",
      "name": "HTTP Request13",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -7376,
        1728
      ],
      "parameters": {
        "url": "=https://api.kie.ai/api/v1/veo/record-info?taskId={{ $json.data.taskId }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "retryOnFail": true,
      "typeVersion": 4.3,
      "waitBetweenTries": 5000
    },
    {
      "id": "0148cb0b-b080-46dd-9b60-e055dcb1388e",
      "name": "Wait6",
      "type": "n8n-nodes-base.wait",
      "position": [
        -7200,
        1888
      ],
      "parameters": {
        "unit": "minutes",
        "amount": 10
      },
      "typeVersion": 1.1
    },
    {
      "id": "fe407dbe-fa9f-4d53-a4df-106be370ccd9",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -8960,
        336
      ],
      "parameters": {
        "width": 768,
        "height": 816,
        "content": "                                                                                                                                                           \n  # UGC Ads Factory                                                                                                                                                                                                                         \n  **Automated AI pipeline for UGC-style video ads**                                                                                                                                                                                           \n                                                                                                                                                                                                                                              \n  `Create row \u2192 Reference image \u2192 Scene plan \u2192 Scene clips \u2192 Stitch final video \u2192 Publish links`                                                                                                                                              \n                                                                                                                                                                                                                                              \n  ### How it works                                                                                                                                                                                                                            \n  - The trigger reads rows in **Videos** where `LAUNCH CREATION = Create`, normalizes fields, and marks each row `Processing`.                                                                                                              \n  - Kie creates a reference image. The workflow polls until completion, then uploads and shares the image in Google Drive.                                                                                                                    \n  - Claude-4o-mini analyzes visual details. Claude Opus converts the script into ordered 8-second scenes with consistent visual context and movement prompts.                                                                                 \n  - Each scene is appended to **Video Data** using `VIDEO ID`, `SCENE NO`, `SCRIPT`, and `TOTAL SCENES`.                                                                                                                                      \n  - VEO3 generates one clip per scene. Successful clips are uploaded and linked; failures are logged with error state.                                                                                                                        \n  - After all scenes complete, clips are sorted and merged via fal.ai FFmpeg.                                                                                                                                                                 \n  - Final video links are written back to **Videos**, and campaign status becomes `Completed`.                                                                                                                                                \n                                                                                                                                                                                                                                              \n  ### Setup                                                                                                                                                                                                                                   \n  - Configure credentials: Google Sheets, Google Drive, Kie, OpenRouter, OpenAI, fal.ai.                                                                                                                                                      \n  - Confirm sheet/tab names and column headers exactly match workflow mapping.                                                                                                                                                                \n  - Set destination folder IDs for image clips and final stitched videos.                                                                                                                                                                     \n                                                                                                                                                                                                                                              \n  ### Customization                                                                                                                                                                                                                           \n  - Tune scene length, polling intervals, model defaults, retry policy, and failure-routing behavior. "
      },
      "typeVersion": 1
    },
    {
      "id": "0559e237-00ff-4efe-a47e-36c8af909baf",
      "name": "Video Status Check",
      "type": "n8n-nodes-base.switch",
      "position": [
        -7200,
        1696
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Success",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "or",
                "conditions": [
                  {
                    "id": "vid-poll-success-flag",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.successFlag }}",
                    "rightValue": 1
                  },
                  {
                    "id": "vid-poll-success-state",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.state }}",
                    "rightValue": "success"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Failed",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "or",
                "conditions": [
                  {
                    "id": "vid-poll-failed-flag",
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    },
                    "leftValue": "={{ $json.data.successFlag }}",
                    "rightValue": 2
                  },
                  {
                    "id": "vid-poll-failed-state",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.state }}",
                    "rightValue": "failed"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Processing",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "or",
                "conditions": [
                  {
                    "id": "vid-poll-processing-flag",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.successFlag }}",
                    "rightValue": 0
                  },
                  {
                    "id": "vid-poll-waiting",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.state }}",
                    "rightValue": "waiting"
                  },
                  {
                    "id": "vid-poll-processing",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.state }}",
                    "rightValue": "processing"
                  },
                  {
                    "id": "vid-poll-generating",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.state }}",
                    "rightValue": "generating"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "Unknown Status"
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "4b470e1c-d761-4d7d-b1be-b52222135c20",
      "name": "Prompt Agent LLM",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        -7488,
        704
      ],
      "parameters": {
        "model": "anthropic/claude-opus-4.5",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "5c6d334c-8555-4459-812e-b495955719c7",
      "name": "Prompt Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -7344,
        704
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"prompt\": { \"type\": \"string\" },\n    \"model\": { \"type\": \"string\" },\n    \"aspectRatio\": { \"type\": \"string\" },\n    \"resolution\": { \"type\": \"string\" }\n  },\n  \"required\": [\"prompt\", \"model\", \"aspectRatio\",\"resolution\"]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "0b88243e-35a0-48ed-8642-7eb2fd553a23",
      "name": "Image Gen Error",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        -5696,
        1904
      ],
      "parameters": {
        "errorMessage": "=Image generation API failed. Code: {{ $json.code }}. Message: {{ $json.msg }}"
      },
      "typeVersion": 1
    },
    {
      "id": "757ee7c8-04b1-44a2-bdc5-2bc952ea21e8",
      "name": "Script Agent LLM",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        -5456,
        592
      ],
      "parameters": {
        "model": "anthropic/claude-opus-4.5",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "f5fdbb5e-0f2d-4d74-a869-c86aa65fe6b2",
      "name": "Scene Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -5280,
        592
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"scenes\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"scene_number\": { \"type\": \"number\" },\n          \"script\": { \"type\": \"string\" },\n          \"visual_description\": { \"type\": \"string\" },\n          \"audio_description\": { \"type\": \"string\" },\n          \"movement\": { \"type\": \"string\" },\n          \"duration_seconds\": { \"type\": \"number\" }\n        },\n        \"required\": [\"scene_number\", \"script\", \"visual_description\", \"movement\", \"duration_seconds\"]\n      }\n    }\n  },\n  \"required\": [\"scenes\"]\n}\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "a40e50b2-5f5c-4b7b-9e94-e3730408f4e3",
      "name": "Nano Banana Prompt Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -7488,
        480
      ],
      "parameters": {
        "text": "=Character Description:\n{{ $('Input').item.json.character_description }}\n\nVideo Script image reference:\n{{ $('Input').item.json.demo_script }}\n\nAspect_ratio:\n{{ $json.aspect_ratio }}\n\nGenerate the complete JSON for Nano Banana Pro API.",
        "options": {
          "systemMessage": "=You are an expert at crafting photorealistic AI image prompts for authentic UGC (User Generated Content) videos.\n\nTASK: Convert the user's character description and setting into a complete Nano Banana Pro API JSON body that generates an ultra-realistic raw mobile selfie photo. Use input details to ger\n\nSTRUCTURED PROMPT ELEMENTS (include ALL in your prompt string):\n\n1. CAMERA & COMPOSITION:\n   - \"iPhone 15 Pro front camera selfie\"\n   - \"9:16/169 vertical/Horizontal portrait orientation\"\n   - \"close-up/Medium close up head and shoulders shot\"\n   - \"35mm lens look, f/2.0 aperture\"\n   - \"EXTREME shallow depth of field, heavy soft bokeh background\" (CRITICAL: The background must be blurred into soft shapes to hide details for later video generation, regardless of the setting)\n\n2. SETTING & POSTURE (Analyze user input and adapt dynamically):\n   - IF CAR: \"Subject sitting in driver's seat of a car, phone positioned like a dash-mount or held casually, car interior and window, character looking toward camera.\"\n   - IF WALKING (Indoors/Outdoors): \"Subject walking, holding camera at arm's length (vlog style), dynamic posture, background elements completely blurred to conceal movement. \"\n   - IF ROOM (Bedroom, Office, Bathroom): \"Casual indoor environment, relaxed posture (sitting or standing),  character looking toward camera.\"\n   - IF OTHER: Apply natural UGC-style framing appropriate for the requested environment.\n\n3. LIGHTING (critical for realism):\n   - \"Natural soft window light\" OR \"soft diffused daylight\"\n   - \"Subtle rim light, no harsh shadows\"\n   - AVOID: \"studio lighting\", \"flash\", \"ring light\"\n\n4. SUBJECT REALISM (anti-AI detection):\n   - \"Realistic skin texture with visible pores, subtle skin imperfections\"\n   - \"Authentic facial expression, mid-conversation, natural hair\"\n5. IMPORTANT:\n   - No iphone or mobile should be visible in the video.\n\nOUTPUT: Return ONLY valid JSON (no markdown, no explanation):\n{\n  \"prompt\": \"[Comprehensive prompt combining all elements above with the user's character description]\",\n  \"model\": \"nano_banana_pro\",\n  \"aspectRatio\": \"9:16\",\n  \"resolution\": \"2k\"\n}"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "retryOnFail": true,
      "typeVersion": 3.1,
      "waitBetweenTries": 5000
    },
    {
      "id": "087b06f3-bed6-4e82-9c49-2652143803bd",
      "name": "Generate UGC Image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -7104,
        480
      ],
      "parameters": {
        "url": "=https://api.kie.ai/api/v1/jobs/createTask",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"model\": \"nano-banana-2\",\n  \"callBackUrl\": \"https://your-domain.com/api/callback\",\n  \"input\": {\n    \"prompt\": {{ JSON.stringify($json.output.prompt) }},\n    \"aspect_ratio\": \"{{ $('Input').item.json.aspect_ratio }}\",\n    \"resolution\": \"2K\",\n    \"output_format\": \"png\"\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "executeOnce": false,
      "retryOnFail": true,
      "typeVersion": 4.3,
      "waitBetweenTries": 5000
    },
    {
      "id": "c0d40d1a-ad66-4c7a-a1bb-ebe2e6c589d5",
      "name": "Image Gen Response Check",
      "type": "n8n-nodes-base.switch",
      "position": [
        -6912,
        464
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Success",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "img-gen-success",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.code }}",
                    "rightValue": 200
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Error",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "img-gen-error",
                    "operator": {
                      "type": "number",
                      "operation": "notEquals"
                    },
                    "leftValue": "={{ $json.code }}",
                    "rightValue": 200
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "Unexpected"
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e9040eb0-e298-4cb5-b8a2-e021476905a3",
      "name": "Workflow Configuration3",
      "type": "n8n-nodes-base.set",
      "position": [
        -5792,
        400
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "7ee37300-28a6-4426-85c8-1b23dab144ea",
              "name": "referenceImage",
              "type": "string",
              "value": "={{ $('Upload file').item.json.webViewLink }}"
            },
            {
              "id": "ref-img",
              "name": "download_image",
              "type": "string",
              "value": "={{ $('Upload file').item.json.webContentLink }}"
            },
            {
              "id": "21a05480-dd91-4a05-a824-e260a621e4f6",
              "name": "character_description",
              "type": "string",
              "value": "={{ $('Input').item.json.character_description }}"
            },
            {
              "id": "demo-script",
              "name": "demo_script",
              "type": "string",
              "value": "={{ $('Input').item.json.demo_script }}"
            },
            {
              "id": "aspect-ratio",
              "name": "aspect_ratio",
              "type": "string",
              "value": "={{ $('Input').item.json.aspect_ratio }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "3f7fdefa-aefa-40f1-b2cc-3d7a97a35655",
      "name": "Split Scenes",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -5168,
        400
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "output.scenes"
      },
      "typeVersion": 1
    },
    {
      "id": "fe848a2d-d4ef-4015-839c-2107b9ad6250",
      "name": "Analyze UGC Image3",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        -5600,
        400
      ],
      "parameters": {
        "text": "Analyze this UGC image in detail. Describe the subject's appearance (age, ethnicity, hair, clothing), setting, lighting, mood, and composition. Focus on details needed for video generation consistency.",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {
          "detail": "high"
        },
        "resource": "image",
        "imageUrls": "={{ $json.download_image }}",
        "operation": "analyze"
      },
      "retryOnFail": true,
      "typeVersion": 2.1
    },
    {
      "id": "eef8c19c-57b7-4b3b-995d-f642cfa394fe",
      "name": "Generate Scene Scripts3",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -5456,
        400
      ],
      "parameters": {
        "text": "=Image Prompt:\n{{ $('Workflow Configuration3').item.json.character_description }}\n\nGenerated Image Analysis:\n{{ $json['0'].content[0].text }}\n\nUser Script:\n{{ $('Workflow Configuration3').item.json.demo_script }}\n\nCreate video scenes from this script.",
        "options": {
          "systemMessage": "=You are an expert Creative Director and Scriptwriter for AI-generated \"talking photo\" video sequences. \n\nCRITICAL GOAL\nYour task is to take a reference image analysis and user instructions (script/requirements) and turn them into a structured series of video scenes.\n\nVISUAL CONSISTENCY (Non-negotiable)\n1. The entire video is generated from ONE static reference image. \n2. The `visual_description` for EVERY scene must be IDENTICAL. \n3. Use the provided image analysis to create a concise (max 300 characters) static visual description. Add: \"iPhone UGC style, slightly grainy, authentic speaking gestures\".\n\nSCENE GENERATION LOGIC\n1. Split the script into logical segments of approximately 20 - 27 words (roughly 8 seconds of speech).\n2. Output a JSON object containing a \"scenes\" array.\n\nSCENE STRUCTURE RULES\nEach object in the `scenes` array must include:\n- `scene_number`: Sequential integer starting at 1.\n- `script`: The spoken text for that specific 8-second segment.\n- `visual_description`: The identical string described above.\n- `duration_seconds`: Always 8.\n\nDYNAMIC MOVEMENT LOGIC (Crucial for Video AI):\nAnalyze the setting from the image analysis and assign the appropriate `movement` string for EVERY scene:\n- IF CAR INTERIOR: \"natural head movements while talking, slight camera vibration from car idling, blurred scenery passing subtly in the windows.\"\n- IF WALKING (Outdoors/Indoors): \"continuous forward walking motion, subject holding camera vlog-style, natural camera bounce matching footsteps, heavily blurred background passing by smoothly.\"\n- IF STATIC ROOM (Bedroom/Office/Couch): \"natural subtle body movement, slight handheld camera drift, expressive facial gestures, static blurred background.\"\n- IF OTHER: Deduce the natural physics of the scene (is the camera static or moving? is the background static or moving?) and write a brief, cohesive motion prompt.\n\nSCRIPT RULES FOR AUTHENTICITY:\n- Don't include pauses: \"And I couldn't believe it\"\n- Conversational tone, not salesy\n- NO stage directions like [smiles] or [nods] in the script text.\n\nOUTPUT: Return ONLY valid JSON:\n{\n  \"scenes\": [\n    {\n      \"scene_number\": 1,\n      \"script\": \"The spoken text...\",\n      \"visual_description\": \"Static description of the person...\",\n      \"audio_description\": \"No background noice\",\n      \"movement\": \"Dynamic motion instructions based on the identified environment...\",\n      \"duration_seconds\": 8\n    }\n  ]\n}\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "retryOnFail": true,
      "typeVersion": 3.1
    },
    {
      "id": "5307f0e6-a123-43b9-8d77-b4fbb75cb652",
      "name": "Input",
      "type": "n8n-nodes-base.set",
      "position": [
        -7648,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "8117b31c-6433-447e-89d0-1ae00d8bd3a5",
              "name": "character_description",
              "type": "string",
              "value": "={{ $json['CHARACTER/SETTING DESCRIPTION'] }}"
            },
            {
              "id": "711643da-17f7-46bc-8c66-294843d4a2b9",
              "name": "demo_script",
              "type": "string",
              "value": "={{ $json.SCRIPT }}"
            },
            {
              "id": "fb55afcc-a21b-49bb-b4b2-e9e504b7bc13",
              "name": "aspect_ratio",
              "type": "string",
              "value": "={{ $json['ASPECT RATIO'] || \"9:16\" }}"
            },
            {
              "id": "23dcda06-c268-4fcd-9e5f-4d8813dcbde7",
              "name": "id",
              "type": "string",
              "value": "={{ $execution.id + '_' + Date.now().toString() + Math.random().toString(36).substring(2, 10) }}"
            },
            {
              "id": "e30c7c90-87e9-47d5-b001-5062a3c7e678",
              "name": "row_number",
              "type": "number",
              "value": "={{ $json.row_number }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "8dc23647-0633-47cf-942c-755cc4b9f94c",
      "name": "videoInput",
      "type": "n8n-nodes-base.set",
      "position": [
        -7728,
        1728
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "94515e20-338a-425c-838d-f77c802c5266",
              "name": "ID",
              "type": "string",
              "value": "={{ $json.ID }}"
            },
            {
              "id": "aa02ee83-02aa-4aee-9e7b-2eb98bcdc902",
              "name": "VIDEO ID",
              "type": "string",
              "value": "={{ $json['VIDEO ID'] }}"
            },
            {
              "id": "cbda8d7e-3f8b-4b3c-8029-7564002e4068",
              "name": "SCRIPT",
              "type": "string",
              "value": "={{ $json.SCRIPT }}"
            },
            {
              "id": "e6a0442e-46b0-4226-a1f5-07e3fa9105a1",
              "name": "IMAGE URL",
              "type": "string",
              "value": "={{ $json['IMAGE URL'] }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "160418ac-08be-4a9d-beb2-cd1074379038",
      "name": "HTTP Request1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -6960,
        1680
      ],
      "parameters": {
        "url": "={{ $('Video Status Check').item.json.data.response.resultUrls[0] }}",
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 4.4,
      "waitBetweenTries": 5000
    },
    {
      "id": "79ed8983-c1ca-4b49-aa0f-742f443de5b4",
      "name": "Wait 10s",
      "type": "n8n-nodes-base.wait",
      "position": [
        -6480,
        608
      ],
      "parameters": {
        "amount": 60
      },
      "typeVersion": 1.1
    },
    {
      "id": "d9a1c791-c535-4cd2-a6e5-a878aa144df3",
      "name": "Image Poll Error",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        -6480,
        864
      ],
      "parameters": {
        "errorMessage": "=Image generation failed permanently. State: {{ $json.data.state }}. SuccessFlag: {{ $json.data.successFlag }}. Error: {{ $json.data.errorMessage || 'Unknown error' }}. TaskId: {{ $json.data.taskId }}"
      },
      "typeVersion": 1
    },
    {
      "id": "210cb9ec-6c71-4673-8818-14fa28cb34c3",
      "name": "Poll Image Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -6640,
        448
      ],
      "parameters": {
        "url": "=https://api.kie.ai/api/v1/jobs/recordInfo?taskId={{ $json.data.taskId }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "retryOnFail": true,
      "typeVersion": 4.3,
      "waitBetweenTries": 5000
    },
    {
      "id": "06526cb8-8aba-47bb-aefe-6553420fe5b1",
      "name": "Image Status Check",
      "type": "n8n-nodes-base.switch",
      "position": [
        -6480,
        416
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Success",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "or",
                "conditions": [
                  {
                    "id": "img-poll-success-flag",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.successFlag }}",
                    "rightValue": 1
                  },
                  {
                    "id": "img-poll-success-state",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.state }}",
                    "rightValue": "success"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Failed",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "or",
                "conditions": [
                  {
                    "id": "img-poll-failed-flag",
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    },
                    "leftValue": "={{ $json.data.successFlag }}",
                    "rightValue": 2
                  },
                  {
                    "id": "img-poll-failed-state",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.state }}",
                    "rightValue": "failed"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Processing",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "or",
                "conditions": [
                  {
                    "id": "img-poll-processing-flag",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.successFlag }}",
                    "rightValue": 0
                  },
                  {
                    "id": "img-poll-waiting",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.state }}",
                    "rightValue": "waiting"
                  },
                  {
                    "id": "img-poll-processing",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.state }}",
                    "rightValue": "processing"
                  },
                  {
                    "id": "img-poll-generating",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.state }}",
                    "rightValue": "generating"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "Unknown Status"
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "9ece6252-e993-493b-9dea-6e4dd721e6b9",
      "name": "Upload file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -6080,
        400
      ],
      "parameters": {
        "name": "={{ $('Input').item.json.id }}.png",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "11kfsPSUmo3vzh5J3evGxEFa6aRrNPh5R"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "99701b3a-4f09-4071-b787-1643a5353309",
      "name": "Download Image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -6208,
        400
      ],
      "parameters": {
        "url": "={{ $json.data.resultJson.parseJson().resultUrls[0] }}",
        "options": {}
      },
      "typeVersion": 4.4
    },
    {
      "id": "dc6b25d5-23de-4609-b1c6-7f3f83065d75",
      "name": "Share file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -5952,
        400
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "share",
        "permissionsUi": {
          "permissionsValues": {
            "role": "reader",
            "type": "anyone"
          }
        }
      },
      "typeVersion": 3
    },
    {
      "id": "a24f13cb-c7af-4452-8c90-28d2d8ba7bdb",
      "name": "UpdateSheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -5008,
        400
      ],
      "parameters": {
        "columns": {
          "value": {
            "ID": "={{ $('Input').first().json.id }}",
            "LAUNCH": "Processing",
            "SCRIPT": "={{ JSON.stringify($json) }}",
            "SCENE NO": "={{ $json.scene_number }}",
            "VIDEO ID": "={{ $('Input').first().json.id }}_{{ $itemIndex }}",
            "IMAGE URL": "={{ $('Workflow Configuration3').first().json.download_image }}",
            "TOTAL SCENES": "={{ $('Generate Scene Scripts3').first().json.output.scenes.length }}"
          },
          "schema": [
            {
              "id": "ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "VIDEO ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "VIDEO ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "IMAGE URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "IMAGE URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "TOTAL SCENES",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "TOTAL SCENES",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SCENE NO",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "SCENE NO",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SCRIPT",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "SCRIPT",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "VIDEO VIEW CLIP",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "VIDEO VIEW CLIP",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "VIDEO CLIP LINK",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "VIDEO CLIP LINK",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LAUNCH",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "LAUNCH",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Error",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Error",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 419137619,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1JmhjG7XehIfIqlwhxf5orUlNDxMf_uuaz01_gyMtBBk/edit#gid=419137619",
          "cachedResultName": "Video Data"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc/edit?usp=drivesdk",
          "cachedResultName": "Ads Factory:  Tax Relief -  Final AI Videos (n8n)"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 5000
    },
    {
      "id": "ebb29036-8a05-4fce-8bb5-d233b87de2e2",
      "name": "UpdateSheet1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -4720,
        864
      ],
      "parameters": {
        "columns": {
          "value": {
            "ID": "={{ $('Input').first().json.id }}",
            "SCRIPT": "={{ $('Input').item.json.demo_script }}",
            "row_number": "={{ $('Input').item.json.row_number }}",
            "LAUNCH CREATION": "Processing"
          },
          "schema": [
            {
              "id": "ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SCRIPT NAME",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "SCRIPT NAME",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SCRIPT",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "SCRIPT",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "CHARACTER/SETTING DESCRIPTION",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "CHARACTER/SETTING DESCRIPTION",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ASPECT RATIO",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ASPECT RATIO",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "VIDEO VIEW LINK",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "VIDEO VIEW LINK",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "VIDEO LINK",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "VIDEO LINK",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LAUNCH CREATION",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "LAUNCH CREATION",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1JmhjG7XehIfIqlwhxf5orUlNDxMf_uuaz01_gyMtBBk/edit#gid=0",
          "cachedResultName": "Videos"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc/edit?usp=drivesdk",
          "cachedResultName": "Ads Factory:  Tax Relief -  Final AI Videos (n8n)"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 5000
    },
    {
      "id": "dca509d8-8d78-4be5-aefb-9addf3debc47",
      "name": "Get row(s) in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -7872,
        1728
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $('Input').item.json.id }}",
              "lookupColumn": "ID"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 419137619,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1JmhjG7XehIfIqlwhxf5orUlNDxMf_uuaz01_gyMtBBk/edit#gid=419137619",
          "cachedResultName": "Video Data"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc/edit?usp=drivesdk",
          "cachedResultName": "Ads Factory:  Tax Relief -  Final AI Videos (n8n)"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 5000
    },
    {
      "id": "cdcd3e51-a210-4a4d-8b58-d6a095fc85eb",
      "name": "Upload file1",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -6784,
        1680
      ],
      "parameters": {
        "name": "={{ $('videoInput').item.json['VIDEO ID'] }}.mp4",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "1HlQRqwXfdYEm8zIsxQ0NsEYRAUEaFvMD"
        }
      },
      "retryOnFail": true,
      "typeVersion": 3,
      "waitBetweenTries": 5000
    },
    {
      "id": "3bda72be-7bf7-425b-8fa0-e262c5452cb1",
      "name": "Share file1",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -6640,
        1680
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "share",
        "permissionsUi": {
          "permissionsValues": {
            "role": "reader",
            "type": "anyone"
          }
        }
      },
      "retryOnFail": true,
      "typeVersion": 3,
      "waitBetweenTries": 5000
    },
    {
      "id": "6aee447c-c1f3-418d-9c3b-eb661161f707",
      "name": "UpdateSheet2",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -6464,
        1680
      ],
      "parameters": {
        "columns": {
          "value": {
            "Error": "No Error",
            "LAUNCH": "Completed",
            "VIDEO ID": "={{ $('videoInput').item.json['VIDEO ID'] }}",
            "VIDEO CLIP LINK": "={{ $('Upload file1').item.json.webContentLink }}",
            "VIDEO VIEW CLIP": "={{ $('Upload file1').item.json.webViewLink.split(\"?\")[0] }}"
          },
          "schema": [
            {
              "id": "ID",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "VIDEO ID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "VIDEO ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "IMAGE URL",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "IMAGE URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "TOTAL SCENES",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "TOTAL SCENES",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SCENE NO",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "SCENE NO",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SCRIPT",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "SCRIPT",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "VIDEO VIEW CLIP",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "VIDEO VIEW CLIP",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "VIDEO CLIP LINK",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "VIDEO CLIP LINK",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LAUNCH",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "LAUNCH",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Error",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Error",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "VIDEO ID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 419137619,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1JmhjG7XehIfIqlwhxf5orUlNDxMf_uuaz01_gyMtBBk/edit#gid=419137619",
          "cachedResultName": "Video Data"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc/edit?usp=drivesdk",
          "cachedResultName": "Ads Factory:  Tax Relief -  Final AI Videos (n8n)"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 5000
    },
    {
      "id": "98e90d5c-382b-4017-b8e7-b8a958360bd2",
      "name": "Get row(s) for Stitch",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -6272,
        1680
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $('videoInput').item.json.ID }}",
              "lookupColumn": "ID"
            },
            {
              "lookupValue": "Completed",
              "lookupColumn": "LAUNCH"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 419137619,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1JmhjG7XehIfIqlwhxf5orUlNDxMf_uuaz01_gyMtBBk/edit#gid=419137619",
          "cachedResultName": "Video Data"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1XgFKo9N2jIiUNtizbpQXMAIDc6mSOhngW6EnAKdtawc/edit?usp=drivesdk",
          "cachedResultName": "Ads Factory:  Tax Relief -  Final AI Videos (n8n)"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 5000
    },
    {
      "id": "09d31ad8-e2fb-47d9-9bc4-7c7f72346821",
      "name": "Sort",
      "type": "n8n-nodes-base.sort",
      "position": [
        -5696,
        1600
      ],
      "parameters": {
        "options": {},
        "sortFieldsUi": {
          "sortField": [
            {
              "fieldName": "SCENE NO"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a44712c4-c5b4-4915-a42e-6bbecbf150c7",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "position": [
        -6080,
        1680
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst totalItems = items.length;\n\n// Assuming TOTAL SCENES is same for all items (usually from sheet row)\nconst totalScenes = Number(items[0].json[\"TOTAL SCENES\"]);\n\nconst isComplete = totalItems >= totalScenes;\n\nfor (const item of items) {\n  item.json.isComplete = isComplete;\n}\n\nreturn items;"
      },
      "typeVersion": 2
    },
    {
      "id": "9e26a0ce-0a75-41d3-92e0-e774afccf9a6",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        -5872,
        1680
      ],
      "parameters": {
        "options": {
          "ignoreCase": true
        },
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0b05360c-9abf-4e3d-ba2a-f3ae3627932b",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.isComplete }}",
              "rightValue": true
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "81261d3e-c2d1-44c4-a396-54c225b9a9a2",
      "name": "download-video8",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -5104,
        1600
      ],
      "parameters": {
        "url": "={{ $json.video.url }}",
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 4.3,
      "waitBetweenTries": 5000
    },
    {
      "id": "65fc1067-2502-460a-aad9-0f4f4afb930d",
      "name": "Upload file2",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -4864,
        1600
      ],
      "parameters": {
        "name": "={{ $('videoInput').item.json.ID }}.mp4",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "1HlQRqwXfdYEm8zIsxQ0NsEYRAUEaFvMD"
        }
      },
      "retryOnFail": true,
      "typeVersion": 3,
      "waitBetweenTries": 5000
    },
    {
      "id": "6ad7af35-7562-448c-a703-80194c105b5e",
      "name": "Share file2",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -4720,
        1600
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "share",
        "permissionsUi": {
          "permissionsValues": {
            "role": "reader",
            "type": "anyone"
          }
        }
      },
      "retryOnFail": true,
      "typeVersion": 3,
      "waitBetweenTries": 5000
    },
    {
      "id": "fdcb362c-2d19-40b6-9fb4-7eb3368668e0",
      "name": "UpdateSheet3",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -4544,
        1600
      ],
      "parameters": {
        "columns": {
          "value": {
            "ID": "={{ $('videoInput').first().json.ID }}",
            "VIDEO LINK": "={{ $('Upload file2').item.json.webContentLink }}",
            "LAUNCH CREATION": "Completed",
            "VIDEO VIEW LINK": "={{ $('Upload file2').item.json.webViewLink.split(\"?\")[0] }}"
          },
          "schema": [
            {
              "id": "ID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SCRIPT NAME",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "SCRIPT NAME",
  

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

This n8n workflow turns a script and character/setting description from Google Sheets into a complete stitched UGC-style video ad, fully automated from intake to final delivery.

Source: https://n8n.io/workflows/14316/ — 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 workflow is designed for: Content creators and marketers E-commerce and product-based businesses Agencies producing social media visuals and videos Automation builders looking for AI-powered crea

HTTP Request, Edit Image, Google Drive +7
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

Viral Video Agent. Uses lmChatOpenRouter, httpRequest, googleSheets, googleDrive. Scheduled trigger; 44 nodes.

OpenRouter Chat, HTTP Request, Google Sheets +3
AI & RAG

Content marketers and SEO specialists who need to generate multiple SEO-optimized articles targeting keyword variations. Ideal for affiliate sites, niche blogs, or service-based businesses creating lo

Agent, Memory Buffer Window, OpenAI Chat +7
AI & RAG

This advanced automation template allows marketing teams, content creators, and branding specialists to automatically generate and publish high-quality, visually captivating branded short videos acros

OpenRouter Chat, HTTP Request, Google Sheets +3