This workflow corresponds to n8n.io template #10358 — we link there as the canonical source.
This workflow follows the Blotaton8N Nodes Blotato → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "Zwz315okMu0UwtRQ",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "\ud83d\udca5 Automate AI Video Creation & Multi-Platform Publishing with Veo 3.1 & Blotato - vide",
"tags": [],
"nodes": [
{
"id": "f614b82e-a053-403d-afb5-b6c9cf9d6fd6",
"name": "Workflow Configuration",
"type": "n8n-nodes-base.set",
"position": [
896,
2000
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "openai_api_key",
"type": "string",
"value": "YOUR_OPENAI_API_KEY"
},
{
"id": "id-2",
"name": "min_idea_length",
"type": "number",
"value": 5
},
{
"id": "id-3",
"name": "required_photos",
"type": "number",
"value": 3
},
{
"id": "id-5",
"name": "fal_api_key",
"type": "string",
"value": "key YOUR_FAL_API_KEY"
},
{
"id": "id-6",
"name": "google_drive_folder_id",
"type": "string",
"value": "YOUR_GOOGLE_DRIVE_FOLDER_ID"
},
{
"id": "id-7",
"name": "google_sheet_id",
"type": "string",
"value": "YOUR_GOOGLE_SHEETS_ID"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "19a1188d-dbbd-48e5-a3ef-6da21410c3ec",
"name": "Parse GPT Response",
"type": "n8n-nodes-base.code",
"position": [
1376,
2000
],
"parameters": {
"jsCode": "// Parse OpenAI-style responses into { prompt, caption, hashtags[], hashtags_string }\nreturn $input.all().map(item => {\n const data = item.json || {};\n \n // Try to locate \"content\" in the common places\n let content =\n data?.choices?.[0]?.message?.content ??\n data?.message?.content ??\n data?.content ??\n null;\n\n let prompt = \"\";\n let caption = \"\";\n let hashtagsArr = [];\n\n // If content is an object (your current input case)\n if (content && typeof content === \"object\") {\n prompt = content.prompt ?? \"\";\n caption = content.caption ?? \"\";\n if (Array.isArray(content.hashtags)) {\n hashtagsArr = content.hashtags;\n } else if (typeof content.hashtags === \"string\") {\n // Support comma/space separated string\n hashtagsArr = content.hashtags.split(/[,\\s]+/).filter(Boolean);\n }\n }\n // If content is a string (some models return JSON as string)\n else if (typeof content === \"string\" && content.trim()) {\n try {\n const parsed = JSON.parse(content);\n prompt = parsed.prompt ?? \"\";\n caption = parsed.caption ?? \"\";\n if (Array.isArray(parsed.hashtags)) {\n hashtagsArr = parsed.hashtags;\n } else if (typeof parsed.hashtags === \"string\") {\n hashtagsArr = parsed.hashtags.split(/[,\\s]+/).filter(Boolean);\n }\n } catch {\n // Not a JSON string \u2014 leave fields empty\n prompt = \"\";\n caption = \"\";\n hashtagsArr = [];\n }\n }\n\n // Normalize hashtags: ensure leading '#', dedupe, no empties\n const norm = Array.from(\n new Set(\n (hashtagsArr || [])\n .map(h => (h ?? \"\").toString().trim())\n .filter(Boolean)\n .map(h => (h.startsWith(\"#\") ? h : `#${h}`))\n )\n );\n const hashtags_string = norm.join(\" \");\n\n return {\n json: {\n prompt,\n caption,\n hashtags: norm,\n hashtags_string\n }\n };\n});\n"
},
"typeVersion": 2
},
{
"id": "b9dfa37c-082f-431d-9494-aa620892b134",
"name": "Optimize Prompt for Veo",
"type": "n8n-nodes-base.set",
"position": [
672,
2224
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "veo_prompt",
"type": "string",
"value": "={{ $json.prompt }} consistent character throughout, photorealistic quality, professional cinematography, 8 seconds duration, 9:16 aspect ratio, 24fps"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "f73ea354-b40b-4dac-9ecc-687b315a4a84",
"name": "GPT-4 API Call",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1072,
2000
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "id",
"value": "gpt-4o-mini"
},
"options": {},
"messages": {
"values": [
{
"role": "system",
"content": "You are a viral video content creator"
},
{
"content": "=Create viral video content for {{ $json.niche }} about {{ $json.idea }}. Return JSON with: prompt (150-200 word cinematic Veo 3.1 description), caption (50-100 word social media text with emojis), hashtags (array of 8-10 tags)"
}
]
},
"jsonOutput": true
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.8
},
{
"id": "44c68f8d-0a12-4f9b-83fa-ca3b939bb223",
"name": "Download Video",
"type": "n8n-nodes-base.httpRequest",
"position": [
672,
2464
],
"parameters": {
"url": "={{ $json.video_url }}",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"typeVersion": 4.2
},
{
"id": "b8a019e2-af8d-4818-ad6d-86a31462e2a1",
"name": "Google Drive Upload",
"type": "n8n-nodes-base.googleDrive",
"position": [
896,
2464
],
"parameters": {
"name": "={{ 'AI_Video_' + $json.user_id + '_' + $json.timestamp + '.mp4' }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Workflow Configuration').first().json.google_drive_folder_id }}"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "563e682a-708e-4268-953b-0cc2df993632",
"name": "Google Sheets Append",
"type": "n8n-nodes-base.googleSheets",
"position": [
1136,
2464
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "id",
"value": "="
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Workflow Configuration').first().json.google_sheet_id }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "2e1a8319-95b3-43c7-b279-94bfd3b4afaf",
"name": "Google Sheets Trigger",
"type": "n8n-nodes-base.googleSheetsTrigger",
"position": [
464,
2000
],
"parameters": {
"event": "rowAdded",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyX",
"unit": "minutes",
"value": 30
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/10yrKcdX92Yxauixzl58RDN6yNKfxAk0zX5avPy0uqAE/edit#gid=0",
"cachedResultName": "Video_Requests"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "10yrKcdX92Yxauixzl58RDN6yNKfxAk0zX5avPy0uqAE",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/10yrKcdX92Yxauixzl58RDN6yNKfxAk0zX5avPy0uqAE/edit?usp=drivesdk",
"cachedResultName": "Video_Requests"
}
},
"credentials": {
"googleSheetsTriggerOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "76a152e7-6aa1-4859-94bf-4470fe79c51d",
"name": "Parse Sheet Input",
"type": "n8n-nodes-base.code",
"position": [
672,
2000
],
"parameters": {
"jsCode": "// Parse Google Sheets Input (headers) and Validate for Veo 3.1 workflow\nconst items = $input.all();\nconst results = [];\n\n// Helper to read and trim a field safely\nfunction getField(data, key) {\n const v = (data[key] ?? data[key?.toUpperCase?.()] ?? \"\").toString();\n return v.trim();\n}\n\nfor (const item of items) {\n const data = item.json || {};\n\n // Read by header names\n const id_video = getField(data, \"id_video\");\n const niche = getField(data, \"niche\");\n const idea = getField(data, \"idea\");\n const url_1 = getField(data, \"url_1\");\n const url_2 = getField(data, \"url_2\");\n const url_3 = getField(data, \"url_3\");\n const url_final = getField(data, \"url_final\"); // peut \u00eatre vide au d\u00e9part\n const status = getField(data, \"status\"); // ex: pending|processing|completed|failed\n const row_number = data.row ?? data._row ?? \"\";\n\n // Validation\n const errors = [];\n\n // niche & idea\n if (!niche || niche.length <= 2) {\n errors.push(\"niche must be longer than 2 characters\");\n }\n if (!idea || idea.length <= 5) {\n errors.push(\"idea must be longer than 5 characters\");\n }\n\n // URLs images requises\n if (!url_1 || !url_1.startsWith(\"http\")) {\n errors.push(\"url_1 is missing or invalid - must start with http\");\n }\n if (!url_2 || !url_2.startsWith(\"http\")) {\n errors.push(\"url_2 is missing or invalid - must start with http\");\n }\n if (!url_3 || !url_3.startsWith(\"http\")) {\n errors.push(\"url_3 is missing or invalid - must start with http\");\n }\n\n // url_final si pr\u00e9sent\n if (url_final && !url_final.startsWith(\"http\")) {\n errors.push(\"url_final is invalid - must start with http if provided\");\n }\n\n // status optionnel : normalisation (facultatif)\n const allowedStatus = new Set([\"\", \"pending\", \"processing\", \"completed\", \"failed\", \"draft\"]);\n if (!allowedStatus.has(status.toLowerCase?.() ?? \"\")) {\n errors.push(`status '${status}' is not recognized (use: pending|processing|completed|failed|draft)`);\n }\n\n // Build output item\n const image_urls = [url_1, url_2, url_3];\n\n const out = {\n json: {\n id_video,\n niche,\n idea,\n image_urls,\n url_final: url_final || \"\",\n status: (status || \"pending\").toLowerCase(),\n row_number,\n timestamp: new Date().toISOString(),\n },\n };\n\n // Valid flag + errors\n if (errors.length) {\n out.json.valid = false;\n out.json.validation_errors = errors;\n } else {\n out.json.valid = true;\n }\n\n results.push(out);\n}\n\nreturn results;\n"
},
"typeVersion": 2
},
{
"id": "65a7f4ed-10d7-44e0-8997-631991fc0bf3",
"name": "Veo Generation1",
"type": "n8n-nodes-base.httpRequest",
"position": [
1136,
2224
],
"parameters": {
"url": "https://fal.run/fal-ai/veo3.1/reference-to-video",
"method": "POST",
"options": {
"timeout": 600000,
"response": {
"response": {
"responseFormat": "json"
}
}
},
"jsonBody": "={{ JSON.stringify($json.veo_request_body) }}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "={{ $('Workflow Configuration').item.json.fal_api_key }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "a403778d-de47-4132-9e4a-4982dcd1f06e",
"name": "Prepare Veo Request Body",
"type": "n8n-nodes-base.code",
"position": [
896,
2224
],
"parameters": {
"jsCode": "const prompt = $input.item.json.veo_prompt || $input.item.json.prompt;\nlet imageUrls = $('Parse Sheet Input').item.json.image_urls;\n\nfunction convertGoogleDriveUrl(url) {\n if (!url) return url;\n if (url.includes('drive.google.com/file/d/')) {\n const match = url.match(/\\/d\\/([a-zA-Z0-9_-]+)/);\n if (match && match[1]) {\n return `https://drive.google.com/uc?export=download&id=${match[1]}`;\n }\n }\n return url;\n}\n\nif (!prompt || prompt.length < 10) {\n throw new Error('Prompt required');\n}\n\nif (!Array.isArray(imageUrls) || imageUrls.length !== 3) {\n throw new Error('Need 3 image URLs');\n}\n\nconst directImageUrls = imageUrls.map(url => convertGoogleDriveUrl(url));\n\ndirectImageUrls.forEach((url, index) => {\n if (!url || !url.startsWith('http')) {\n throw new Error('Invalid image URL at position ' + (index + 1));\n }\n});\n\nreturn {\n json: {\n veo_request_body: {\n prompt: prompt,\n image_urls: directImageUrls,\n duration: 8,\n aspect_ratio: \"9:16\"\n },\n ...($input.item.json)\n }\n};"
},
"typeVersion": 2
},
{
"id": "f65730da-04f6-4e63-9a38-b9b3354a3b02",
"name": "Extract Video Data",
"type": "n8n-nodes-base.code",
"position": [
1376,
2224
],
"parameters": {
"jsCode": "// Extract video data from Veo Generation response\nconst items = $input.all();\nconst results = [];\n\nfor (const item of items) {\n const data = item.json || {};\n \n // Extract video data from current node\n const video_url = data.video?.url || '';\n const video_content_type = data.video?.content_type || '';\n const video_file_size = data.video?.file_size || 0;\n const video_file_name = data.video?.file_name || '';\n \n // Preserve data from previous nodes\n const niche = $('Parse Sheet Input').item.json.niche || '';\n const idea = $('Parse Sheet Input').item.json.idea || '';\n const caption = $('Parse GPT Response').item.json.caption || '';\n const hashtags_string = $('Parse GPT Response').item.json.hashtags_string || '';\n const veo_prompt = $('Optimize Prompt for Veo').item.json.veo_prompt || '';\n const id_video = $('Parse Sheet Input').item.json.id_video || '';\n const row_number = $('Parse Sheet Input').item.json.row_number || '';\n \n results.push({\n json: {\n video_url,\n video_content_type,\n video_file_size,\n video_file_name,\n generation_completed_at: new Date().toISOString(),\n niche,\n idea,\n caption,\n hashtags_string,\n veo_prompt,\n id_video,\n row_number\n }\n });\n}\n\nreturn results;"
},
"typeVersion": 2
},
{
"id": "3b65094d-10e0-42a2-af60-ce4110d81f35",
"name": "Step 5 - Publishing",
"type": "n8n-nodes-base.stickyNote",
"position": [
1536,
1376
],
"parameters": {
"color": 5,
"width": 796,
"height": 1316,
"content": "# \ud83d\udce4 STEP 5: PUBLISHING & TRACKING\n\n### Install the Blotato [Blotato](https://blotato.com/?ref=firas) Node in n8n (Community Nodes)\n1. In n8n, open **Settings \u2192 Community Nodes**. \n2. Click **Install**, then add: `@blotato/n8n-nodes-blotato`. \n3. Log in to **Blotato**. \n4. Go to **Settings \u2192 API Keys**. \n5. In n8n \u2192 **Credentials \u2192 New**. \n6. Choose **Blotato API** \n(provided by the community node you installed). \n\n\u2705 **Activate Workflow:**\n- Toggle workflow to **Active** state\n- Ensure trigger is enabled\n\n\u2705 **Monitor Executions:**\n- Check execution history regularly\n- Review error logs if failures occur\n"
},
"typeVersion": 1
},
{
"id": "98ea7ae3-a917-42bf-9872-c9a212281224",
"name": "Upload Video to BLOTATO",
"type": "@blotato/n8n-nodes-blotato.blotato",
"position": [
1376,
2464
],
"parameters": {
"mediaUrl": "={{ $json.url_final }}",
"resource": "media"
},
"credentials": {
"blotatoApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "950a3e4f-52d5-4124-8c70-bc1b0da6cc00",
"name": "Youtube",
"type": "@blotato/n8n-nodes-blotato.blotato",
"position": [
1856,
2464
],
"parameters": {
"options": {},
"platform": "youtube",
"accountId": {
"__rl": true,
"mode": "list",
"value": "8047",
"cachedResultUrl": "https://backend.blotato.com/v2/accounts/8047",
"cachedResultName": "DR FIRASS (Dr. Firas)"
},
"postContentText": "={{ $('Save to Google Sheets').item.json.CAPTION }}",
"postContentMediaUrls": "={{ $json.url }}",
"postCreateYoutubeOptionTitle": "={{ $('Save to Google Sheets').item.json.IDEA }}",
"postCreateYoutubeOptionPrivacyStatus": "private",
"postCreateYoutubeOptionShouldNotifySubscribers": false
},
"credentials": {
"blotatoApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "62cf18fb-818d-40a8-be61-b08aecdebdec",
"name": "Tiktok",
"type": "@blotato/n8n-nodes-blotato.blotato",
"position": [
1632,
2000
],
"parameters": {
"options": {},
"platform": "tiktok",
"accountId": {
"__rl": true,
"mode": "list",
"value": "9332",
"cachedResultUrl": "https://backend.blotato.com/v2/accounts/9332",
"cachedResultName": "docteur.firas"
},
"postContentText": "={{ $('Save to Google Sheets').item.json.CAPTION }}",
"postContentMediaUrls": "={{ $json.url }}"
},
"credentials": {
"blotatoApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "f250b454-e081-49b6-abf8-9ebe04cd152f",
"name": "Linkedin",
"type": "@blotato/n8n-nodes-blotato.blotato",
"position": [
1840,
2000
],
"parameters": {
"options": {},
"platform": "linkedin",
"accountId": {
"__rl": true,
"mode": "list",
"value": "1446",
"cachedResultUrl": "https://backend.blotato.com/v2/accounts/1446",
"cachedResultName": "Samuel Amalric"
},
"postContentText": "={{ $('Save to Google Sheets').item.json.CAPTION }}",
"postContentMediaUrls": "={{ $json.url }}"
},
"credentials": {
"blotatoApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "6075fdc3-f2ae-43b8-9429-3f138f6a506c",
"name": "Facebook",
"type": "@blotato/n8n-nodes-blotato.blotato",
"position": [
1632,
2224
],
"parameters": {
"options": {},
"platform": "facebook",
"accountId": {
"__rl": true,
"mode": "list",
"value": "1759",
"cachedResultUrl": "https://backend.blotato.com/v2/accounts/1759",
"cachedResultName": "Firass Ben"
},
"facebookPageId": {
"__rl": true,
"mode": "list",
"value": "101603614680195",
"cachedResultUrl": "https://backend.blotato.com/v2/accounts/1759/subaccounts/101603614680195",
"cachedResultName": "Dr. Firas"
},
"postContentText": "={{ $('Save to Google Sheets').item.json.CAPTION }}",
"postContentMediaUrls": "={{ $json.url }}"
},
"credentials": {
"blotatoApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "fb35a6e6-8d5b-44f8-894c-3cd64cf43009",
"name": "Instagram",
"type": "@blotato/n8n-nodes-blotato.blotato",
"position": [
1840,
2224
],
"parameters": {
"options": {},
"accountId": {
"__rl": true,
"mode": "list",
"value": "1687",
"cachedResultUrl": "https://backend.blotato.com/v2/accounts/1687",
"cachedResultName": "acces.a.vie"
},
"postContentText": "={{ $('Save to Google Sheets').item.json.CAPTION }}",
"postContentMediaUrls": "={{ $json.url }}"
},
"credentials": {
"blotatoApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "4177dca6-53a5-4b32-9796-b526302ecc17",
"name": "Twitter (X)",
"type": "@blotato/n8n-nodes-blotato.blotato",
"position": [
1632,
2464
],
"parameters": {
"options": {},
"platform": "twitter",
"accountId": {
"__rl": true,
"mode": "list",
"value": "1289",
"cachedResultUrl": "https://backend.blotato.com/v2/accounts/1289",
"cachedResultName": "Docteur_Firas"
},
"postContentText": "={{ $('Save to Google Sheets').item.json.CAPTION }}",
"postContentMediaUrls": "={{ $json.url }}"
},
"credentials": {
"blotatoApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "6d972b56-f5eb-423d-9215-21ce753564a3",
"name": "Merge1",
"type": "n8n-nodes-base.merge",
"position": [
2128,
2160
],
"parameters": {
"mode": "chooseBranch",
"numberInputs": 6
},
"typeVersion": 3.2
},
{
"id": "21eedebf-5b84-4ee6-ac5d-9bdadaba1211",
"name": "Google Sheets Append1",
"type": "n8n-nodes-base.googleSheets",
"position": [
2128,
2464
],
"parameters": {
"columns": {
"value": {
"status": "Published",
"id_video": "={{ $('Google Sheets Trigger').first().json.id_video }}"
},
"schema": [
{
"id": "id_video",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "id_video",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "niche",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "niche",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "idea",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "idea",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "url_1",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "url_1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "url_2",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "url_2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "url_3",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "url_3",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "url_final",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "url_final",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "status",
"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": [
"id_video"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/10yrKcdX92Yxauixzl58RDN6yNKfxAk0zX5avPy0uqAE/edit#gid=0",
"cachedResultName": "Video_Requests"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "=10yrKcdX92Yxauixzl58RDN6yNKfxAk0zX5avPy0uqAE"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "a6cd7ba1-36a7-4807-9b47-1112da74a6ac",
"name": "Step 1 - Prerequisites",
"type": "n8n-nodes-base.stickyNote",
"position": [
-192,
1376
],
"parameters": {
"color": 5,
"width": 598,
"height": 1316,
"content": "# \ud83c\udfac AI VIDEO GENERATOR - VEO 3.1\n\n**Workflow Steps:**\n1. Monitor Google Sheets for new video requests\n2. Generate content with GPT-4\n3. Create video with Veo 3.1\n4. Upload to Google Drive\n5. Publish to social media via Blotato\n# \ud83d\udccb STEP 1: PREREQUISITES\n\n1. **OpenAI (GPT-4)**\n - Sign up: [platform.openai.com](https://platform.openai.com)\n - Get API key: [platform.openai.com/api-keys](https://platform.openai.com/api-keys)\n - Estimated cost: ~$0.01-0.05 per video\n\n2. **fal.ai (Veo 3.1)**\n - Sign up: [fal.ai](https://fal.ai)\n - Get API key: [fal.ai/dashboard/keys](https://fal.ai/dashboard/keys)\n - Estimated cost: ~$0.50-2.00 per video\n\n3. **Google Account**\n - Google Sheets (trigger & tracking)\n - Google Drive (video storage)\n - Free tier available\n\n4. **Blotato (Social Media Publishing)**\n - Sign up: [blotato.com](https://blotato.com)\n - Get API key from Settings \u2192 API Keys\n - Multi-platform publishing support\n\n# \ud83d\udcca STEP 2: GOOGLE SHEETS\n\n### Create Video_Requests Sheet\n1. Create a new Google Sheet named **Video_Requests**\n2. Add the following columns (A through H):\n - **A: id_video** - Unique video ID (auto-generated or sequential)\n - **B: niche** - Content niche or category (e.g. Tech, Fashion, Fitness)\n - **C: idea** - Short video idea or concept (min 5 characters)\n - **D: url_1** - First reference image (scene, product, or creator)\n - **E: url_2** - Second reference image\n - **F: url_3** - Third reference image\n - **G: url_final** - Final generated video URL (auto-filled by n8n)\n - **H: status** - Processing status (pending / processing / completed / failed)\n\n\n### Image URL Requirements\n- All image URLs must start with `http://` or `https://`\n- Google Drive URLs will be automatically converted to direct download links\n- Minimum 3 images required per video request\n\n### Google Drive Setup\n1. Create a folder in Google Drive for video storage\n2. Copy the folder ID from the URL\n3. Update the `google_drive_folder_id` in Workflow Configuration node"
},
"typeVersion": 1
},
{
"id": "d844cb16-6387-4745-8aaa-c5aa1b073c99",
"name": "Step 3 - API Keys Configuration",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
1376
],
"parameters": {
"color": 5,
"width": 550,
"height": 584,
"content": "# \ud83d\udd11 STEP 3: API KEYS CONFIGURATION\n\n\n## \u26a0\ufe0f Important Warnings\n\n**Timeout:** Veo video generation can take 5-10 minutes. HTTP request timeout is set to 10 minutes (600,000ms).\n\n**Estimated Costs Per Video:**\n- GPT-4 API call: ~$0.01-0.05\n- Fal.ai Veo 3.1 generation: ~$0.50-1.00\n- Total per video: ~$0.51-1.05\n\n**Rate Limits:** Be mindful of API rate limits for all services."
},
"typeVersion": 1
},
{
"id": "12c2de0c-cfc0-4e9d-8508-eebb22c9b094",
"name": "Step 4 - Workflow Activation",
"type": "n8n-nodes-base.stickyNote",
"position": [
976,
1376
],
"parameters": {
"color": 6,
"width": 550,
"height": 582,
"content": "# \ud83d\ude80 STEP 4: WORKFLOW ACTIVATION\n\n## Pre-Activation Checklist\n\n\u2705 **Verify All Credentials:**\n- OpenAI API key configured\n- Fal.ai API key set\n- Google Sheets OAuth connected\n- Google Drive OAuth connected\n- Blotato API key added (if publishing)\n\n\u2705 **Test Workflow:**\n1. Add a test row in your Google Sheets:\n - id_video: TEST_001\n - niche: Health\n - idea: Benefits of morning exercise\n - url_1, url_2, url_3: Valid image URLs\n - status: pending\n2. Wait for trigger to fire (30 min polling)\n3. Monitor execution in n8n dashboard\n\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "3bc03c0c-d6bb-4851-b83b-9d6c223d02bb",
"connections": {
"Merge1": {
"main": [
[
{
"node": "Google Sheets Append1",
"type": "main",
"index": 0
}
]
]
},
"Tiktok": {
"main": [
[
{
"node": "Merge1",
"type": "main",
"index": 0
}
]
]
},
"Youtube": {
"main": [
[
{
"node": "Merge1",
"type": "main",
"index": 5
}
]
]
},
"Facebook": {
"main": [
[
{
"node": "Merge1",
"type": "main",
"index": 2
}
]
]
},
"Linkedin": {
"main": [
[
{
"node": "Merge1",
"type": "main",
"index": 1
}
]
]
},
"Instagram": {
"main": [
[
{
"node": "Merge1",
"type": "main",
"index": 3
}
]
]
},
"Twitter (X)": {
"main": [
[
{
"node": "Merge1",
"type": "main",
"index": 4
}
]
]
},
"Download Video": {
"main": [
[
{
"node": "Google Drive Upload",
"type": "main",
"index": 0
}
]
]
},
"GPT-4 API Call": {
"main": [
[
{
"node": "Parse GPT Response",
"type": "main",
"index": 0
}
]
]
},
"Veo Generation1": {
"main": [
[
{
"node": "Extract Video Data",
"type": "main",
"index": 0
}
]
]
},
"Parse Sheet Input": {
"main": [
[
{
"node": "Workflow Configuration",
"type": "main",
"index": 0
}
]
]
},
"Extract Video Data": {
"main": [
[
{
"node": "Download Video",
"type": "main",
"index": 0
}
]
]
},
"Parse GPT Response": {
"main": [
[
{
"node": "Optimize Prompt for Veo",
"type": "main",
"index": 0
}
]
]
},
"Google Drive Upload": {
"main": [
[
{
"node": "Google Sheets Append",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets Append": {
"main": [
[
{
"node": "Upload Video to BLOTATO",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets Trigger": {
"main": [
[
{
"node": "Parse Sheet Input",
"type": "main",
"index": 0
}
]
]
},
"Workflow Configuration": {
"main": [
[
{
"node": "GPT-4 API Call",
"type": "main",
"index": 0
}
]
]
},
"Optimize Prompt for Veo": {
"main": [
[
{
"node": "Prepare Veo Request Body",
"type": "main",
"index": 0
}
]
]
},
"Upload Video to BLOTATO": {
"main": [
[
{
"node": "Tiktok",
"type": "main",
"index": 0
},
{
"node": "Linkedin",
"type": "main",
"index": 0
},
{
"node": "Facebook",
"type": "main",
"index": 0
},
{
"node": "Instagram",
"type": "main",
"index": 0
},
{
"node": "Twitter (X)",
"type": "main",
"index": 0
},
{
"node": "Youtube",
"type": "main",
"index": 0
}
]
]
},
"Prepare Veo Request Body": {
"main": [
[
{
"node": "Veo Generation1",
"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.
blotatoApigoogleDriveOAuth2ApigoogleSheetsOAuth2ApigoogleSheetsTriggerOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
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 editing or manual uploads. Perfect for those using Veo 3.1, GPT-4, and Blotato to…
Source: https://n8n.io/workflows/10358/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
💥 Automate YouTube thumbnail creation from video links -vide. Uses telegramTrigger, httpRequest, googleDrive, gmail. Event-driven trigger; 25 nodes.
💥 Automate YouTube thumbnail creation from video links -vide. Uses telegramTrigger, httpRequest, googleDrive, gmail. Event-driven trigger; 25 nodes.
This workflow is designed for YouTube creators, content marketers, automation builders, and agencies who want to repurpose existing YouTube videos into new original content and automate the publishing
The Problem That it Solves
Note: Now includes an Apify alternative for Rapid API (Some users can't create new accounts on Rapid API, so I have added an alternative for you. But immediately you are able to get access to Rapid AP