Consistent AI UGC AD Video Agent in n8n - By Sohail
Shared 12/4/2025
7 views
Visual Workflow
JSON Code
{
"id": "srcw9nW8ho5QJ490",
"meta": {
"instanceId": "9fb634bb746cbe3fe9f7fa86fdd635510d2f0c24c4ba919fbba1ca6aec3c4e57",
"templateCredsSetupCompleted": true
},
"name": "AI Consistent UGC Character Ad Agent",
"tags": [
{
"id": "XZ2fZUKyIdD6LbGn",
"name": "Content Creation",
"createdAt": "2025-10-22T09:44:29.381Z",
"updatedAt": "2025-10-22T09:44:29.381Z"
}
],
"nodes": [
{
"id": "13e295b7-dc9e-483d-9abb-4928a9d90e97",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-128,
1792
],
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"typeVersion": 1.2
},
{
"id": "25bae00f-47e3-4222-8397-c0fe687b3d94",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-160,
1696
],
"parameters": {
"color": 7,
"width": 528,
"height": 480,
"content": "## Get Product Information And Video Instructions"
},
"typeVersion": 1
},
{
"id": "24067559-8f3b-4fdb-937b-3a3503afdb6a",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
-160,
2208
],
"parameters": {
"color": 5,
"width": 1504,
"height": 480,
"content": "## 📷 Generate UGC Image"
},
"typeVersion": 1
},
{
"id": "47d4053b-7d39-43d2-a870-f5cae46d03fd",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
-160,
2720
],
"parameters": {
"color": 5,
"width": 1504,
"height": 352,
"content": "## 🎥 Generate UGC Video"
},
"typeVersion": 1
},
{
"id": "11ef307d-0f02-4d2f-bd9e-fa9c15eac1a5",
"name": "Get Pending Videos",
"type": "n8n-nodes-base.googleSheets",
"position": [
192,
1792
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "Pending",
"lookupColumn": "Status"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PVFbX_DkGf8l-bFCWXkTi_oDGgtSjPkPbRoI_Ryi6Pw/edit#gid=0",
"cachedResultName": "Tasks"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1PVFbX_DkGf8l-bFCWXkTi_oDGgtSjPkPbRoI_Ryi6Pw",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PVFbX_DkGf8l-bFCWXkTi_oDGgtSjPkPbRoI_Ryi6Pw/edit?usp=drivesdk",
"cachedResultName": "Consistent UGC Character Ad Automation | Ai With Sohail"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "TB2tCNqF1GBm2ag8",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "b865aa46-d4d7-4aac-8c26-adaf486d0a0b",
"name": "If Response",
"type": "n8n-nodes-base.if",
"position": [
272,
3200
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "8a2caa94-db0d-4141-ab47-c803e69db7c9",
"operator": {
"type": "object",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.data.response }}",
"rightValue": "success"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "1ac04de1-60ae-47ce-a3cd-491174208356",
"name": "GPT 4.1 Mini",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
-112,
2544
],
"parameters": {
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "6z6zYFNsqyqFRUEB",
"name": "OpenRouter account"
}
},
"typeVersion": 1
},
{
"id": "d6b0196f-18fd-4538-b026-fa69909f1bdc",
"name": "Person With Product Image Generate",
"type": "n8n-nodes-base.httpRequest",
"position": [
448,
2288
],
"parameters": {
"url": "https://openrouter.ai/api/v1/chat/completions",
"method": "POST",
"options": {},
"jsonBody": "={\n \"model\": \"google/gemini-2.5-flash-image\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"{{ $json.output.replace(/\\r?\\n|\\r/g, ' ')\n .replace(/\"/g, '')\n .replace(/[“”]/g, '') }}\"\n },\n {\n \"type\": \"image_url\",\n \"image_url\": {\n \"url\": \"{{ $('Get Pending Videos').item.json['Product Photo'] }}\"\n }\n },\n {\n \"type\": \"image_url\",\n \"image_url\": {\n \"url\": \"{{ $('Get Pending Videos').item.json['Person Photo'] }}\"\n }\n }\n ]\n }\n ]\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "openRouterApi"
},
"credentials": {
"openRouterApi": {
"id": "6z6zYFNsqyqFRUEB",
"name": "OpenRouter account"
}
},
"typeVersion": 4.2
},
{
"id": "c8578d35-08d2-4baf-86f2-ad6deb23c533",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-112,
1984
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "2218c5df-1caf-4698-8b3d-390ba3c68cd9",
"name": "Get Video",
"type": "n8n-nodes-base.httpRequest",
"position": [
80,
3200
],
"parameters": {
"url": "https://api.kie.ai/api/v1/veo/record-info",
"options": {},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"queryParameters": {
"parameters": [
{
"name": "taskId",
"value": "={{ $('Veo Video').item.json.data.taskId }}"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"id": "CJk6wBwuTaqsL3Ij",
"name": "Kie Auth"
}
},
"typeVersion": 4.2
},
{
"id": "085f699e-87c2-4ce6-ad2d-6bb17f358b3f",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-160,
3104
],
"parameters": {
"color": 5,
"width": 832,
"height": 288,
"content": "## 🎥 Check Video And Send Update"
},
"typeVersion": 1
},
{
"id": "76049d0b-b221-4d69-b93a-4ababfef6f6b",
"name": "Veo Video Prompt",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
64,
2816
],
"parameters": {
"text": "={{ $json.combined }}\n---\nFirst Frame:\n{{ $json.startFrame.prompt }}\nLast Frame:\n{{ $json.endFrame.prompt }}",
"options": {
"systemMessage": "=You are an expert UGC video prompt composer for Google VEO3.\nYour job is to generate a single, complete selfie-style UGC video prompt for VEO3 based on:\n\nTarget Audience\n\nProduct Name\n\nProduct Description\n\nICP (Ideal Customer Profile)\n\nPerson Name\n\nPerson Description\n\nVideo Instructions / Scenario\n\nOrientation (provided in user prompt)\n\nOne merged reference image containing person + product\n\nYour final output must be a natural, influencer-style selfie video prompt that VEO3 can use directly.\n\nYou must write content that naturally fits an 8-second performance, even though the final output must not mention duration.\n\nThis prompt must be strictly safe for work, containing zero erotic, sexual, suggestive, revealing, or intimate elements.\n\n✔ SAFETY REQUIREMENT (CRITICAL)\n\nThe generated prompt must be fully non-erotic, meaning:\n\nNo sexual themes\n\nNo sensuality\n\nNo intimacy\n\nNo provocative poses\n\nNo revealing clothing\n\nNo descriptions of body parts in a sexual or suggestive way\n\nNo flirting or romantic undertones\n\nNo adult themes\n\nThe prompt MUST read like a clean, normal, everyday influencer video intended for all audiences.\n\n✔ Goals\n\nProduce a realistic UGC selfie video prompt\n\nMaintain consistency with the reference image\n\nEnsure the person & product match the reference\n\nKeep the tone friendly, authentic, and safe\n\nPhone must never appear on screen\n\nVideo feels casual and natural\n\nFits an 8-second script (implicitly)\n\n✔ Requirements\n1. Subject & Framing\n\nThe subject is the person described in the ICP\n\nHolds or interacts with the product\n\nShot is selfie-style at arm’s length\n\nLooks directly into the camera\n\nSlight natural handheld shake\n\nMust follow user-provided orientation (e.g., “vertical 9:16”)\n\n2. Visual Style\n\nNatural lighting\n\nRealistic environment that matches the scenario\n\nSubtle imperfections (slight wobble, soft grain, natural breathing movement)\n\nFace and product always visible\n\nClothing must be normal, everyday, modest, non-provocative\n\nNo phone, reflections, overlays, subtitles, text or logos\n\n3. Tone & Dialogue\n\nThe subject speaks 1–2 casual sentences that:\n\nFit an 8-second delivery\n\nAre friendly and natural\n\nHighlight one product benefit\n\nSound personal, honest, and relatable\n\nAre completely non-erotic\n\n4. Technical Specs\n\nSelfie handheld shot\n\nUser-specified orientation\n\nReference image used ONLY for style consistency (never mentioned)\n\n✔ Embedded Components Required\n\nYour final VEO3 prompt must include:\n\nICP persona (age, gender, vibe, clothing, demeanor)\n\nProduct look and how it’s held\n\nOne highlighted benefit\n\nSetting/environment\n\nLighting style\n\nCamera style (selfie handheld, slight shake)\n\n1–2 short spoken sentences\n\nExplicit orientation\n\nSafety-compliant, non-erotic expressions only\n\n✔ Output Format (CRITICAL)\n\nYour output must be ONLY the VEO3 prompt text, nothing else.\n\nNo markdown\n\nNo tags\n\nNo explanation\n\nNo labels\n\nNo JSON\n\nNo duration mentioned\n\nNo unsafe content\n\nJust the final clean prompt string.\n\n⭐ Sample Prompts (For Reference Inside System Prompt Only)\n\n(Do NOT mention these samples in your actual output; they are only for the model to learn style.)\n\nSample 1 – Skincare Product\n\n“A vertical 9:16 selfie-style video of a young woman in her bedroom holding a small skincare serum bottle. Natural morning light fills the room as she smiles warmly into the camera, her expression relaxed and friendly. She lifts the serum slightly and says, ‘This has been making my skin feel so much calmer lately—super easy to add to my routine.’ Subtle handheld shake, soft shadows, cozy background, and a modest casual outfit that matches her everyday look.”\n\nSample 2 – Fitness Gummies\n\n“A vertical 9:16 handheld selfie shot of a young man standing in a gym hallway holding a pack of fitness gummies. The lighting is bright and natural, with ambient gym sounds in the background. He looks directly at the camera and says, ‘These gummies have been helping me stay consistent after workouts—I love how simple they are.’ Slight camera wobble and clear visibility of both his face and the product.”\n\nSample 3 – Beverage Product\n\n“A vertical 9:16 selfie video of a woman in her kitchen holding a canned drink. She smiles at the camera, gently lifting the can, and says, ‘This tastes amazing and keeps me going through my workday.’ Quiet, clean kitchen background, soft natural lighting, and small natural movements from handheld filming.”"
},
"promptType": "define"
},
"typeVersion": 2.2
},
{
"id": "82d9ccf0-f538-4412-bc57-0434c9aa4125",
"name": "Veo Video",
"type": "n8n-nodes-base.httpRequest",
"position": [
560,
2816
],
"parameters": {
"url": "https://api.kie.ai/api/v1/veo/generate",
"method": "POST",
"options": {},
"jsonBody": "={{ $json.body }}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "CJk6wBwuTaqsL3Ij",
"name": "Kie Auth"
}
},
"typeVersion": 4.2
},
{
"id": "bd55e3e9-ba02-4fb2-a649-d1e0fbc33aff",
"name": "Frame Images Prompt",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-112,
2288
],
"parameters": {
"text": "={{ $json.combined }}\n\nmake to sure to keep clothese consistent!",
"options": {
"systemMessage": "=You are an AI prompt generator whose job is to produce two perfect NanoBanana-compatible text-to-image prompts:\none Start Frame and one End Frame.\n\nThese will serve as the starting and ending frames for VO3/Sora video generation.\n\nYou will be given the following inputs:\n\nTarget Audience\n\nProduct Name\n\nProduct Description\n\nVideo Instructions\n\nPerson Name\n\nPerson Description\n\nAspect Ratio\n\nA single Character Image (reference)\n\nA single Product Image (reference)\n\nYour task is to generate two complete NanoBanana prompts, each containing:\n\nFull scene description\n\nCharacter consistency rules implicitly applied\n\nProduct accuracy\n\nSetting, pose, lighting, mood\n\nTarget audience influence\n\nUGC-style composition\n\nPainting-safe style if required\n\nA negative prompt included at the end of the same string, like this:\n--negative <negative prompt text>\n\nImportant Rules & Requirements\n1. Character Consistency\n\nThe character must match the reference image exactly\n\nMaintain facial features, skin tone, hairstyle, body proportions, identity\n\nRefer to them as “the character from the provided image”\n\n2. Product Accuracy\n\nThe product must match the reference image exactly\n\nShape, color, label, material, branding\n\nRefer to it as “the product from the provided image”\n\n3. Scene Creation\n\nUse the video instructions to design:\n\nSetting\n\nPose\n\nAction\n\nComposition\n\nMood\n\nCamera style (optional but encouraged)\n\nLighting\n\nTarget audience energy\n\n4. Start Frame vs End Frame\n\nYour two outputs must represent two different moments in the same narrative.\n\nStart Frame — intro or starting action\n\nEnd Frame — final moment, payoff, conclusion, expression shift, or post-action\n\n5. Output Format (Critical)\n\nYour output must be ONLY an array of two strings:\n\n[\n \"<full prompt for start frame, including negative prompt at the end>\",\n \"<full prompt for end frame, including negative prompt at the end>\"\n]\n\n\nNo objects\n\nNo keys\n\nNo wrappers\n\nNo extra text\n\nNo commentary\n\nEach string must end with a negative prompt, e.g.:\n\n--negative photorealism, wrong face, distorted hands, altered product, extra people, artifacts, hallucinated objects\n\n6. Output ONLY the array of strings\n\nNo explanations.\nNo commentary.\nNo additional text."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "1a0ce7e5-46ff-4c1f-9270-09b744d59b5b",
"name": "JSON Schema for Two-Frame NanoBanana Prompt Output",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
112,
2528
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"title\": \"TwoFrameNanoBananaPromptStrings\",\n \"type\": \"array\",\n \"minItems\": 2,\n \"maxItems\": 2,\n \"items\": {\n \"type\": \"string\",\n \"description\": \"A full NanoBanana prompt including the negative prompt appended at the end.\"\n }\n}\n"
},
"typeVersion": 1.3
},
{
"id": "0b140a6a-8dbd-4cd2-b977-a10106dbed5d",
"name": "Video Gen Body",
"type": "n8n-nodes-base.code",
"position": [
368,
2816
],
"parameters": {
"jsCode": "const aspect = $('Format Frames').first().json.aspectRatio \nconst aspectRatio = aspect === 'Portrait' ? \"9:16\" : \"16:9\"\nconst startFrameImage = $('Format Frames').first().json.startFrame.image\nconst endFrameImage = $('Format Frames').first().json.endFrame.image\nconst prompt = $input.first().json.output\n .replace(/\\r?\\n|\\r/g, ' ')\n .replace(/\"/g, '')\n .replace(/[“”]/g, '') \n\nconst body = {\n \"prompt\": prompt,\n \"imageUrls\": [\n startFrameImage,\n endFrameImage\n ],\n \"model\": \"veo3_fast\",\n \"aspectRatio\": aspectRatio,\n \"enableFallback\": false,\n \"enableTranslation\": true,\n \"generationType\": \"FIRST_AND_LAST_FRAMES_2_VIDEO\"\n}\n\n\nreturn {\n body\n}"
},
"typeVersion": 2
},
{
"id": "c18ff97c-331a-4288-b5e9-ed3257072742",
"name": "Format Frames",
"type": "n8n-nodes-base.code",
"position": [
-112,
2816
],
"parameters": {
"jsCode": "const input = $input.all().map(i=>i.json)\nconst output = {\n startFrame: input[0],\n endFrame: input[1],\n combined: input[0].combined,\n aspectRatio: input[0].aspectRatio,\n rowNumber: input[0].rowNumber\n}\nreturn output"
},
"typeVersion": 2
},
{
"id": "dd0baeb5-f669-455e-a46d-0258e0ea841b",
"name": "Split Out",
"type": "n8n-nodes-base.splitOut",
"position": [
224,
2288
],
"parameters": {
"options": {},
"fieldToSplitOut": "output"
},
"typeVersion": 1
},
{
"id": "38f49bbd-cfc5-49e8-82b8-acc867c37521",
"name": "Row Data",
"type": "n8n-nodes-base.set",
"position": [
192,
2000
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a13575f3-820a-4f0d-ae7a-b9c5dc65870a",
"name": "combined",
"type": "string",
"value": "=Target Audience: {{ $('Get Pending Videos').item.json['Target Audience'] }}\nProduct Name: {{ $('Get Pending Videos').item.json['Product Name'] }}\nProduct Description: {{ $('Get Pending Videos').item.json['Product Description'] }}\nVideo Instructions: {{ $('Get Pending Videos').item.json['Video Instructions'] }}\nPerson Name: {{ $('Get Pending Videos').item.json['Person Name'] }}\nPerson Description: {{ $('Get Pending Videos').item.json['Person Description'] }}\nAspect Ratio: {{ $('Get Pending Videos').item.json['Aspect Ratio'] }}"
},
{
"id": "cb7c04e7-166c-4c97-888c-6ea40ec25aec",
"name": "aspectRatio",
"type": "string",
"value": "={{ $('Get Pending Videos').item.json['Aspect Ratio'] }}"
},
{
"id": "b0529d64-a9fb-412e-90ba-50b88d27a740",
"name": "rowNumber",
"type": "string",
"value": "={{ $('Get Pending Videos').item.json.row_number }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "8b36c2e7-d8ee-4a3b-841e-9725ff8fb5f5",
"name": "Row Data F. Image",
"type": "n8n-nodes-base.set",
"position": [
944,
2288
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "ed4d08b5-8ccf-4878-bccf-85bb87e8fb97",
"name": "prompt",
"type": "string",
"value": "={{ $('Split Out').item.json.output }}"
},
{
"id": "cde905fa-2eb9-4092-ac11-a5a55274dd67",
"name": "image",
"type": "string",
"value": "={{ $json.data.downloadUrl }}"
},
{
"id": "83893ae4-ab29-44ba-b0ae-c1912d0eac5e",
"name": "combined",
"type": "string",
"value": "={{ $('Row Data').item.json.combined }}"
},
{
"id": "915feaa3-dc89-4883-a57b-b6e674145068",
"name": "aspectRatio",
"type": "string",
"value": "={{ $('Row Data').item.json.aspectRatio }}"
},
{
"id": "1b7c95a9-91ea-4e8b-8c54-556a69f1b4f5",
"name": "rowNumber",
"type": "string",
"value": "={{ $('Row Data').item.json.rowNumber }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "8d81c728-848c-4217-b7ec-cbfa8b5507c7",
"name": "If Video Gen Error",
"type": "n8n-nodes-base.if",
"position": [
752,
2816
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "22ef4bfc-0c11-4326-8f53-0bd64c913ddb",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.code }}",
"rightValue": 400
}
]
}
},
"typeVersion": 2.2
},
{
"id": "371a9418-89f0-4e92-884b-4c48057cd1ee",
"name": "If Video Gen Internal Error",
"type": "n8n-nodes-base.if",
"position": [
944,
2832
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a179d758-83ac-461b-ac8d-2b2489382dcf",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.data.errorCode }}",
"rightValue": 400
}
]
}
},
"typeVersion": 2.2
},
{
"id": "b6cf705e-f269-4674-b39b-7e28afb40906",
"name": "Upload Image",
"type": "n8n-nodes-base.httpRequest",
"position": [
688,
2288
],
"parameters": {
"url": "https://kieai.redpandaai.co/api/file-base64-upload",
"method": "POST",
"options": {},
"sendBody": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "base64Data",
"value": "={{ $json.choices[0].message.images[0].image_url.url }}"
},
{
"name": "uploadPath",
"value": "images/base64"
},
{
"name": "fileName",
"value": "{{Math.floor(Math.random()*999999999)}}_image.png"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "CJk6wBwuTaqsL3Ij",
"name": "Kie Auth"
}
},
"typeVersion": 4.2
},
{
"id": "5fb786da-d1f7-4cb2-8938-6a264120e3f8",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"position": [
-112,
3200
],
"webhookId": "333c32ae-acd3-4a2b-899a-af2016087609",
"parameters": {
"unit": "minutes",
"amount": 1
},
"typeVersion": 1.1
},
{
"id": "7599a941-ba12-45b9-8c98-56bf859a21f7",
"name": "Update Row: Failed",
"type": "n8n-nodes-base.googleSheets",
"position": [
1200,
2896
],
"parameters": {
"columns": {
"value": {
"Status": "Failed",
"row_number": "={{ $('Row Data F. Image').item.json.rowNumber }}"
},
"schema": [
{
"id": "No",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "No",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Video Instructions",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Video Instructions",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Aspect Ratio",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Aspect Ratio",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Product Name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Product Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Product Photo",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Product Photo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Target Audience",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Target Audience",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Product Description",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Product Description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Person Name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Person Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Person Photo",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Person Photo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Person Description",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Person Description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "UGC Video",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "UGC Video",
"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/1PVFbX_DkGf8l-bFCWXkTi_oDGgtSjPkPbRoI_Ryi6Pw/edit#gid=0",
"cachedResultName": "Tasks"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1PVFbX_DkGf8l-bFCWXkTi_oDGgtSjPkPbRoI_Ryi6Pw",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PVFbX_DkGf8l-bFCWXkTi_oDGgtSjPkPbRoI_Ryi6Pw/edit?usp=drivesdk",
"cachedResultName": "Consistent UGC Character Ad Automation | Ai With Sohail"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "TB2tCNqF1GBm2ag8",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "8f6863e7-7717-49a1-88e7-aa643d51eba3",
"name": "Update Row: Completed",
"type": "n8n-nodes-base.googleSheets",
"position": [
480,
3184
],
"parameters": {
"columns": {
"value": {
"Status": "Completed",
"UGC Video": "={{ $json.data.response.resultUrls[0] }}",
"row_number": "={{ $('Format Frames').item.json.rowNumber }}"
},
"schema": [
{
"id": "No",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "No",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Product",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Product",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Product Photo",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Product Photo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Target Audience",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Target Audience",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Product Description",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Product Description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Video Instructions",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Video Instructions",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "UGC Video",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "UGC Video",
"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/1PVFbX_DkGf8l-bFCWXkTi_oDGgtSjPkPbRoI_Ryi6Pw/edit#gid=0",
"cachedResultName": "Tasks"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1PVFbX_DkGf8l-bFCWXkTi_oDGgtSjPkPbRoI_Ryi6Pw",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PVFbX_DkGf8l-bFCWXkTi_oDGgtSjPkPbRoI_Ryi6Pw/edit?usp=drivesdk",
"cachedResultName": "Consistent UGC Character Ad Automation | Ai With Sohail"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "TB2tCNqF1GBm2ag8",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "04908a91-4950-4e20-a623-c2fda6caef78",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-864,
1696
],
"parameters": {
"width": 672,
"height": 1520,
"content": "# 🛠️ Setup Guide \n\n## **Author: [Sohail Jafri](https://link.thesohailjafri.me/web_ai) | [Youtube](https://link.thesohailjafri.me/yt_ai) | [Instagram](https://link.thesohailjafri.me/ig_ai) | [Join Skool](https://link.thesohailjafri.me/join-skool)**\n\n### Follow the steps below to get your **AI Consistent UGC Character Ad Agent**:\n---\n\n### ✅ Step 1: Copy the Google Sheet Template \nThis workflow pulls tasks from a Google Sheet labeled **Tasks**.\n\n📄 **Google Sheet Template:** \n👉 https://docs.google.com/spreadsheets/d/1PVFbX_DkGf8l-bFCWXkTi_oDGgtSjPkPbRoI_Ryi6Pw/copy\n\n**Google Sheets Nodes:** \n- **Get Pending Videos** \n- **Update Row: Completed** \n- **Update Row: Failed** \n- **Row Data / Row Data F. Image** \n\nEach requires: \n- **Google Sheets OAuth2** credential \n:contentReference[oaicite:0]{index=0}\n\n**Required Sheet Columns:** \n`Product Name`, `Product Description`, `Product Photo`, `Person Name`, `Person Photo`, `Person Description`, \n`Target Audience`, `Video Instructions`, `Aspect Ratio`, `Status`, `UGC Video`, `row_number`\n\n---\n\n### ✅ Step 2: Connect Your OpenRouter API \nOpenRouter is used for model prompting inside:\n\n- **GPT 4.1 Mini** \n- **Frame Images Prompt** \n- **Veo Video Prompt** \n\nCredential needed: \n- **OpenRouter account** \n:contentReference[oaicite:1]{index=1}\n\n---\n\n### ✅ Step 3: Add Your Kie.AI API Key \nKie AI is used for generating VEO videos and checking task status.\n\n**Nodes using Kie Auth:** \n- **Veo Video** (`/api/v1/veo/generate`) \n- **Get Video** (`/api/v1/veo/record-info`) \n- **Upload Image** (`/api/file-base64-upload`) \n\nCredential required: \n- **Kie Auth (HTTP Header Auth)** \n:contentReference[oaicite:2]{index=2}\n\n---\n\n### ✅ Step 4: Verify Other Node Logic \nNo credentials needed for these, but they control core logic:\n\n- **Split Out** \n- **Format Frames** \n- **Video Gen Body** \n- **Loop Over Items** \n- **If Response / If Video Gen Error / If Video Gen Internal Error** \n- **Wait (1 min retry loop)** \n\n"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "058e4631-43ba-4906-8f62-90a9b8140b89",
"connections": {
"Wait": {
"main": [
[
{
"node": "Get Video",
"type": "main",
"index": 0
}
]
]
},
"Row Data": {
"main": [
[
{
"node": "Frame Images Prompt",
"type": "main",
"index": 0
}
]
]
},
"Get Video": {
"main": [
[
{
"node": "If Response",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "Person With Product Image Generate",
"type": "main",
"index": 0
}
]
]
},
"Veo Video": {
"main": [
[
{
"node": "If Video Gen Error",
"type": "main",
"index": 0
}
]
]
},
"If Response": {
"main": [
[
{
"node": "Update Row: Completed",
"type": "main",
"index": 0
}
],
[
{
"node": "If Video Gen Error",
"type": "main",
"index": 0
}
]
]
},
"GPT 4.1 Mini": {
"ai_languageModel": [
[
{
"node": "Frame Images Prompt",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Veo Video Prompt",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Upload Image": {
"main": [
[
{
"node": "Row Data F. Image",
"type": "main",
"index": 0
}
]
]
},
"Format Frames": {
"main": [
[
{
"node": "Veo Video Prompt",
"type": "main",
"index": 0
}
]
]
},
"Video Gen Body": {
"main": [
[
{
"node": "Veo Video",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Row Data",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get Pending Videos",
"type": "main",
"index": 0
}
]
]
},
"Veo Video Prompt": {
"main": [
[
{
"node": "Video Gen Body",
"type": "main",
"index": 0
}
]
]
},
"Row Data F. Image": {
"main": [
[
{
"node": "Format Frames",
"type": "main",
"index": 0
}
]
]
},
"Get Pending Videos": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"If Video Gen Error": {
"main": [
[
{
"node": "Update Row: Failed",
"type": "main",
"index": 0
}
],
[
{
"node": "If Video Gen Internal Error",
"type": "main",
"index": 0
}
]
]
},
"Update Row: Failed": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Frame Images Prompt": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"Update Row: Completed": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"If Video Gen Internal Error": {
"main": [
[
{
"node": "Update Row: Failed",
"type": "main",
"index": 0
}
],
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Person With Product Image Generate": {
"main": [
[
{
"node": "Upload Image",
"type": "main",
"index": 0
}
]
]
},
"JSON Schema for Two-Frame NanoBanana Prompt Output": {
"ai_outputParser": [
[
{
"node": "Frame Images Prompt",
"type": "ai_outputParser",
"index": 0
}
]
]
}
}
}