{
  "id": "YyYivZiaag1ME8LZ",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "VEO3 AI Video Generator \u2014 Form + ChatGPT AI Prompt + fal.ai VEO3 + Google Drive + Gmail",
  "tags": [],
  "nodes": [
    {
      "id": "9f757d4e-89a4-4ac6-8bd8-ba17763a8247",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1040,
        -464
      ],
      "parameters": {
        "color": 4,
        "width": 540,
        "height": 1300,
        "content": "## VEO3 AI Video Generator \u2014 Form + ChatGPT AI Prompt + fal.ai VEO3 + Google Drive + Gmail\n\nFor creators and marketers who want to turn a one-line video idea into a finished, audio-rich clip without writing a complex prompt. You fill a form with a simple idea in plain English. A ChatGPT AI model converts it into a detailed, professional VEO3 prompt (subject, camera motion, lighting, audio, style). The optimized prompt is sent to fal.ai which runs Google's VEO3 model to generate an 8-second video with native audio. The workflow polls for completion, downloads the MP4, saves it to Google Drive, and emails you the link.\n\n## How it works\n- **1. Form \u2014 Video Request** collects your email, the video idea, and a style choice\n- **2. AI Agent \u2014 Optimize VEO3 Prompt** turns the plain-English idea into a structured VEO3 prompt and a short title, returned as strict JSON\n- **OpenAI Chat Model** the language model attached to the AI Agent\n- **3. Code \u2014 Parse Prompt and Prepare** safely parses the JSON, builds a filename-safe title, and sets aspect ratio and duration\n- **4. HTTP \u2014 Submit to fal.ai VEO3** queues the generation job and returns a request_id\n- **5. Wait \u2014 30 Seconds** gives VEO3 time before the first status check\n- **6. HTTP \u2014 Check VEO3 Status** reads the job status\n- **7. IF \u2014 Video COMPLETED?** routes to download when ready, otherwise to retry\n- **7b. Wait \u2014 Retry 30s** waits then loops back to the status check\n- **8. HTTP \u2014 Get Video URL** fetches the finished job result with the MP4 URL\n- **9. HTTP \u2014 Download MP4** downloads the video binary\n- **10. Google Drive \u2014 Save MP4** saves the file with the AI title as filename\n- **11. Gmail \u2014 Send Video Link** emails you the Drive link\n\n## Set up steps\n1. **fal.ai API (runs VEO3)** \u2014 create a free account at https://fal.ai, make an API key at https://fal.ai/dashboard/keys, and replace `YOUR_FAL_AI_API_KEY` in nodes 4, 6, and 8. VEO3 generation costs fal.ai credits \u2014 check current pricing at https://fal.ai/models/fal-ai/veo3\n2. **OpenAI** \u2014 in **OpenAI Chat Model**, connect your OpenAI API credential and pick any current ChatGPT model from the dropdown\n3. **Google Drive** \u2014 create a folder for your videos, copy its folder ID from the URL after /folders/, replace `YOUR_GDRIVE_FOLDER_ID` in node 10, and connect Google Drive OAuth2\n4. **Gmail** \u2014 connect Gmail OAuth2 in node 11. The recipient address comes from the form, so no email needs to be hard-coded\n5. Activate the workflow, open the Form URL, type a video idea in plain English, and submit. Wait about 2-3 minutes and check your email for the Drive link"
      },
      "typeVersion": 1
    },
    {
      "id": "fd59df79-1fc1-47b2-9a0d-043d17acaf90",
      "name": "Section \u2014 Form Input and AI Prompt",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        -224
      ],
      "parameters": {
        "color": 5,
        "width": 756,
        "height": 484,
        "content": "## Form Input and AI Prompt\nUser types a plain-English idea and picks a style. The ChatGPT AI model converts it into a detailed professional VEO3 prompt with all elements (subject, camera, lighting, audio)."
      },
      "typeVersion": 1
    },
    {
      "id": "d9a5b65f-48fe-46fc-b9c3-1a0ca99f69d3",
      "name": "Section \u2014 Submit, Poll, and Download",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        -336
      ],
      "parameters": {
        "color": 6,
        "width": 1172,
        "height": 692,
        "content": "## Submit, Poll, and Download\nfal.ai VEO3 receives the prompt and returns a request_id. The workflow waits, checks status, and loops every 30s until COMPLETED, then fetches the result and downloads the MP4 binary."
      },
      "typeVersion": 1
    },
    {
      "id": "43963a31-4e9c-4e75-9f87-83418c3c02d2",
      "name": "Section \u2014 Save to Drive and Email",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1664,
        -240
      ],
      "parameters": {
        "color": 4,
        "width": 932,
        "height": 516,
        "content": "## Save to Drive and Email\nThe MP4 is saved to Google Drive with the AI-generated title as filename. Gmail sends you the Drive link."
      },
      "typeVersion": 1
    },
    {
      "id": "ca236fc8-3ef2-4c20-ad29-13ce5c7880bd",
      "name": "1. Form \u2014 Video Request",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -320,
        -64
      ],
      "parameters": {
        "options": {
          "path": "veo3-video-generator",
          "buttonLabel": "Generate Video",
          "appendAttribution": false
        },
        "formTitle": "VEO3 AI Video Generator",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Your Email Address",
              "placeholder": "user@example.com \u2014 video link will be sent here",
              "requiredField": true
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "Video Idea",
              "placeholder": "Describe what you want in the video \u2014 e.g. A chef preparing fresh pasta in a modern kitchen, steam rising, upbeat background music",
              "requiredField": true
            },
            {
              "fieldType": "dropdown",
              "fieldLabel": "Video Style",
              "fieldOptions": {
                "values": [
                  {
                    "option": "Cinematic \u2014 Professional film style"
                  },
                  {
                    "option": "Documentary \u2014 Realistic natural footage"
                  },
                  {
                    "option": "Commercial \u2014 Advertisement style"
                  },
                  {
                    "option": "Animation \u2014 3D cartoon style"
                  },
                  {
                    "option": "Action \u2014 Dynamic fast-paced"
                  }
                ]
              },
              "requiredField": true
            }
          ]
        },
        "formDescription": "Describe your video idea in plain English. AI will convert it into a professional VEO3 prompt and generate an 8-second video with native audio. You will receive a Google Drive link via email when ready."
      },
      "typeVersion": 2.2
    },
    {
      "id": "a5f5bd68-e116-4d8f-8461-0090502b0d1e",
      "name": "2. AI Agent \u2014 Optimize VEO3 Prompt",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -80,
        -64
      ],
      "parameters": {
        "text": "=Video Idea: {{ $json['Video Idea'] }}\nStyle: {{ $json['Video Style'] }}",
        "options": {
          "systemMessage": "You are an expert VEO3 video prompt engineer. Convert a simple video idea into a detailed, professional VEO3 prompt that will generate a high-quality 8-second video.\n\nAll videos are 16:9 landscape format, 8 seconds long. Optimize for widescreen cinematic presentation.\n\nReturn ONLY valid JSON \u2014 no markdown, no code fences, no explanation.\n\nReturn this exact structure:\n{\n  \"title\": \"<short factual title 5-60 chars \u2014 describes what is shown, no emotional words like epic or magical>\",\n  \"prompt\": \"<detailed VEO3 prompt 80-400 words \u2014 include: Subject (main focus), Context (setting/environment), Action (what happens), Style (film style), Camera Motion (dolly/tracking/aerial/static/pan), Composition (wide shot/close-up/medium), Ambiance (lighting/color/mood), Audio (ambient sounds, music description, any dialogue in quotes for lip-sync)>\"\n}\n\nVEO3 PROMPT RULES:\n- Always include Audio \u2014 VEO3 generates native audio, this is its biggest feature\n- For dialogue: write exact words in double quotes for perfect lip-sync\n- Use professional film terminology for camera work\n- Be specific about lighting \u2014 golden hour, harsh shadows, soft diffused, neon glow etc\n- Mention realistic physics and natural movements for better quality\n- Optimize for 8-second pacing \u2014 what happens start to finish\n\nSTYLE MAPPING:\n- Cinematic: use 'Cinematic widescreen style, dramatic lighting, shallow depth of field'\n- Documentary: use 'Documentary footage style, natural lighting, handheld camera feel'\n- Commercial: use 'Commercial advertisement style, bright clean lighting, product showcase feel'\n- Animation: use '3D cartoon animation style, vibrant colors, stylized render'\n- Action: use 'Dynamic action cinematography, fast tracking shots, motion blur, high energy'"
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "b1e51332-3d98-43bf-b7cb-dd6cf09cacfd",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -80,
        144
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "005aef7f-ef6a-4e07-85fd-7ad96986352e",
      "name": "3. Code \u2014 Parse Prompt and Prepare",
      "type": "n8n-nodes-base.code",
      "position": [
        480,
        -64
      ],
      "parameters": {
        "jsCode": "// Parse AI JSON output and prepare for fal.ai\nconst raw    = $input.first().json.output || '';\nconst email  = $('1. Form \u2014 Video Request').first().json['Your Email Address'] || '';\nconst idea   = $('1. Form \u2014 Video Request').first().json['Video Idea'] || '';\nconst style  = $('1. Form \u2014 Video Request').first().json['Video Style'] || '';\n\nlet parsed = { title: 'Generated Video', prompt: '' };\ntry {\n  const cleaned = raw.trim()\n    .replace(/^```json\\s*/i, '')\n    .replace(/^```\\s*/i, '')\n    .replace(/```$/i, '')\n    .trim();\n  parsed = JSON.parse(cleaned);\n} catch (e) {\n  parsed = {\n    title: 'Generated Video ' + Date.now(),\n    prompt: raw.substring(0, 500) || idea\n  };\n}\n\nconst safeTitle = (parsed.title || 'video')\n  .replace(/[^a-zA-Z0-9 _-]/g, '')\n  .replace(/\\s+/g, '_')\n  .substring(0, 60);\n\nreturn [{\n  json: {\n    email,\n    videoIdea:   idea,\n    videoStyle:  style,\n    title:       parsed.title  || 'Generated Video',\n    safeTitle:   safeTitle,\n    prompt:      parsed.prompt || idea,\n    aspectRatio: '16:9',\n    duration:    '8s'\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "bbeb46ed-de2e-4709-a834-2148a867895e",
      "name": "4. HTTP \u2014 Submit to fal.ai VEO3",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        672,
        -64
      ],
      "parameters": {
        "url": "https://queue.fal.run/fal-ai/veo3",
        "method": "POST",
        "options": {
          "timeout": 60000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "jsonBody": "={{ JSON.stringify({\n  prompt: $json.prompt,\n  aspect_ratio: $json.aspectRatio,\n  duration: $json.duration\n}) }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Key YOUR_FAL_AI_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "8c6b8251-5910-46d4-a492-652fa5e5c6bd",
      "name": "5. Wait \u2014 30 Seconds",
      "type": "n8n-nodes-base.wait",
      "position": [
        912,
        -64
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "87470e8b-86ed-487f-a5f9-75f8041e23eb",
      "name": "6. HTTP \u2014 Check VEO3 Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1152,
        -64
      ],
      "parameters": {
        "url": "=https://queue.fal.run/fal-ai/veo3/requests/{{ $('4. HTTP \u2014 Submit to fal.ai VEO3').first().json.request_id }}/status",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Key YOUR_FAL_AI_API_KEY"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "631a9399-1d34-41e2-8001-5ef5dc357163",
      "name": "7. IF \u2014 Video COMPLETED?",
      "type": "n8n-nodes-base.if",
      "position": [
        1408,
        -64
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "status-completed",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "COMPLETED"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "6337de38-5d0c-4ccc-b528-991a41e1b6d2",
      "name": "7b. Wait \u2014 Retry 30s",
      "type": "n8n-nodes-base.wait",
      "position": [
        1408,
        144
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "b714fa12-5de9-4d68-bff2-6dff599738ae",
      "name": "8. HTTP \u2014 Get Video URL",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1728,
        -80
      ],
      "parameters": {
        "url": "=https://queue.fal.run/fal-ai/veo3/requests/{{ $('4. HTTP \u2014 Submit to fal.ai VEO3').first().json.request_id }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Key YOUR_FAL_AI_API_KEY"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f03bda13-bfeb-421f-b90c-95763f7ca5e7",
      "name": "9. HTTP \u2014 Download MP4",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1968,
        -80
      ],
      "parameters": {
        "url": "={{ $json.video.url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d56e8de4-67aa-47b9-8a38-2da9b84b376e",
      "name": "10. Google Drive \u2014 Save MP4",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        2208,
        -80
      ],
      "parameters": {
        "name": "={{ $('3. Code \u2014 Parse Prompt and Prepare').first().json.safeTitle }}.mp4",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive",
          "cachedResultName": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GDRIVE_FOLDER_ID"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "77c698da-dd78-48e7-8f91-931b1d0885c3",
      "name": "11. Gmail \u2014 Send Video Link",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2448,
        -80
      ],
      "parameters": {
        "sendTo": "={{ $('3. Code \u2014 Parse Prompt and Prepare').first().json.email }}",
        "message": "=<div style=\"font-family:Arial,sans-serif;max-width:640px;margin:0 auto;background:#f5f5f5;\">\n\n  <div style=\"background:#1a1a2e;padding:24px 28px;border-radius:8px 8px 0 0;\">\n    <h1 style=\"color:#fff;font-size:20px;margin:0;\">Your AI Video is Ready</h1>\n    <p style=\"color:#aaa;font-size:13px;margin:6px 0 0;\">Generated by VEO3 via fal.ai</p>\n  </div>\n\n  <div style=\"background:#fff;padding:24px 28px;\">\n\n    <div style=\"background:#f0f4ff;border-left:4px solid #4a90e2;padding:14px;border-radius:0 6px 6px 0;margin-bottom:20px;\">\n      <h2 style=\"margin:0 0 6px;font-size:14px;color:#1a1a2e;\">Video Title</h2>\n      <p style=\"margin:0;font-size:16px;font-weight:600;color:#333;\">{{ $('3. Code \u2014 Parse Prompt and Prepare').first().json.title }}</p>\n    </div>\n\n    <div style=\"background:#e8f5e9;border-left:4px solid #43a047;padding:14px;border-radius:0 6px 6px 0;margin-bottom:20px;\">\n      <h2 style=\"margin:0 0 6px;font-size:14px;color:#1a1a2e;\">Your Video on Google Drive</h2>\n      <a href=\"{{ $json.webViewLink }}\" style=\"color:#4a90e2;font-size:14px;word-break:break-all;\">{{ $json.webViewLink }}</a>\n    </div>\n\n    <div style=\"margin-bottom:20px;\">\n      <h2 style=\"font-size:14px;color:#1a1a2e;margin:0 0 8px;\">Your Original Idea</h2>\n      <p style=\"font-size:13px;color:#555;line-height:1.6;margin:0;\">{{ $('3. Code \u2014 Parse Prompt and Prepare').first().json.videoIdea }}</p>\n    </div>\n\n    <div style=\"background:#f9f9f9;padding:14px;border-radius:6px;\">\n      <h2 style=\"font-size:14px;color:#1a1a2e;margin:0 0 8px;\">AI-Optimized VEO3 Prompt Used</h2>\n      <p style=\"font-size:12px;color:#666;line-height:1.6;margin:0;\">{{ $('3. Code \u2014 Parse Prompt and Prepare').first().json.prompt }}</p>\n    </div>\n\n  </div>\n\n  <div style=\"background:#1a1a2e;padding:12px 24px;text-align:center;border-radius:0 0 8px 8px;\">\n    <p style=\"color:#888;font-size:11px;margin:0;\">Powered by n8n + ChatGPT AI + Google VEO3 via fal.ai</p>\n  </div>\n\n</div>",
        "options": {
          "senderName": "VEO3 Video Generator"
        },
        "subject": "=Your VEO3 Video is Ready \u2014 {{ $('3. Code \u2014 Parse Prompt and Prepare').first().json.title }}"
      },
      "typeVersion": 2.1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "9e016525-b51b-4cf7-afcf-8a8aaa2b0ab0",
  "nodeGroups": [],
  "connections": {
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "2. AI Agent \u2014 Optimize VEO3 Prompt",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "5. Wait \u2014 30 Seconds": {
      "main": [
        [
          {
            "node": "6. HTTP \u2014 Check VEO3 Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7b. Wait \u2014 Retry 30s": {
      "main": [
        [
          {
            "node": "6. HTTP \u2014 Check VEO3 Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9. HTTP \u2014 Download MP4": {
      "main": [
        [
          {
            "node": "10. Google Drive \u2014 Save MP4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1. Form \u2014 Video Request": {
      "main": [
        [
          {
            "node": "2. AI Agent \u2014 Optimize VEO3 Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8. HTTP \u2014 Get Video URL": {
      "main": [
        [
          {
            "node": "9. HTTP \u2014 Download MP4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7. IF \u2014 Video COMPLETED?": {
      "main": [
        [
          {
            "node": "8. HTTP \u2014 Get Video URL",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "7b. Wait \u2014 Retry 30s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "10. Google Drive \u2014 Save MP4": {
      "main": [
        [
          {
            "node": "11. Gmail \u2014 Send Video Link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6. HTTP \u2014 Check VEO3 Status": {
      "main": [
        [
          {
            "node": "7. IF \u2014 Video COMPLETED?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4. HTTP \u2014 Submit to fal.ai VEO3": {
      "main": [
        [
          {
            "node": "5. Wait \u2014 30 Seconds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. AI Agent \u2014 Optimize VEO3 Prompt": {
      "main": [
        [
          {
            "node": "3. Code \u2014 Parse Prompt and Prepare",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3. Code \u2014 Parse Prompt and Prepare": {
      "main": [
        [
          {
            "node": "4. HTTP \u2014 Submit to fal.ai VEO3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}