AutomationFlowsAI & RAG › Generate Product Videos Automatically with Gemini, Fal and Google Workspace

Generate Product Videos Automatically with Gemini, Fal and Google Workspace

ByCong Nguyen @cong-nguyen on n8n.io

This workflow turns your n8n into an automated product-video generator powered by Google Sheets. When a new row is added with status = run, it: Downloads the product image from Google Drive. Converts the image to base64 and sends it to Gemini, which creates a branded ad-style…

Event trigger★★★★☆ complexity16 nodesGoogle Sheets TriggerGoogle DriveGoogle SheetsHTTP Request
AI & RAG Trigger: Event Nodes: 16 Complexity: ★★★★☆ Added:

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

This workflow follows the Google Drive → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "id": "06fc66f7-c12e-443c-bfdb-1339128e0dec",
      "name": "Google Sheets Trigger",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "position": [
        0,
        368
      ],
      "parameters": {
        "event": "rowAdded",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "=xxxx"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "=xxxxxx"
        }
      },
      "credentials": {
        "googleSheetsTriggerOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4f833098-8f46-457f-9e47-5e273b831de4",
      "name": "Download file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        464,
        368
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $json.link_image }}",
          "__regex": "https:\\/\\/(?:drive|docs)\\.google\\.com(?:\\/.*|)\\/d\\/([0-9a-zA-Z\\-_]+)(?:\\/.*|)"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "27356824-4c60-47f8-9c25-846d2716bd25",
      "name": "Extract from File",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        688,
        368
      ],
      "parameters": {
        "options": {},
        "operation": "binaryToPropery"
      },
      "typeVersion": 1
    },
    {
      "id": "8d2848d5-b2e5-49a7-9480-526ae86212b6",
      "name": "Convert to File",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        1168,
        368
      ],
      "parameters": {
        "options": {},
        "operation": "toBinary",
        "sourceProperty": "=candidates[0].content.parts[0].inlineData.data"
      },
      "typeVersion": 1.1
    },
    {
      "id": "2491f22b-31e8-4190-91ce-b3ef4889ae14",
      "name": "Upload file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1424,
        368
      ],
      "parameters": {
        "name": "={{ $now }}",
        "driveId": {
          "__rl": true,
          "mode": "id",
          "value": "=My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "=xxxxx"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "dac990c2-64a1-4e13-b9d4-ffbeb890f90c",
      "name": "Update row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2816,
        368
      ],
      "parameters": {
        "columns": {
          "value": {
            "STT": "={{ $('Google Sheets Trigger').item.json.STT }}",
            "status": "finished",
            "link_video": "={{ $json.webViewLink }}"
          },
          "schema": [
            {
              "id": "STT",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "STT",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "link_image",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "link_image",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "note",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "note",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "link_video",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "link_video",
              "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": [
            "STT"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1WCta4mwXQB0vY1Etre78IrVouruy6gRRe1mToswv6v8/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "=xxxx"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "82b056de-b2ac-4575-95b0-6bf1a10f4549",
      "name": "Sticky Note \u2014 Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 5,
        "width": 680,
        "height": 320,
        "content": "## Workflow Overview\n**Purpose:** Auto-generate branded product/ad videos directly from Google Sheets rows.\n**Trigger:** A new row is added with an image link (Google Sheets Trigger - rowAdded).\n**Steps:**\n1) Download image from Google Drive \u2192 Extract base64.\n2) Call Gemini API to create an ad-style image variant.\n3) Convert & upload the generated image to Drive (images folder).\n4) Send the image to FAL (image-to-video) to create a short clip.\n5) Poll FAL response URL until status = completed, then download the video.\n6) Upload video to Drive (videos folder) and update the sheet with the video link.\n\n**Result:** A fully automated pipeline: a spreadsheet row \u2192 final video asset."
      },
      "typeVersion": 1
    },
    {
      "id": "e93e737c-4712-46ed-9511-3a054cd34818",
      "name": "Sticky Note \u2014 Setup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1120,
        0
      ],
      "parameters": {
        "color": 3,
        "width": 680,
        "height": 280,
        "content": "## Setup Checklist\n- APIs & Keys: Google Sheets, Google Drive, **Gemini API key**, **FAL API key** (use Credentials; do not hardcode).\n- Google Drive: set folder IDs in the two **Upload file** nodes (image/video destinations).\n- Sheet columns (minimum): `STT`, `link_image`, `link_video`, `status`, `note`.\n- Trigger: runs when a new row is added.\n- Quick Test: add a row with a valid `link_image` \u2192 image generated \u2192 video uploaded \u2192 `link_video` written back."
      },
      "typeVersion": 1
    },
    {
      "id": "9d4202cd-993b-4f9c-b190-4058e827c9f9",
      "name": "Sticky Note \u2014 Notes & Tips",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        0
      ],
      "parameters": {
        "color": 4,
        "width": 680,
        "height": 300,
        "content": "## Notes & Tips\n- Security: keep `x-goog-api-key` and FAL `Authorization` in Credentials (`{{$credentials...}}`).\n- Polling: FAL is async; poll `response_url` until `status == completed` before downloading the video.\n- Links: if an API needs a direct file URL, use Drive direct-download (`uc?export=download&id=<FILE_ID>`).\n- Prompts: tweak Gemini text for brand voice; change FAL `prompt` (e.g., replace \"slow moving\").\n- Error Handling: add `If` + `Wait` + retries; log failures to the sheet (`status`, `note`).\n- Scale: paste multiple rows to batch-generate creatives."
      },
      "typeVersion": 1
    },
    {
      "id": "c1d73203-257e-4988-816d-393a3ca6fb6a",
      "name": "Filter",
      "type": "n8n-nodes-base.filter",
      "position": [
        208,
        368
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "ca5a2759-ec88-45a8-b037-58341ec5da2c",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "run"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "618d9398-d6f6-4b6a-8c8b-de030f213c49",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        1856,
        368
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "28ff8eda-a56e-4314-a980-b95ac06cb740",
      "name": "Create product image with model",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        912,
        368
      ],
      "parameters": {
        "url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image-preview:generateContent",
        "method": "POST",
        "options": {
          "redirect": {
            "redirect": {}
          }
        },
        "jsonBody": "={\n  \"contents\": [\n    {\n      \"parts\": [\n        {\n          \"text\": \"Create a image with model and product attached to create ads videos with this require: {{ JSON.stringify($('Filter').item.json.note).slice(1,-1) }}\"\n        },\n        {\n          \"inline_data\": {\n            \"mime_type\": \"image/jpeg\",\n            \"data\": \"{{ $json.data }}\"\n          }\n        }\n      ]\n    }\n  ]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "x-goog-api-key",
              "value": "xxxxxx"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f6cbccbc-9b32-40c2-9735-0915e44e684e",
      "name": "Create video",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1648,
        368
      ],
      "parameters": {
        "url": "https://queue.fal.run/fal-ai/ltxv-13b-098-distilled/image-to-video",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "prompt",
              "value": "=slow motion,  {{ $('Filter').item.json.note }}"
            },
            {
              "name": "image_url",
              "value": "={{ $json.webContentLink }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Key xxxxx"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0b700727-2e6b-4ce8-989d-ab18f1a5d887",
      "name": "Get Link Video",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2080,
        368
      ],
      "parameters": {
        "url": "={{ $json.response_url }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Key xxxx"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c5c00e9c-b56a-459b-a00c-151316707c4f",
      "name": "Download video",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2336,
        368
      ],
      "parameters": {
        "url": "={{ $json.video.url }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "306165a7-4320-4fcc-a03f-6cd424074c29",
      "name": "Upload video",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        2592,
        368
      ],
      "parameters": {
        "name": "={{ $now }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive",
          "cachedResultUrl": "https://drive.google.com/drive/my-drive",
          "cachedResultName": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "=xxxx"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    }
  ],
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Get Link Video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter": {
      "main": [
        [
          {
            "node": "Download file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload file": {
      "main": [
        [
          {
            "node": "Create video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create video": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload video": {
      "main": [
        [
          {
            "node": "Update row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download file": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download video": {
      "main": [
        [
          {
            "node": "Upload video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Link Video": {
      "main": [
        [
          {
            "node": "Download video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to File": {
      "main": [
        [
          {
            "node": "Upload file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File": {
      "main": [
        [
          {
            "node": "Create product image with model",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets Trigger": {
      "main": [
        [
          {
            "node": "Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create product image with model": {
      "main": [
        [
          {
            "node": "Convert to File",
            "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

This workflow turns your n8n into an automated product-video generator powered by Google Sheets. When a new row is added with status = run, it: Downloads the product image from Google Drive. Converts the image to base64 and sends it to Gemini, which creates a branded ad-style…

Source: https://n8n.io/workflows/8764/ — 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, marketers, and automation enthusiasts who want to produce professional AI-generated videos and publish them automatically on social media — without edit

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

This n8n workflow automatically generates presentation-style "screen recording" videos with AI-generated slides and a talking head avatar overlay. You provide a topic and intention, and the workflow h

HTTP Request, N8N Nodes Veed, Google Drive +1
AI & RAG

Monitor Google Drive folder, parsing PDF, DOCX and image file into a destination folder, ready for further processing (e.g. RAG ingestion, translation, etc.) Keep processing log in Google Sheet and se

Google Drive Trigger, Google Drive, HTTP Request +2
AI & RAG

This is the final piece of the AI content factory. This workflow takes your text-based video scripts and automatically generates high-quality audio voiceovers for each one, turning your text into read

Read Write File, Google Sheets, HTTP Request +2
AI & RAG

Generate realistic, high-quality images from text prompts using the Flux AI Text-to-Image Generator API via RapidAPI, and seamlessly store the results in Google Drive and log them in Google Sheets — a

Form Trigger, HTTP Request, Google Sheets +1