This workflow corresponds to n8n.io template #10175 — we link there as the canonical source.
This workflow follows the Agent → 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 →
{
"id": "pUSSmWHjoH7Vl0pv",
"name": "\u2705 Viral Reels Factory",
"tags": [],
"nodes": [
{
"id": "45400d45-c09e-432e-9ad9-819fa5db5b56",
"name": "Get Past Objects",
"type": "n8n-nodes-base.googleSheets",
"position": [
224,
416
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hNzWblAWsI_5u4RUK7kC3tSbR9riex94ZUuslhhDb8o/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1hNzWblAWsI_5u4RUK7kC3tSbR9riex94ZUuslhhDb8o",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hNzWblAWsI_5u4RUK7kC3tSbR9riex94ZUuslhhDb8o/edit?usp=drivesdk",
"cachedResultName": "VEO ASMR"
}
},
"typeVersion": 4.6
},
{
"id": "e7530bf8-e164-4357-b37e-c1a6c7cd2bf8",
"name": "Prompt Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1296,
416
],
"parameters": {
"text": "={{ $json.output.object }}",
"options": {
"systemMessage": "=# Overview \nYou are an AI agent that specializes in generating text-to-video prompts optimized for ASMR-style videos using Google Veo 3. \n\nYou will receive the name of a fruit-shaped glass object (e.g. \"glass apple\", \"glass mango\", \"glass croissant\"). Your task is to generate a hyper-realistic, sensory-rich video prompt of that object being gently and artistically divided in a controlled, CGI-rendered simulation.\n\n---\n\n## Policy Compliance Reminder (CRITICAL):\n\nTo ensure your prompt is accepted and not filtered out by Google Veo, you **must follow these safety guidelines**:\n\n- The scene must depict a **fully stylized digital animation**. It must be clearly artificial, artistic, and safe.\n- Do **not** say the object is being \u201ccut,\u201d \u201csliced,\u201d \u201cshattered,\u201d \u201ccleaved,\u201d or \u201cstabbed.\u201d These words are policy triggers.\n- Instead, describe the object as made from a **resin-like material that mimics glass** and emphasize **pre-designed seams or grooves**.\n- The object should appear to **separate or open smoothly** as part of an animation, not through destructive force.\n- You may include a \u201cblade\u201d or \u201ctool\u201d only if it is described as sleek, polished, choreographed, and interacting with pre-defined lines in the object.\n- Avoid all aggressive words like \u201csnap,\u201d \u201cpierce,\u201d \u201cstrike,\u201d or \u201cbreak.\u201d\n- Reassure at the end that this is **100% CGI, digitally rendered, with no physical tools or real materials involved**.\n\n---\n\n## Core Requirements:\n\n- The video must feel cinematic, photorealistic, and calming.\n- Framing: 9:16 vertical. The object should fill most of the vertical space.\n- Scene: Static vertical close-up of a dark walnut cutting board and a fruit-shaped resin object with subtle translucency and color.\n- The object should be described as **amber, ruby, or emerald-colored resin** \u2014 not literal glass.\n- A **polished steel blade** may appear, but it must move gracefully and along a **pre-designed groove**.\n- The action must be safe, simulated, and elegant. No force or destruction implied.\n- Include four ASMR sound layers:\n 1. A soft tonal contact as the blade touches the surface \n 2. A smooth glide sound as the form divides \n 3. A muted wooden note as the tool completes its motion \n 4. A light chime as the separated piece rests on the board \n- Keep language soft, immersive, and artistic.\n\n---\n\n## Prompt Output Format:\n\n**Subject**: A sculpted fruit form resembling a [object], made from a colored, semi-translucent resin that mimics glass, rests on a dark walnut cutting board, framed in vertical 9:16. \n**Setting**: Static vertical close-up, lit softly from above. Gentle light glides over the board\u2019s surface and the object\u2019s colored curves. \n**Action**: A sleek, polished steel blade enters from the top right. In a graceful, choreographed motion, the blade glides along a pre-designed groove in the resin form. The material responds with a controlled, simulated separation, revealing a smooth, inner core. There are no splinters, no breakage \u2014 only a seamless division along internal seams designed for the animation. \n**Style**: Stylized CGI realism. Every surface is rendered with photographic precision, but the entire scene is clearly artificial, safe, and elegant. \n**Sound**: Four clean ASMR layers: \n1. A crisp tone as the blade contacts the smooth resin \n2. A subtle glide as the form separates \n3. A soft wooden note as the blade rests \n4. A delicate chime as the separated half settles onto the board \n**Camera Motion**: Locked-off 9:16 composition. Focus shifts gently from the tool\u2019s edge to the exposed interior. \n**Composition**: The object is centered vertically. The blade enters cleanly from the top. No hands are visible. \n**Ambiance**: No music, no speech \u2014 just layered, quiet cutting sounds in a controlled environment. \n\nThis is a digitally rendered simulation \u2014 no real glass, tools, or objects are shown. The scene is entirely safe, artistic, and stylized for ASMR effect.\n"
},
"promptType": "define"
},
"typeVersion": 2
},
{
"id": "f7f6370e-f9bd-48d3-a5db-e695fd9c2048",
"name": "Idea Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
896,
416
],
"parameters": {
"text": "=Objects: {{ $json.objects.join(\", \") }}",
"options": {
"systemMessage": "=# Overview \nYou are an AI agent that selects unique **fruits** for ASMR-style glass cutting videos.\n\n## Your Task \nYou will receive a list of 7 fruits that have already been used. \nYour job is to generate **one new fruit** that is **not on that list**, and would look visually compelling if it were made of **glass** and cut with a knife in a close-up ASMR video.\n\n## Requirements\n- The fruit must **not repeat** any of the 7 provided items. \n- The fruit must have a **clear, recognizable shape** and be **physically feasible** to cut with a knife (even if it\u2019s made of glass). \n- Prioritize fruits that would look **aesthetic and interesting** with a translucent, colored glass texture. \n- Do **not** explain or describe the fruit.\n\n## Output Format \nOutput a JSON object with the following structure:\n\n{\n \"object\": \"Glass [Object name]\",\n \"caption\": \"Glass [Object name] ASMR\"\n}\n\nReplace `[object name]` with the newly generated fruit. Do not include any punctuation or commentary.\n\n## Example Output \n{\n \"object\": \"Glass Apple\",\n \"caption\": \"Glass Apple ASMR\"\n}"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2
},
{
"id": "5778efac-9d2f-4647-baab-c58859139eca",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
448,
416
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
},
{
"id": "ac1edde2-1fd2-4934-a07d-330446fb95ba",
"name": "Set Object List",
"type": "n8n-nodes-base.set",
"position": [
672,
416
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "cf818c10-ad6d-4349-830f-393529a79d62",
"name": "objects",
"type": "array",
"value": "=[\"{{ $json.data[0].object }}\",\"{{ $json.data[1].object }}\"]"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "8bc3c143-c420-405b-994a-cdfcb7e23193",
"name": "Object & Caption",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1056,
640
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"object\": {\n \"type\": \"string\",\n \"description\": \"A new object name in the format 'glass [object]', all lowercase with no punctuation.\"\n },\n \"caption\": {\n \"type\": \"string\",\n \"description\": \"A caption in the format 'glass [object] ASMR', matching the object field exactly.\"\n }\n },\n \"required\": [\"object\", \"caption\"]\n}"
},
"typeVersion": 1.3
},
{
"id": "7f96f17f-c901-42b5-9a70-ad18a6056f1f",
"name": "When clicking \u2018Execute workflow\u2019",
"type": "n8n-nodes-base.manualTrigger",
"position": [
0,
416
],
"parameters": {},
"typeVersion": 1
},
{
"id": "7fbb0979-6e84-433f-9a19-279b9f4e6f3b",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
928,
640
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {}
},
"typeVersion": 1.2
},
{
"id": "10073bf9-c998-47dd-9c34-91d9cc3c1455",
"name": "SET",
"type": "n8n-nodes-base.set",
"position": [
1696,
416
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "84fea8d5-e7cc-4519-963f-d2ae988337b5",
"name": "PROJECT_ID",
"type": "string",
"value": ""
},
{
"id": "1c227cbf-eb4a-4cb6-b13a-64900385a0e8",
"name": "CLIENT_EMAIL",
"type": "string",
"value": ""
},
{
"id": "d2e61510-9510-46e7-9025-82b3e5825ed7",
"name": "LOCATION_ID",
"type": "string",
"value": "us-central1"
},
{
"id": "050b1715-4fb9-4c60-9e14-ef07da4cd3e9",
"name": "API_ENDPOINT",
"type": "string",
"value": "us-central1-aiplatform.googleapis.com"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "6968fc32-9cde-4810-9e33-bdf0fdb82684",
"name": "JWT",
"type": "n8n-nodes-base.jwt",
"position": [
1920,
416
],
"parameters": {
"options": {},
"useJson": true,
"claimsJson": "={\n \"iss\": \"{{ $json.CLIENT_EMAIL }}\",\n \"scope\": \"https://www.googleapis.com/auth/cloud-platform\",\n \"aud\": \"https://www.googleapis.com/oauth2/v4/token\",\n \"exp\": {{ Math.floor(Date.now() / 1000) + 3500 }},\n \"iat\": {{ Math.floor(Date.now() / 1000) }}\n}\n"
},
"typeVersion": 1
},
{
"id": "20094117-b83a-49c3-b3a9-fdd4a74f5fec",
"name": "GET TOKEN",
"type": "n8n-nodes-base.httpRequest",
"position": [
2144,
416
],
"parameters": {
"url": "https://www.googleapis.com/oauth2/v4/token",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "form-urlencoded",
"bodyParameters": {
"parameters": [
{
"name": "grant_type",
"value": "urn:ietf:params:oauth:grant-type:jwt-bearer"
},
{
"name": "assertion",
"value": "={{ $json.token }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "f836567d-e5a9-457c-89fb-2c42d2123867",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
3040,
416
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "4642d47b-fafc-4487-8799-1f1e0e544ef1",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.response.videos[0].bytesBase64Encoded }}",
"rightValue": ""
}
]
}
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"typeVersion": 3.2
},
{
"id": "9a64b984-2aa0-48e8-8c1b-dd7fc9ccfb61",
"name": "Generate Video",
"type": "n8n-nodes-base.httpRequest",
"position": [
2368,
416
],
"parameters": {
"url": "=https://{{ $('SET').first().json.API_ENDPOINT }}/v1/projects/{{ $('SET').first().json.PROJECT_ID }}/locations/{{ $('SET').first().json.LOCATION_ID }}/publishers/google/models/veo-3.0-generate-preview:predictLongRunning ",
"method": "POST",
"options": {},
"jsonBody": "={\n \"endpoint\": \"projects/{{ $('SET').first().json.PROJECT_ID }}/locations/{{ $('SET').first().json.LOCATION_ID }}/publishers/google/models/veo-3.0-generate-preview\",\n \"instances\": [\n {\n \"prompt\": {{ JSON.stringify($('Prompt Agent').item.json.output) }}\n }\n ],\n \"parameters\": {\n \"aspectRatio\": \"16:9\",\n \"sampleCount\": 1,\n \"durationSeconds\": \"8\",\n \"personGeneration\": \"allow_all\",\n \"addWatermark\": false,\n \"includeRaiReason\": true,\n \"generateAudio\": true\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $('GET TOKEN').item.json.access_token }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "deefd66e-6603-4e02-b867-d3fafc720fd9",
"name": "Fetch Status",
"type": "n8n-nodes-base.httpRequest",
"position": [
2816,
336
],
"parameters": {
"url": "=https://{{ $('SET').first().json.API_ENDPOINT }}/v1/projects/{{ $('SET').first().json.PROJECT_ID }}/locations/{{ $('SET').first().json.LOCATION_ID }}/publishers/google/models/veo-3.0-generate-preview:fetchPredictOperation",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "operationName",
"value": "={{ $json.name }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $('GET TOKEN').item.json.access_token }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "4e474315-2704-4c7b-aeb6-65daf8a01ed9",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"position": [
2592,
416
],
"parameters": {
"amount": 20
},
"typeVersion": 1.1
},
{
"id": "10550efe-791e-4da3-9f9f-005ee678fdac",
"name": "Convert to File",
"type": "n8n-nodes-base.convertToFile",
"notes": "At this step, the video should be generated and ready to convert to 9:16 aspect ratio",
"position": [
3264,
416
],
"parameters": {
"options": {},
"operation": "toBinary",
"sourceProperty": "response.videos[0].bytesBase64Encoded"
},
"notesInFlow": true,
"typeVersion": 1.1
},
{
"id": "5e677094-e6bc-41e4-a6e1-d76fa293d47e",
"name": "Rendering...",
"type": "n8n-nodes-base.wait",
"position": [
3936,
416
],
"parameters": {},
"typeVersion": 1.1
},
{
"id": "7258109f-ae30-4c4f-866a-b8f09aaab255",
"name": "Download final video",
"type": "n8n-nodes-base.httpRequest",
"position": [
4832,
416
],
"parameters": {
"url": "={{ $('Done?').item.json.response.url }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "f8714eae-ab8b-46dd-a819-223c03ecc03b",
"name": "Upload to GCS (To be accessible via URL)",
"type": "n8n-nodes-base.googleCloudStorage",
"position": [
3488,
416
],
"parameters": {
"resource": "object",
"operation": "create",
"bucketName": "veo_courses",
"createData": {},
"objectName": "ViralReelz",
"createQuery": {},
"requestOptions": {},
"encryptionHeaders": {}
},
"retryOnFail": true,
"typeVersion": 1,
"waitBetweenTries": 2000
},
{
"id": "b5b22d9c-93db-4a82-8db2-59eb6c88bb2f",
"name": "Turn video to 9:16",
"type": "n8n-nodes-base.httpRequest",
"position": [
3712,
416
],
"parameters": {
"url": "https://api.shotstack.io/v1/render",
"method": "POST",
"options": {},
"jsonBody": "={\n\t\"timeline\": {\n\t\t\"tracks\": [\n\t\t\t{\n\t\t\t\t\"clips\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"asset\": {\n\t\t\t\t\t\t\t\"type\": \"video\",\n\t\t\t\t\t\t\t\"src\": \"{{ $json.mediaLink }}\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"start\": 0,\n\t\t\t\t\t\t\"length\": 8,\n\t\t\t\t\t\t\"fit\": \"crop\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t},\n\t\"output\": {\n\t\t\"format\": \"mp4\",\n\t\t\"aspectRatio\": \"9:16\",\n\t\t\"resolution\": \"hd\"\n\t}\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "fd649de0-eaf2-4505-894d-42ae07eb9a52",
"name": "Done?",
"type": "n8n-nodes-base.if",
"position": [
4384,
416
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "fc24d410-040a-4ca6-b70f-7473af617bd9",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.response.status }}",
"rightValue": "done"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "1d4a8e28-74c8-4709-b5d2-b60e6aacbbbb",
"name": "Configure me",
"type": "n8n-nodes-base.set",
"position": [
4608,
416
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "0f5772c0-1f84-45e9-b131-8be1c8dd6d85",
"name": "postiz_api",
"type": "string",
"value": "https://api.postiz.com/public/v1"
},
{
"id": "f3d9536a-3dc9-4673-b774-0434ca64575f",
"name": "share_title",
"type": "string",
"value": "={{ $('Idea Agent').item.json.output.caption }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "3396327d-8cbf-4301-91a0-e1de365c0139",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
4560,
192
],
"parameters": {
"color": 3,
"width": 220,
"height": 380,
"content": "# \u2757 Config"
},
"typeVersion": 1
},
{
"id": "b41ab464-3fb0-411f-8216-266fdca03b9d",
"name": "Done?1",
"type": "n8n-nodes-base.httpRequest",
"position": [
4160,
336
],
"parameters": {
"url": "=https://api.shotstack.io/v1/render/{{ $('Turn video to 9:16').item.json.response.id }}",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "264a12c7-e626-4247-a8f4-0df60347574e",
"name": "Upload video to Postiz",
"type": "n8n-nodes-base.httpRequest",
"position": [
5056,
416
],
"parameters": {
"url": "=https://api.postiz.com/public/v1/upload",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "file",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "8e937887-b050-462a-8a38-0e7e7cd17e4e",
"name": "Get Postiz integrations",
"type": "n8n-nodes-base.httpRequest",
"position": [
5280,
416
],
"parameters": {
"url": "=https://api.postiz.com/public/v1/integrations",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "013ae745-6a51-45bd-967f-5cc98ecd776f",
"name": "Switch1",
"type": "n8n-nodes-base.switch",
"position": [
5504,
400
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "tiktok",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "3ff74ffe-3f82-437d-9218-bce4f7551211",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.identifier }}",
"rightValue": "tiktok"
}
]
},
"renameOutput": true
},
{
"outputKey": "youtube",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "2edc7f5f-18cf-45e2-9a10-03c6ee2a062f",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.identifier }}",
"rightValue": "youtube"
}
]
},
"renameOutput": true
},
{
"outputKey": "instagram",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f461c331-7506-486b-ab4a-de03823f82f9",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.identifier }}",
"rightValue": "instagram"
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "99f9050c-7fbc-4ebb-b1fc-26cf1d5fac43",
"name": "Schedule YouTube",
"type": "n8n-nodes-base.httpRequest",
"position": [
5728,
416
],
"parameters": {
"url": "=https://api.postiz.com/public/v1/posts",
"method": "POST",
"options": {},
"jsonBody": "={\n \"type\": \"schedule\",\n \"date\": \"{{ $now.plus(1, 'days').toISO() }}\",\n \"tags\": [],\n \"shortLink\": false,\n \"posts\": [\n {\n \"integration\": {\n \"id\": \"{{ $('Switch1').item.json.id }}\"\n },\n \"value\": [\n {\n \"content\": \"{{ $('Get Past Objects').first().json.quote.replace(/\"/g, \"\") }}\",\n \"image\": [\n {\n \"id\": \"{{ $('Upload video to Postiz').item.json.id }}\",\n \"path\": \"{{ $('Upload video to Postiz').item.json.path }}\"\n }\n ]\n }\n ],\n \"settings\": {\n \"title\": \"{{ $('Get Past Objects').first().json.quote.replace(/\"/g, \"\") }}\",\n \"type\": \"public\"\n }\n }\n ]\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "2e16d4b6-1fee-4948-bb5f-c5442559b053",
"name": "Schedule TikTok",
"type": "n8n-nodes-base.httpRequest",
"position": [
5728,
224
],
"parameters": {
"url": "=https://api.postiz.com/public/v1/posts",
"method": "POST",
"options": {},
"jsonBody": "={\n \"type\": \"schedule\",\n \"date\": \"{{ $now.plus(1, 'days').toISO() }}\",\n \"tags\": [],\n \"shortLink\": false,\n \"posts\": [\n {\n \"integration\": {\n \"id\": \"{{ $('Switch1').item.json.id }}\"\n },\n \"value\": [\n {\n \"content\": \"{{ $('Get Past Objects').first().json.quote.replace(/\"/g, \"\") }}\",\n \"image\": [\n {\n \"id\": \"{{ $('Upload video to Postiz').item.json.id }}\",\n \"path\": \"{{ $('Upload video to Postiz').item.json.path }}\"\n }\n ]\n }\n ],\n \"settings\": {\n \"title\": \"{{ $('Get Past Objects').first().json.quote.replace(/\"/g, \"\") }}\",\n \"privacy_level\": \"PUBLIC_TO_EVERYONE\",\n \"duet\": \"false\",\n \"stitch\": \"false\",\n \"comment\": \"true\",\n \"autoAddMusic\": \"no\",\n \"brand_content_toggle\": \"false\",\n \"brand_organic_toggle\": \"false\",\n \"content_posting_method\": \"DIRECT_POST\"\n }\n }\n ]\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "9485041f-7139-4a2f-917f-0d05f0fe41ea",
"name": "Schedule Instagram",
"type": "n8n-nodes-base.httpRequest",
"position": [
5728,
608
],
"parameters": {
"url": "=https://api.postiz.com/public/v1/posts",
"method": "POST",
"options": {},
"jsonBody": "={\n \"type\": \"schedule\",\n \"date\": \"{{ $now.plus(1, 'days').toISO() }}\",\n \"tags\": [],\n \"shortLink\": false,\n \"posts\": [\n {\n \"integration\": {\n \"id\": \"{{ $('Switch1').item.json.id }}\"\n },\n \"value\": [\n {\n \"content\": \"{{ $('Get Past Objects').first().json.quote.replace(/\"/g, \"\") }}\",\n \"image\": [\n {\n \"id\": \"{{ $('Upload video to Postiz').item.json.id }}\",\n \"path\": \"{{ $('Upload video to Postiz').item.json.path }}\"\n }\n ]\n }\n ],\n \"settings\": {\n \"title\": \"{{ $('Get Past Objects').first().json.quote.replace(/\"/g, \"\") }}\",\n \"post_type\": \"post\"\n }\n }\n ]\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "301a2fb3-f381-4dc3-b57c-0a7c398f30b8",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
5152,
112
],
"parameters": {
"color": 6,
"width": 464,
"height": 496,
"content": "## Checking the available channels"
},
"typeVersion": 1
},
{
"id": "dd760b85-96e1-4b05-abcc-0d86a3d6c2ee",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
5616,
112
],
"parameters": {
"color": 3,
"width": 320,
"height": 656,
"content": "## Scheduling the posts"
},
"typeVersion": 1
},
{
"id": "6d0e6ac4-efb4-455c-bed4-4c746a901179",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-544,
-176
],
"parameters": {
"width": 432,
"height": 1376,
"content": "\ud83c\udfa5 Veo Machine Reels Factory \u2014 Full User Guide\n\ud83e\udded Introduction\n\nThe Veo Machine Reels Factory is an automated content creation system built in n8n that turns creative ideas into fully rendered ASMR-style glass fruit reels, ready to post on TikTok, YouTube Shorts, and Instagram Reels.\n\nThis template connects multiple AI and automation services into a single, repeatable pipeline. It eliminates manual steps \u2014 from concept brainstorming to posting \u2014 allowing creators or marketing teams to produce viral short-form videos hands-free.\n\n\u2699\ufe0f How It Works (In Short)\n\nThe workflow starts automatically every 8 hours (or manually when triggered).\n\nIt checks a Google Sheet to see which fruits have already been used.\n\nAn AI \u201cIdea Agent\u201d selects a new, unique glass fruit concept.\n\nAnother AI \u201cPrompt Agent\u201d writes a cinematic Google Veo 3 prompt describing the video.\n\nThe system sends that prompt to Google Veo, which generates the actual video file.\n\nThe video is automatically:\n\nConverted to 9:16 vertical format via Shotstack\n\nUploaded to Google Cloud Storage\n\nPosted to TikTok, YouTube, and Instagram through Postiz API\n\n\ud83e\uddf1 Requirements\n\nBefore running this workflow, make sure you have the following ready:\n\nCategory\tRequirement\nGoogle Cloud\tProject ID, Service Account Email, and Storage Bucket (e.g., veo_courses)\nVeo Access\tAccess to Google Veo 3.0 API (through Vertex AI or similar endpoint)\nGoogle Sheets\tA sheet with previous fruit ideas (used for avoiding duplicates)\nOpenAI Account\tAPI key configured in n8n credentials\nShotstack Account\tAPI key (for cropping to 9:16)\nPostiz Account\tActive integrations for TikTok, YouTube, and Instagram\nn8n Instance\tVersion supporting LangChain, HTTP, JWT, and Google nodes\n\ud83e\udde9 Workflow Structure Overview\n\nThe workflow can be divided into five main parts:\n\n\ud83d\udd52 Automation & Data Input\n\n\ud83e\udde0 AI Generation (Idea + Prompt Creation)\n\n\ud83c\udfac Video Generation with Google Veo\n\n\ud83d\udcf1 Video Conversion & Upload\n\n\ud83d\ude80 Auto-Publishing to Social Media\n\nLet\u2019s go through each part in detail."
},
"typeVersion": 1
},
{
"id": "2d938bce-ddf1-4dee-bbdf-cb95df7b50d3",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
112,
80
],
"parameters": {
"color": 5,
"width": 464,
"height": 256,
"content": "How to Use\n\nMake sure your Google Sheet is linked and accessible with the same Google account connected to n8n.\n\nAdd previously used fruits in column A (one per line).\n\nIf you want to trigger it manually, click \u201cExecute Workflow\u201d in n8n instead of waiting for the schedule.\n\nResult:\nThe system prepares a list of \u201cused\u201d fruits to feed into the AI for idea generation"
},
"typeVersion": 1
},
{
"id": "90804430-3fdd-4d42-a70c-edec8b67234f",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
736,
64
],
"parameters": {
"width": 816,
"height": 288,
"content": "\ud83e\udde0 PART 2 \u2014 AI Generation (Idea + Prompt Creation)\nPurpose\n\nThis section generates:\n\nA new \u201cglass fruit\u201d idea that hasn\u2019t been used before.\n\nA cinematic Veo-compatible text prompt to generate the ASMR video.\n\nIncludes\n\nIdea Agent (LangChain Node + OpenAI GPT-4.1-mini)\n\nObject & Caption Output Parser\n\nPrompt Agent (LangChain Node + GPT-4.1-mini)\n\nHow it Works\n\nIdea Agent takes your list of used fruits and outputs a new idea like:\n\n{ \"object\": \"Glass Mango\", \"caption\": \"Glass Mango ASMR\" }\n\n\nOutput Parser ensures this format is clean JSON.\n\nPrompt Agent then writes a detailed text-to-video prompt for Google Veo based on that fruit.\n\nHow to Use\n\nNo manual input needed \u2014 this runs automatically.\n\nYou can tweak the creative tone or style rules by editing the system message in the Prompt Agent.\n\nIf you want shorter or different themes, adjust the descriptive text in the \u201cPrompt Agent\u201d node.\n\nResult:\nYou get a hyper-realistic, safe, cinematic prompt that\u2019s fully compliant with Veo content policies."
},
"typeVersion": 1
},
{
"id": "c0f58447-7ac7-4d0a-96f6-96a2eed9ea5f",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1888,
64
],
"parameters": {
"width": 736,
"height": 288,
"content": "\ud83c\udfac PART 3 \u2014 Video Generation (Google Veo 3.0)\nPurpose\n\nThis part authenticates with Google Cloud, sends the prompt to Veo, and retrieves the rendered video.\n\nIncludes\n\nSET (Google Cloud credentials)\n\nJWT + GET TOKEN (Authentication)\n\nGenerate Video (POST request to Veo API)\n\nWait \u2192 Fetch Status \u2192 Switch (Checks generation progress)\n\nHow it Works\n\nThe workflow builds a secure JWT, exchanges it for an OAuth token, and calls the Veo API.\n\nVeo starts generating the ASMR-style video based on the AI prompt.\n\nThe workflow waits, then checks every few seconds until Veo\u2019s API confirms the video is ready.\n\nOnce done, it retrieves the base64-encoded video data.\n\nHow to Use\n\nYou must fill the PROJECT_ID and CLIENT_EMAIL in the SET node with your actual Google Cloud details.\n\nEnsure the Veo API endpoint (aiplatform.googleapis.com) matches your project\u2019s region.\n\nThe \u201cWait\u201d time can be increased if your videos take longer to generate.\n\nResult:\nA finished .mp4 video is now ready for post-processing."
},
"typeVersion": 1
},
{
"id": "29ab5742-a777-4c85-a035-aa08a3b7abf5",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
3104,
64
],
"parameters": {
"width": 928,
"height": 288,
"content": "\ud83d\udcf1 PART 4 \u2014 Video Conversion & Upload\nPurpose\n\nPrepares the video for social media: converting to 9:16 format and uploading it to cloud storage.\n\nIncludes\n\nConvert to File\n\nUpload to Google Cloud Storage\n\nShotstack Conversion (Turn video to 9:16)\n\nRendering + Done Checks\n\nHow it Works\n\nConverts Veo\u2019s output to an actual video file.\n\nUploads it to your Google Cloud Storage bucket (veo_courses).\n\nSends the video to Shotstack, which crops and renders it vertically (9:16).\n\nWaits until Shotstack finishes processing.\n\nHow to Use\n\nMake sure your GCS bucket exists and allows file uploads.\n\nAdd your Shotstack API key in n8n credentials.\n\nOptional: You can adjust video length or resolution inside the Shotstack JSON body.\n\nResult:\nYou now have a finished vertical HD ASMR video stored in the cloud."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "2615cbe8-8824-4f29-8654-103fabc62edb",
"connections": {
"JWT": {
"main": [
[
{
"node": "GET TOKEN",
"type": "main",
"index": 0
}
]
]
},
"SET": {
"main": [
[
{
"node": "JWT",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Fetch Status",
"type": "main",
"index": 0
}
]
]
},
"Done?": {
"main": [
[
{
"node": "Configure me",
"type": "main",
"index": 0
}
],
[
{
"node": "Rendering...",
"type": "main",
"index": 0
}
]
]
},
"Done?1": {
"main": [
[
{
"node": "Done?",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "Convert to File",
"type": "main",
"index": 0
}
],
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Switch1": {
"main": [
[
{
"node": "Schedule TikTok",
"type": "main",
"index": 0
}
],
[
{
"node": "Schedule YouTube",
"type": "main",
"index": 0
}
],
[
{
"node": "Schedule Instagram",
"type": "main",
"index": 0
}
]
]
},
"Aggregate": {
"main": [
[
{
"node": "Set Object List",
"type": "main",
"index": 0
}
]
]
},
"GET TOKEN": {
"main": [
[
{
"node": "Generate Video",
"type": "main",
"index": 0
}
]
]
},
"Idea Agent": {
"main": [
[
{
"node": "Prompt Agent",
"type": "main",
"index": 0
}
]
]
},
"Configure me": {
"main": [
[
{
"node": "Download final video",
"type": "main",
"index": 0
}
]
]
},
"Fetch Status": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Prompt Agent": {
"main": [
[
{
"node": "SET",
"type": "main",
"index": 0
}
]
]
},
"Rendering...": {
"main": [
[
{
"node": "Done?1",
"type": "main",
"index": 0
}
]
]
},
"Generate Video": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Convert to File": {
"main": [
[
{
"node": "Upload to GCS (To be accessible via URL)",
"type": "main",
"index": 0
}
]
]
},
"Set Object List": {
"main": [
[
{
"node": "Idea Agent",
"type": "main",
"index": 0
}
]
]
},
"Get Past Objects": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"Object & Caption": {
"ai_outputParser": [
[
{
"node": "Idea Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Idea Agent",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Prompt Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Turn video to 9:16": {
"main": [
[
{
"node": "Rendering...",
"type": "main",
"index": 0
}
]
]
},
"Download final video": {
"main": [
[
{
"node": "Upload video to Postiz",
"type": "main",
"index": 0
}
]
]
},
"Upload video to Postiz": {
"main": [
[
{
"node": "Get Postiz integrations",
"type": "main",
"index": 0
}
]
]
},
"Get Postiz integrations": {
"main": [
[
{
"node": "Switch1",
"type": "main",
"index": 0
}
]
]
},
"When clicking \u2018Execute workflow\u2019": {
"main": [
[
{
"node": "Get Past Objects",
"type": "main",
"index": 0
}
]
]
},
"Upload to GCS (To be accessible via URL)": {
"main": [
[
{
"node": "Turn video to 9:16",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
🎥 Veo Machine Reels Factory — Full User Guide 🧭 Introduction
Source: https://n8n.io/workflows/10175/ — 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.
Transform a single quote into a fully-rendered cinematic short video — with voice-over, visuals, and music — then publish it directly to TikTok, Instagram Reels, and YouTube Shorts. This isn’t just au
🎯 Create viral TikToks, Shorts, Reels, podcasts, and ASMR videos in minutes — all on autopilot.
Generate AI viral videos with NanoBanana & VEO3, shared on socials via Blotato 2. Uses @blotato/n8n-nodes-blotato, googleSheets, lmChatOpenAi, toolThink. Event-driven trigger; 94 nodes.
This template is designed for marketers, content creators, and e-commerce brands who want to automate the creation of professional ad videos at scale. It’s ideal for teams looking to generate consiste
This comprehensive n8n workflow automates the entire Meta (Facebook/Instagram) advertising process, from asset analysis to ad creation. It combines AI-powered content analysis with automated ad deploy