This workflow corresponds to n8n.io template #12929 — we link there as the canonical source.
This workflow follows the Agent → Form 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 →
{
"id": "dpAPzcy7d7FAPB4q",
"name": "Auto-Generate AI Product Review Videos",
"tags": [],
"nodes": [
{
"id": "9be96357-f528-4e8b-9ded-fc6f9df265bb",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
-1184,
176
],
"parameters": {
"options": {},
"modelName": "models/gemini-3-pro-preview"
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "8df6e615-8000-4f6f-b7f6-6c8d25624167",
"name": "Structured Output Parser1",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-944,
144
],
"parameters": {
"autoFix": true,
"jsonSchemaExample": "{\n \"image_prompt\": \"string\"\n}\n"
},
"typeVersion": 1.3
},
{
"id": "851b173f-5093-4e3c-823d-e017ec18d9d6",
"name": "Wait3",
"type": "n8n-nodes-base.wait",
"position": [
-240,
272
],
"parameters": {
"amount": 15
},
"typeVersion": 1.1
},
{
"id": "34dfb73c-db8a-4768-bc10-d0c1450a0b87",
"name": "Get Images",
"type": "n8n-nodes-base.httpRequest",
"position": [
-16,
272
],
"parameters": {
"url": "=https://api.geminigen.ai/uapi/v1/history/{{ $json.uuid }}",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "039910b6-1255-4239-ba1a-2d27ccc75320",
"name": "Generate Images",
"type": "n8n-nodes-base.httpRequest",
"position": [
-448,
272
],
"parameters": {
"url": "https://api.geminigen.ai/uapi/v1/generate_image",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "prompt",
"value": "={{ $json.output.image_prompt }}"
},
{
"name": "model",
"value": "imagen-pro"
},
{
"name": "aspect_ratio",
"value": "9:16"
},
{
"name": "style",
"value": "Photorealistic"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "8fb2e5e3-265c-4989-b127-e64475d93bb3",
"name": "Google Gemini Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
-1184,
992
],
"parameters": {
"options": {},
"modelName": "models/gemini-3-pro-preview"
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "c0d1d207-9a4e-4ed2-b39f-d09e1b12beea",
"name": "Generate Videos",
"type": "n8n-nodes-base.httpRequest",
"position": [
-384,
752
],
"parameters": {
"url": "https://api.geminigen.ai/uapi/v1/video-gen/veo",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "prompt",
"value": "={{ $json.video_prompt }}"
},
{
"name": "model",
"value": "veo-3-fast"
},
{
"name": "resolution",
"value": "720p"
},
{
"name": "aspect_ratio",
"value": "9:16"
},
{
"name": "file_urls",
"value": "={{ $('Get Images').item.json.generated_image[0].image_url }}"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "746a1c77-f782-474c-9ab0-1ee57ca4a94f",
"name": "Wait1",
"type": "n8n-nodes-base.wait",
"position": [
-192,
752
],
"parameters": {
"amount": 10
},
"typeVersion": 1.1
},
{
"id": "8e70b0e6-55f8-4597-a5a4-28e1128aecab",
"name": "Get Videos",
"type": "n8n-nodes-base.httpRequest",
"position": [
-16,
752
],
"parameters": {
"url": "=https://api.geminigen.ai/uapi/v1/history/{{ $json.uuid }}",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "4e3157e7-02c0-4149-919c-b8b6b846982e",
"name": "If1",
"type": "n8n-nodes-base.if",
"position": [
160,
752
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8a2caa94-db0d-4141-ab47-c803e69db7c9",
"operator": {
"type": "number",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": 2
}
]
}
},
"typeVersion": 2.2
},
{
"id": "04ef9a4a-7a46-4358-a59e-f742a7b83a23",
"name": "Code in JavaScript",
"type": "n8n-nodes-base.code",
"position": [
-1264,
1424
],
"parameters": {
"jsCode": "// 1. L\u1ea5y item \u0111\u1ea7u ti\u00ean t\u1eeb node Aggregate\nconst item = $input.first();\n\n// 2. L\u1ea5y danh s\u00e1ch link (\u0111ang l\u00e0 m\u1ea3ng c\u00e1c chu\u1ed7i text)\n// D\u1eef li\u1ec7u l\u1ea5y t\u1eeb tr\u01b0\u1eddng 'video_url'\nconst originalUrls = item.json.video_url; \n\n// 3. Bi\u1ebfn \u0111\u1ed5i th\u00e0nh d\u1ea1ng [{\"video_url\": \"link1\"}, {\"video_url\": \"link2\"}]\nconst formattedList = originalUrls.map(url => ({\n video_url: url\n}));\n\n// 4. T\u1ea1o object t\u1ed5ng theo \u0111\u00fang c\u1ea5u tr\u00fac y\u00eau c\u1ea7u\nconst finalObject = {\n video_urls: formattedList,\n id: \"2323\"\n};\n\n// 5. Tr\u1ea3 v\u1ec1 k\u1ebft qu\u1ea3\n// Quan tr\u1ecdng: D\u00f9ng JSON.stringify() \u0111\u1ec3 bi\u1ebfn object th\u00e0nh chu\u1ed7i text nh\u01b0 b\u1ea1n mu\u1ed1n\nreturn {\n json: {\n output: JSON.stringify(finalObject)\n }\n};"
},
"typeVersion": 2
},
{
"id": "1edb4090-0a50-4534-9b9b-fe43cbc2a503",
"name": "Upload media",
"type": "@blotato/n8n-nodes-blotato.blotato",
"position": [
-480,
1424
],
"parameters": {
"resource": "media",
"useBinaryData": true
},
"credentials": {
"blotatoApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "af58fd15-ed8e-4e3d-a154-9afed6298596",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
560
],
"parameters": {
"color": 6,
"width": 1024,
"height": 576,
"content": "## Video Generation\nGenerate short video scenes from the video prompts and monitor rendering status.\nEach scene is processed independently before being merged into the final video.\n"
},
"typeVersion": 1
},
{
"id": "b38141d2-c511-4d92-b333-dd514963ff96",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1504,
1136
],
"parameters": {
"color": 6,
"width": 848,
"height": 672,
"content": "## Video Merge\nMerge all generated video scenes into a single final product review video.\nThis step prepares the video for publishing without manual editing.\n\n"
},
"typeVersion": 1
},
{
"id": "bcc9b865-edde-439f-9933-fe8a18e89601",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1504,
560
],
"parameters": {
"color": 7,
"width": 848,
"height": 576,
"content": "## Video Prompt Generation\nGenerate structured video prompts for each scene based on the product review script.\nEach prompt represents a short segment of the final product review video.\n\n"
},
"typeVersion": 1
},
{
"id": "d4789257-7f33-4e4f-867d-368569aaec9f",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
16
],
"parameters": {
"color": 7,
"width": 1024,
"height": 544,
"content": "## Image Generation\nGenerate AI-based product images using the structured image prompts.\nThese images are used as visual references for the video generation stage.\n\n"
},
"typeVersion": 1
},
{
"id": "2d1bea5b-208c-4ec0-b197-46ba85f7f5d0",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1504,
16
],
"parameters": {
"color": 6,
"width": 848,
"height": 544,
"content": "## Image Prompt Generation\nAnalyze the product image to extract visual context and generate structured image prompts.\nThese prompts are reused later to ensure visual consistency across generated scenes.\n"
},
"typeVersion": 1
},
{
"id": "22577962-9fc1-4a82-a6fa-cfbd201f44cb",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
1136
],
"parameters": {
"color": 7,
"width": 1024,
"height": 672,
"content": "## Publish & Log\nPublish the final video to social media platforms.\nPublishing results, including success and error states, are logged to Google Sheets for tracking.\n\n\n"
},
"typeVersion": 1
},
{
"id": "994a9248-118b-411f-8553-77ad2278759c",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2768,
0
],
"parameters": {
"width": 800,
"height": 848,
"content": "## \ud83d\udee0\ufe0f Workflow Setup Guide\n\nAuthor: [GiangxAI](https://www.youtube.com/@giangxai.official)\n\n## How it works\n\n- Submit a product image and basic product information through a form as the workflow input.\n- Analyze the product image to extract visual context, key features, and marketing angles.\n- Generate an AI-powered product review script and structured image/video prompts.\n- Create video scenes using Veo 3 and automatically merge them into a final review video.\n- Publish the video to social platforms and log success or errors to Google Sheets.\n\n## Setup steps\n\n1. Open the Form Submit trigger and review the required input fields.\n2. Add your AI model credentials (Gemini or OpenRouter) to the script and prompt generation nodes.\n3. Configure your image and video generation API keys (Veo 3 or compatible providers).\n4. Review the video merge node and ensure the ffmpeg or merge API endpoint is correctly set.\n5. Add your Blotato API credentials to enable social media publishing.\n6. Connect Google Sheets and select the sheet used for logging publishing results.\n\nOnce configured, activate the workflow to start generating and publishing AI product review videos automatically.\n\n\nYou can track publishing results using the sample [Google Sheet](https://docs.google.com/spreadsheets/d/1gzD2jSlznYENE_IwwW0o4Qe0ZbQTnkj3wi8dKixmEv0/edit?usp=sharing)\n"
},
"typeVersion": 1
},
{
"id": "5c6032e1-0b5c-4aeb-8a9f-9e497d1e86f7",
"name": "Product Image & Info Input",
"type": "n8n-nodes-base.formTrigger",
"position": [
-1744,
288
],
"parameters": {
"options": {},
"formTitle": "UCG VIDEO",
"formFields": {
"values": [
{
"fieldType": "file",
"fieldLabel": "Image"
},
{
"fieldLabel": "Video review description"
}
]
},
"formDescription": "Enter product images to generate content"
},
"typeVersion": 2.3
},
{
"id": "5a86273a-63b8-447d-9875-d54d78e0f1e0",
"name": "Analyze Product Image",
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"position": [
-1312,
288
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "models/gemini-3-pro-preview",
"cachedResultName": "models/gemini-3-pro-preview"
},
"options": {},
"resource": "image",
"inputType": "binary",
"operation": "analyze",
"binaryPropertyName": "Image"
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "5171befd-2ab5-4379-9bbe-6e7b323a0d54",
"name": "AI Prompt Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-1024,
288
],
"parameters": {
"text": "=Your task: Create an image creation prompt that adheres to your system's instructions.\n\nEnsure that the reference image is reproduced as accurately as possible in the generated images, especially the text.\n\nThis is a user-provided description:\n\n{{ $('Product Image & Info Input').item.json['M\u00f4 t\u1ea3 video review'] }}\n\n\nDescription of the reference image:\n\n{{ $json.content.parts[0].text }}",
"options": {
"systemMessage": "=VAI TR\u00d2\nB\u1ea1n l\u00e0 UGC Image Prompt Builder.\n\nM\u1ee4C TI\u00caU\nD\u1ef1a tr\u00ean \u1ea3nh tham chi\u1ebfu / \u1ea3nh s\u1ea3n ph\u1ea9m, h\u00e3y t\u1ea1o m\u1ed9t prompt m\u00f4 t\u1ea3 \u1ea3nh ng\u1eafn g\u1ecdn, t\u1ef1 nhi\u00ean \u0111\u1ec3 d\u00f9ng cho AI t\u1ea1o \u1ea3nh ho\u1eb7c video UGC \u0111\u1eddi th\u1ef1c.\n\n\u2699\ufe0f QUY T\u1eaeC CHUNG (B\u1eaeT BU\u1ed8C)\n\nPhong c\u00e1ch UGC ch\u00e2n th\u1eadt, nh\u01b0 \u1ea3nh/video quay b\u1eb1ng \u0111i\u1ec7n tho\u1ea1i.\n\nKh\u00f4ng d\u00e0n d\u1ef1ng, kh\u00f4ng \u00e1nh s\u00e1ng studio, kh\u00f4ng ng\u00f4n ng\u1eef qu\u1ea3ng c\u00e1o.\n\nCh\u1ea5p nh\u1eadn s\u1ef1 kh\u00f4ng ho\u00e0n h\u1ea3o: t\u00f3c con, n\u1ebfp nh\u0103n, texture da, n\u1ec1n h\u01a1i b\u1eeba b\u1ed9n.\n\nN\u1ebfu kh\u00f4ng c\u00f3 y\u00eau c\u1ea7u r\u00f5 \u2192 \u0111\u1eb7t s\u1ea3n ph\u1ea9m trong b\u1ed1i c\u1ea3nh \u0111\u1eddi th\u01b0\u1eddng h\u1ee3p l\u00fd.\n\nM\u1eccI CH\u1eee tr\u00ean bao b\u00ec/ph\u1ea7n hi\u1ec3n th\u1ecb ph\u1ea3i gi\u1eef nguy\u00ean 100% nh\u01b0 \u1ea3nh g\u1ed1c.\n\nTUY\u1ec6T \u0110\u1ed0I KH\u00d4NG b\u1ecba:\n\nch\u1ee9ng nh\u1eadn\n\ncon s\u1ed1\n\ntuy\u00ean b\u1ed1 marketing\n\nbadge / logo kh\u00f4ng c\u00f3 th\u1eadt\n\n\ud83d\udcf8 G\u1ee2I \u00dd PHONG C\u00c1CH M\u00c1Y \u1ea2NH\n\n(m\u1ed7i prompt d\u00f9ng \u00edt nh\u1ea5t 2\u20133 \u00fd)\n\n\u1ea3nh ch\u1ee5p \u0111i\u1ec7n tho\u1ea1i\n\nkhung h\u00ecnh c\u1ea7m tay\n\nb\u1ed1 c\u1ee5c l\u1ec7ch t\u00e2m\n\n\u00e1nh s\u00e1ng t\u1ef1 nhi\u00ean trong nh\u00e0\n\nb\u00f3ng \u0111\u1ed5 m\u1ec1m\n\nnh\u00f2e chuy\u1ec3n \u0111\u1ed9ng nh\u1eb9\n\nph\u01a1i s\u00e1ng t\u1ef1 \u0111\u1ed9ng\n\nphong c\u00e1ch ch\u01b0a ch\u1ec9nh s\u1eeda\n\nh\u1ea1t nhi\u1ec5u nh\u1eb9\n\n\ud83d\udeab GI\u1edaI H\u1ea0N\n\nKh\u00f4ng n\u00eau t\u00ean nh\u00e2n v\u1eadt c\u00f3 b\u1ea3n quy\u1ec1n.\n\nKh\u00f4ng vi\u1ebft h\u1ed9i tho\u1ea1i ho\u1eb7c k\u1ecbch b\u1ea3n.\n\nCh\u1ec9 xu\u1ea5t ra prompt t\u1ea1o \u1ea3nh.\n\n\ud83d\udce6 \u0110\u1ecaNH D\u1ea0NG \u0110\u1ea6U RA (B\u1eaeT BU\u1ed8C)\n\n\ud83d\udc49 Ch\u1ec9 tr\u1ea3 v\u1ec1 1 object JSON duy nh\u1ea5t, \u0111\u00fang c\u1ea5u tr\u00fac sau:\n\n{\n \"image_prompt\": \"M\u00f4 t\u1ea3 d\u1ea1ng v\u0103n xu\u00f4i (t\u1ed1i \u0111a 120 t\u1eeb), bao g\u1ed3m:\n - Ch\u1ee7 th\u1ec3 (ai)\n - H\u00e0nh \u0111\u1ed9ng (\u0111ang l\u00e0m g\u00ec)\n - C\u1ea3m x\u00fac / mood\n - B\u1ed1i c\u1ea3nh \u0111\u1eddi th\u1ef1c\n - Phong c\u00e1ch / m\u00e1y \u1ea3nh\n - M\u00e0u s\u1eafc t\u1ed5ng th\u1ec3\n - Ghi ch\u00fa \u0111\u1ed9 ch\u00ednh x\u00e1c ch\u1eef (gi\u1eef nguy\u00ean 100% text nh\u00ecn th\u1ea5y)\"\n}\n\n\ud83d\udc65 THI\u1ebeT L\u1eacP M\u1eb6C \u0110\u1ecaNH V\u1ec0 NH\u00c2N V\u1eacT\n\nN\u1ebfu kh\u00f4ng ch\u1ec9 \u0111\u1ecbnh: \u0111a d\u1ea1ng gi\u1edbi t\u00ednh & ch\u1ee7ng t\u1ed9c t\u1ef1 nhi\u00ean.\n\n\u0110\u1ed9 tu\u1ed5i m\u1eb7c \u0111\u1ecbnh: 21\u201338.\n\n\u01afu ti\u00ean kh\u00f4ng gian th\u1eadt: nh\u00e0, \u0111\u01b0\u1eddng ph\u1ed1, c\u1eeda h\u00e0ng, ph\u00f2ng gym, v\u0103n ph\u00f2ng.\n\n\u2705 CHECK TR\u01af\u1edaC KHI TR\u1ea2 K\u1ebeT QU\u1ea2\n\n C\u00f3 \u0111\u00fang 1 key image_prompt\n\n Kh\u00f4ng ng\u00f4n ng\u1eef qu\u1ea3ng c\u00e1o\n\n C\u00f3 y\u1ebfu t\u1ed1 \u0111\u1eddi th\u1ef1c, kh\u00f4ng ho\u00e0n h\u1ea3o\n\n C\u00f3 ghi ch\u00fa gi\u1eef nguy\u00ean ch\u1eef tr\u00ean s\u1ea3n ph\u1ea9m\n\n \u2264 120 t\u1eeb"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "61d6ed9c-cb12-478d-a007-db2ed6a58248",
"name": "Split Video Prompts",
"type": "n8n-nodes-base.splitOut",
"position": [
-896,
736
],
"parameters": {
"options": {},
"fieldToSplitOut": "output.scenes"
},
"typeVersion": 1
},
{
"id": "e001fc36-f200-4eb8-be2c-7fb4069a14e4",
"name": "Video Prompt Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-1072,
1008
],
"parameters": {
"autoFix": true,
"jsonSchemaExample": "{\n \"video_title\" : \"string\",\n \"video_description\": \"string\",\n \"scenes\": {\n \"scene_1\": {\n \"video_prompt\": \"string\"\n },\n \"scene_2\": {\n \"video_prompt\": \"string\"\n \n },\n \"scene_3\": {\n \"video_prompt\": \"string\"\n }\n}\n}"
},
"typeVersion": 1.3
},
{
"id": "9282cfe8-8b80-4425-8ef1-d3ce61ddd31d",
"name": "Create Video Prompt",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-1232,
736
],
"parameters": {
"text": "=Create a UGC-style video prompt based on the reference image and user description.\n\nUser description (can be left blank):\n{{ $json.input_text }}",
"options": {
"systemMessage": "=ROLE\nYou are a UGC Continuation Video Sequence Agent.\n\nYour job is to create a SEQUENCE of 3 short UGC ad videos (\u22488 seconds each)\nthat feel like ONE continuous real-life moment split into 3 clips \u2014\nNOT 3 separate or restarted videos.\n\nYou must think about all 3 scenes in a single pass and preserve:\n- motion continuity\n- body and hand state\n- camera rhythm\n- spoken dialogue continuity\n\n---\n\nCORE CONTINUITY RULES (CRITICAL)\n\n- Each scene must feel like the VERY NEXT MOMENT after the previous one.\n- This is NOT a restart.\n- Treat the reference image as PRE-CONTEXT, not the opening frame.\n- Do NOT start from a neutral pose or static framing.\n- Always start IN THE MIDDLE of an ongoing action or reaction.\n- Assume the same space, same outfit, same product, same general framing.\n- The camera is perceived as continuously rolling across scenes.\n\nIf any scene feels like it \u201cstarts over\u201d, it is WRONG.\n\n---\n\nVOICE RULES (EMBEDDED IN VIDEO PROMPT)\n\n- Spoken lines MUST be written INSIDE the video prompt.\n- All spoken dialogue MUST be in VIETNAMESE.\n- Voice sounds casual, unscripted, like self-talk or vlog speech.\n- Dialogue happens WHILE the action is ongoing.\n- No narration, no ad-speak, no exaggerated claims.\n\n---\n\nVIDEO TITLE (HOOK) \u2014 PAIN & NEED AWARENESS AND VIDEO DESCIPTION (REQUIRED)\n\nIn addition to the 3 scenes, you MUST generate ONE video title that acts as a\nscroll-stopping HOOK.\n\nHOOK OBJECTIVE\n- Clearly surface a real, relatable PROBLEM or PAIN the customer experiences.\n- Make the viewer think: \u201cThat\u2019s exactly me.\u201d\n- Trigger NEED awareness without mentioning any solution.\n\nTITLE REQUIREMENTS\n- Written in Vietnamese\n- Maximum 12 words\n- Casual, spoken language (inner thoughts, complaints, or self-questions)\n- Focus ONLY on the problem or its consequence\n- Do NOT mention the product or solution\n- No praise, no marketing tone, no CTA\n\nHOOK\u2013SCENE ALIGNMENT (CRITICAL)\n- The title represents the viewer\u2019s internal thought.\n- Scene 1 must visually and emotionally show that exact problem in real life.\n\nVideo Description Goals\n\n- Briefly summarize the problem, solution, and CTA\n- Quickly visualize the video content for the viewer\n- Arouse customer demand\n\nVideo Description Requirements\n\n- Written in Vietnamese\n\n- Maximum 120 words\n\n- Everyday, natural language\n\n---\n\nGLOBAL GOAL (3 \u00d7 8s)\n\nScene 1: Hook + personal reason for using the product \nScene 2: Active usage (proof of use) \nScene 3: After-use state + soft CTA \n\n---\n\nSCENE RESPONSIBILITIES\n\nSCENE 1 \u2014 HOOK + WHY\n- Start mid-action (already moving, reaching, adjusting, preparing).\n- Casually reveal a personal reason or small problem.\n- No demo.\n- No CTA.\n\nSCENE 2 \u2014 HOW / PROOF\n- Begin from the EXACT body and hand state where Scene 1 ended.\n- Show real usage in progress.\n- Spoken words describe what the person is doing, NOT benefits.\n\nSCENE 3 \u2014 RESULT + SOFT CTA\n- Begin from the after-use state of Scene 2.\n- Minimal action, relaxed posture.\n- Soft CTA phrased like a personal suggestion, NOT a sales pitch.\n\n---\n\nUGC VISUAL STYLE\n\n- Phone-shot, handheld feel\n- Natural or mixed indoor lighting\n- Slight motion blur or micro shake is acceptable\n- Product is visible but NEVER posed like a product shot\n\n---\n\nOUTPUT CONTRACT (STRICT)\n\nReturn ONLY ONE valid JSON object.\nDo NOT include any text outside the JSON.\n\nUse EXACTLY this structure:\n\n{\n \"video_title\": \"Pain-based hook in natural Vietnamese\",\n \"video_description\": \"Briefly summarize the problem, solution, and CTA\",\n \"scene_1\": {\n \"video_prompt\": \"Describe the scene starting mid-action, including camera movement, environment, body motion, AND embedded Vietnamese spoken dialogue in quotes, spoken naturally while the action continues.\"\n },\n \"scene_2\": {\n \"video_prompt\": \"Direct continuation of scene 1 with uninterrupted motion and framing, including embedded Vietnamese spoken dialogue describing the usage while it happens.\"\n },\n \"scene_3\": {\n \"video_prompt\": \"Continuation from the after-use state, calm ending, including embedded Vietnamese spoken dialogue with a soft, non-pushy CTA.\"\n }\n}\n\n---\n\nABSOLUTE PROHIBITIONS\n\n- No restarts\n- No neutral poses\n- No product re-introduction\n- No unboxing\n- No slogans or ad language\n- No claims or exaggerated benefits\n- No text outside the JSON\n"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "c542088d-a110-4142-993b-e67ecf387bf2",
"name": "Loop Video Prompts",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-560,
752
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "75910483-ea6d-4924-9f70-ea1ee59185cd",
"name": "Aggregate Videos",
"type": "n8n-nodes-base.aggregate",
"position": [
-1456,
1424
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "generated_video[0].video_url"
}
]
}
},
"typeVersion": 1
},
{
"id": "c26499cf-7ee1-4fd8-bc66-cda8ed83f384",
"name": "Merge Videos",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1040,
1424
],
"parameters": {
"url": "=https://no-code-architects-toolkit-1047852419409.us-west4.run.app/v1/video/concatenate",
"method": "POST",
"options": {
"redirect": {
"redirect": {}
}
},
"jsonBody": "={{ $json.output }}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "e63ca7d0-6689-45cc-bb24-1a608f40b916",
"name": "Download Video",
"type": "n8n-nodes-base.httpRequest",
"position": [
-848,
1424
],
"parameters": {
"url": "={{ $json.response }}",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "13678d8d-7c35-4119-bc0c-4c449d8b9109",
"name": "Log Success",
"type": "n8n-nodes-base.googleSheets",
"position": [
112,
1344
],
"parameters": {
"columns": {
"value": {
"Status": "Posted"
},
"schema": [
{
"id": "Ti\u00eau \u0111\u1ec1",
"type": "string",
"display": true,
"required": false,
"displayName": "Ti\u00eau \u0111\u1ec1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "M\u00f4 t\u1ea3 video",
"type": "string",
"display": true,
"required": false,
"displayName": "M\u00f4 t\u1ea3 video",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Link video",
"type": "string",
"display": true,
"required": false,
"displayName": "Link video",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1gzD2jSlznYENE_IwwW0o4Qe0ZbQTnkj3wi8dKixmEv0/edit#gid=0",
"cachedResultName": "Trang t\u00ednh1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1gzD2jSlznYENE_IwwW0o4Qe0ZbQTnkj3wi8dKixmEv0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1gzD2jSlznYENE_IwwW0o4Qe0ZbQTnkj3wi8dKixmEv0/edit?usp=drivesdk",
"cachedResultName": "Video Review"
}
},
"typeVersion": 4.7
},
{
"id": "adbcfadd-d392-4056-a0f6-54648573cd28",
"name": "Log Error",
"type": "n8n-nodes-base.googleSheets",
"position": [
128,
1552
],
"parameters": {
"columns": {
"value": {
"Status": "Error"
},
"schema": [
{
"id": "Ti\u00eau \u0111\u1ec1",
"type": "string",
"display": true,
"required": false,
"displayName": "Ti\u00eau \u0111\u1ec1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "M\u00f4 t\u1ea3 video",
"type": "string",
"display": true,
"required": false,
"displayName": "M\u00f4 t\u1ea3 video",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Link video",
"type": "string",
"display": true,
"required": false,
"displayName": "Link video",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1gzD2jSlznYENE_IwwW0o4Qe0ZbQTnkj3wi8dKixmEv0/edit#gid=0",
"cachedResultName": "Trang t\u00ednh1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1gzD2jSlznYENE_IwwW0o4Qe0ZbQTnkj3wi8dKixmEv0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1gzD2jSlznYENE_IwwW0o4Qe0ZbQTnkj3wi8dKixmEv0/edit?usp=drivesdk",
"cachedResultName": "Video Review"
}
},
"typeVersion": 4.7
},
{
"id": "4a08a365-318e-41c8-832c-ac5281567190",
"name": "Create post Facebook",
"type": "@blotato/n8n-nodes-blotato.blotato",
"onError": "continueErrorOutput",
"position": [
-288,
1424
],
"parameters": {
"options": {},
"platform": "facebook",
"accountId": {
"__rl": true,
"mode": "list",
"value": "15884",
"cachedResultUrl": "https://backend.blotato.com/v2/accounts/15884",
"cachedResultName": "Giang VT"
},
"facebookPageId": {
"__rl": true,
"mode": "list",
"value": "688227101036478",
"cachedResultUrl": "https://backend.blotato.com/v2/accounts/15884/subaccounts/688227101036478",
"cachedResultName": "Giang VT"
},
"postContentText": "={{ $('Product Image & Info Input').item.json['M\u00f4 t\u1ea3'] }}",
"postContentMediaUrls": "={{ $json.url }}"
},
"credentials": {
"blotatoApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "ae699705-e99d-4279-a21f-be0b6eeb92f1",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1872,
0
],
"parameters": {
"color": 7,
"width": 368,
"height": 576,
"content": "## Product input\n\nSubmit a product image and basic product information.\nThe workflow will generate, merge, and publish an AI product review video automatically.\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "a5212fcf-227b-4355-9760-2d30b11396e6",
"connections": {
"If1": {
"main": [
[
{
"node": "Loop Video Prompts",
"type": "main",
"index": 0
}
],
[
{
"node": "Wait1",
"type": "main",
"index": 0
}
]
]
},
"Wait1": {
"main": [
[
{
"node": "Get Videos",
"type": "main",
"index": 0
}
]
]
},
"Wait3": {
"main": [
[
{
"node": "Get Images",
"type": "main",
"index": 0
}
]
]
},
"Get Images": {
"main": [
[
{
"node": "Create Video Prompt",
"type": "main",
"index": 0
}
]
]
},
"Get Videos": {
"main": [
[
{
"node": "If1",
"type": "main",
"index": 0
}
]
]
},
"Merge Videos": {
"main": [
[]
]
},
"Upload media": {
"main": [
[
{
"node": "Create post Facebook",
"type": "main",
"index": 0
}
]
]
},
"Download Video": {
"main": [
[
{
"node": "Upload media",
"type": "main",
"index": 0
}
]
]
},
"AI Prompt Agent": {
"main": [
[
{
"node": "Generate Images",
"type": "main",
"index": 0
}
]
]
},
"Generate Images": {
"main": [
[
{
"node": "Wait3",
"type": "main",
"index": 0
}
]
]
},
"Generate Videos": {
"main": [
[
{
"node": "Wait1",
"type": "main",
"index": 0
}
]
]
},
"Aggregate Videos": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Merge Videos",
"type": "main",
"index": 0
}
]
]
},
"Loop Video Prompts": {
"main": [
[
{
"node": "Aggregate Videos",
"type": "main",
"index": 0
}
],
[
{
"node": "Generate Videos",
"type": "main",
"index": 0
}
]
]
},
"Create Video Prompt": {
"main": [
[
{
"node": "Split Video Prompts",
"type": "main",
"index": 0
}
]
]
},
"Split Video Prompts": {
"main": [
[
{
"node": "Loop Video Prompts",
"type": "main",
"index": 0
}
]
]
},
"Video Prompt Parser": {
"ai_outputParser": [
[
{
"node": "Create Video Prompt",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Create post Facebook": {
"main": [
[
{
"node": "Log Success",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Error",
"type": "main",
"index": 0
}
]
]
},
"Analyze Product Image": {
"main": [
[
{
"node": "AI Prompt Agent",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Prompt Agent",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Structured Output Parser1",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Google Gemini Chat Model1": {
"ai_languageModel": [
[
{
"node": "Create Video Prompt",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Video Prompt Parser",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser1": {
"ai_outputParser": [
[
{
"node": "AI Prompt Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Product Image & Info Input": {
"main": [
[
{
"node": "Analyze Product Image",
"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.
blotatoApigooglePalmApihttpHeaderAuth
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically creates AI product review videos from a product image and short description using n8n and Veo 3.
Source: https://n8n.io/workflows/12929/ — 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.
This Shopify AI automation is an advanced n8n-powered workflow that transforms Shopify product collections into SEO-optimized blog articles with images, while maintaining full visibility and control t
This workflow is designed for e-commerce, marketing teams, or creators who want to automate the production of high-quality, AI-generated product visuals and ad creatives.
Categories: Business Automation, Content Creation, SEO, AI
This workflow automates batch video publishing prep from a Google Drive folder with AI-generated, platform-specific copy and a simple approval queue in Google Sheets. Perfect for Agencies, content cre
This workflow transforms text-based resume data into visually stunning images by leveraging Google Gemini's reasoning and vision capabilities. It autonomously analyzes the candidate's profile, selects