Tinatin Gholadze commited on
Commit
7e9e6f8
·
verified ·
1 Parent(s): 68800b4

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +78 -14
  2. UGC Single Video Generator.json +440 -0
  3. image.png +0 -0
README.md CHANGED
@@ -1,14 +1,78 @@
1
- ---
2
- title: UGC Video Generator
3
- emoji: 🌖
4
- colorFrom: gray
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 5.49.1
8
- app_file: app.py
9
- pinned: false
10
- license: apache-2.0
11
- short_description: Generates UGC videos using n8n, Anthropic, and the Veo 3 API
12
- ---
13
-
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # UGC Single Video Generator (n8n + AI)
2
+
3
+ Automatically generate authentic **User-Generated Content (UGC)** videos from a simple form submission, powered by **n8n**, **Anthropic**, and **KIE.AI** video generation.
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ This workflow automates the process of creating influencer-style promotional videos.
10
+ Users describe the type of video and influencer, optionally let AI write the script, and select the video’s aspect ratio.
11
+ The workflow then generates a complete UGC-style MP4 video using AI, returning a video link automatically.
12
+
13
+ ---
14
+
15
+ ## How It Works
16
+
17
+
18
+
19
+ 1. **Form Submission**
20
+ - A form asks the user for:
21
+ - Video description
22
+ - Influencer type
23
+ - Whether to auto-generate a script
24
+ - Optional custom script
25
+ - Aspect ratio (9:16 or 16:9)
26
+
27
+ 2. **AI Script Generation**
28
+ - If “generate script” is checked, the workflow calls **Anthropic Claude** to produce a short, natural UGC-style script based on the video description and influencer type.
29
+
30
+ 3. **Prompt Building**
31
+ - Combines description, script, and influencer details to create structured text prompts for video generation.
32
+
33
+ 4. **Video Generation**
34
+ - Sends prompts to the **KIE.AI Video API** (`veo3_fast` model) to generate a realistic influencer-style video.
35
+
36
+ 5. **Video Retrieval**
37
+ - Fetches the finished MP4 file and returns the link automatically.
38
+
39
+ ---
40
+
41
+ ## Workflow Structure
42
+
43
+ | Step | Node | Description |
44
+ |------|------|--------------|
45
+ | 1 | **Form Trigger** | Collects user input through a custom web form. |
46
+ | 2 | **Edit Fields** | Normalizes and prepares fields for downstream use. |
47
+ | 3 | **Script Decision** | Checks if the user wants to auto-generate or use a custom script. |
48
+ | 4 | **HTTP Request (Anthropic)** | Generates a short script using Claude. |
49
+ | 5 | **Determine Final Script** | Merges AI or manual script with user input. |
50
+ | 6 | **Create Prompts** | Builds natural prompts for image/video generation. |
51
+ | 7 | **Generate Video (KIE.AI)** | Sends request to the KIE.AI API to produce the video. |
52
+ | 8 | **Check Video Success** | Confirms if the API returned a success code. |
53
+ | 9 | **Get Video File** | Retrieves the video download link using the task ID. |
54
+ | 10 | **Output Result** | Outputs video URL and status as JSON. |
55
+
56
+ ---
57
+ ## Example Output
58
+
59
+ Watch the demo video:
60
+ 👉 [UGC Video Example](https://tempfile.aiquickdraw.com/p/ae9d1909b26ece72d9464ee9ffdc1800_1760653790.mp4)
61
+
62
+
63
+ ## Setup Instructions
64
+
65
+ ### 1️⃣ Prerequisites
66
+ - [n8n](https://n8n.io) installed (self-hosted or Cloud)
67
+ - Accounts and API keys for:
68
+ - **Anthropic API**
69
+ - **KIE.AI Video API**
70
+ - Optional: a hosting service (e.g., Railway, Vercel) for the form trigger webhook.
71
+
72
+ ### 2️⃣ Environment Variables
73
+
74
+ Create a `.env` file in your n8n environment:
75
+
76
+ ```bash
77
+ ANTHROPIC_API_KEY=your-anthropic-key
78
+ KIE_API_KEY=your-kie-api-key
UGC Single Video Generator.json ADDED
@@ -0,0 +1,440 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "UGC Single Video Generator",
3
+ "nodes": [
4
+ {
5
+ "parameters": {
6
+ "conditions": {
7
+ "options": {
8
+ "caseSensitive": true,
9
+ "leftValue": "",
10
+ "typeValidation": "strict",
11
+ "version": 1
12
+ },
13
+ "conditions": [
14
+ {
15
+ "id": "c6c12c9a-3622-427b-b12c-fee98864612b",
16
+ "leftValue": "=={{ $json.generate_script ? 'yes' : '' }}",
17
+ "rightValue": "true",
18
+ "operator": {
19
+ "type": "string",
20
+ "operation": "notEmpty",
21
+ "singleValue": true
22
+ }
23
+ }
24
+ ],
25
+ "combinator": "and"
26
+ },
27
+ "options": {}
28
+ },
29
+ "name": "Script Decision",
30
+ "type": "n8n-nodes-base.if",
31
+ "typeVersion": 2,
32
+ "position": [
33
+ -2704,
34
+ 144
35
+ ],
36
+ "id": "9a304dcc-d4a5-4f73-b9c4-3c38e166d23e"
37
+ },
38
+ {
39
+ "parameters": {
40
+ "jsCode": "const video_description = $json.video_description || '';\nconst influencer_type = $json.influencer_type || '';\nconst custom_script = $json.custom_script || '';\nconst generate_script = $json.generate_script === true || $json.generate_script === 'true';\nconst aspect_ratio = $json.aspect_ratio || '9:16';\nconst model = 'veo3_fast';\n\n// Decide which script to use\nlet final_script = '';\nif (generate_script) {\n final_script = `Based on your description: ${video_description}`;\n} else {\n final_script = custom_script || video_description;\n}\n\nreturn [{\n json: {\n video_description,\n influencer_type,\n aspect_ratio,\n model,\n final_script\n }\n}];\n"
41
+ },
42
+ "name": "Determine Final Script",
43
+ "type": "n8n-nodes-base.code",
44
+ "typeVersion": 2,
45
+ "position": [
46
+ -2208,
47
+ 128
48
+ ],
49
+ "id": "a4c9891b-1959-411a-8af5-459ef12da255"
50
+ },
51
+ {
52
+ "parameters": {
53
+ "jsCode": "const videoDesc = $json.video_description;\nconst influencerType = $json.influencer_type;\nconst script = $json.final_script;\nconst imageAnalysis = $json.response || 'casual indoor setting with natural lighting';\nconst aspectRatio = $json.aspect_ratio;\nconst referenceImageUrl = $json.reference_image_url;\nconst model = $json.model;\n\n// Create image prompt for generation\nconst imagePrompt = `emotion: relaxed and friendly\\naction: ${videoDesc}\\ncharacter: ${influencerType}\\nsetting: Casual indoor environment with natural lighting, authentic UGC style\\nstyle: iPhone selfie video, slightly uneven framing, authentic amateur quality`;\n\n// Create video prompt with dialogue\nconst videoPrompt = `dialogue: ${script}\\nemotion: Playful, authentic, genuine excitement\\naction: ${videoDesc}, speaking naturally while gesturing, making eye contact with camera\\nvoice_type: ${influencerType} casual male voice\\ncharacter: ${influencerType}\\nsetting: ${imageAnalysis}`;\n\nreturn [{\n json: {\n image_prompt: imagePrompt,\n video_prompt: videoPrompt,\n aspect_ratio: aspectRatio,\n reference_image_url: referenceImageUrl,\n model: model\n }\n}];"
54
+ },
55
+ "name": "Create Prompts",
56
+ "type": "n8n-nodes-base.code",
57
+ "typeVersion": 2,
58
+ "position": [
59
+ -2000,
60
+ 128
61
+ ],
62
+ "id": "d06ee6f4-db8d-4e76-ae32-26cd56bf5457"
63
+ },
64
+ {
65
+ "parameters": {
66
+ "method": "POST",
67
+ "url": "https://api.kie.ai/api/v1/veo/generate",
68
+ "sendHeaders": true,
69
+ "headerParameters": {
70
+ "parameters": [
71
+ {
72
+ "name": "Authorization",
73
+ "value": "Bearer {{ $env.API_KEY }}"
74
+ },
75
+ {
76
+ "name": "Content-Type",
77
+ "value": "application/json"
78
+ }
79
+ ]
80
+ },
81
+ "sendBody": true,
82
+ "bodyParameters": {
83
+ "parameters": [
84
+ {
85
+ "name": "prompt",
86
+ "value": "={{ $json.video_prompt }}"
87
+ },
88
+ {
89
+ "name": "model",
90
+ "value": "veo3_fast"
91
+ },
92
+ {
93
+ "name": "aspectRatio",
94
+ "value": "9:16"
95
+ }
96
+ ]
97
+ },
98
+ "options": {}
99
+ },
100
+ "name": "Generate Video",
101
+ "type": "n8n-nodes-base.httpRequest",
102
+ "typeVersion": 4.2,
103
+ "position": [
104
+ -1808,
105
+ 128
106
+ ],
107
+ "id": "80681c35-dc58-465b-a97d-0af508e3d8e3",
108
+ "alwaysOutputData": true
109
+ },
110
+ {
111
+ "parameters": {
112
+ "conditions": {
113
+ "options": {
114
+ "caseSensitive": true,
115
+ "leftValue": "",
116
+ "typeValidation": "strict",
117
+ "version": 1
118
+ },
119
+ "conditions": [
120
+ {
121
+ "id": "7d311e3b-504a-4904-8461-7b277f71c859",
122
+ "leftValue": "={{ $json.code }}\n\n\n\n\n",
123
+ "rightValue": "={{ 200 }}",
124
+ "operator": {
125
+ "type": "dateTime",
126
+ "operation": "equals"
127
+ }
128
+ }
129
+ ],
130
+ "combinator": "and"
131
+ },
132
+ "options": {}
133
+ },
134
+ "name": "Check Video Success",
135
+ "type": "n8n-nodes-base.if",
136
+ "typeVersion": 2,
137
+ "position": [
138
+ -1616,
139
+ 128
140
+ ],
141
+ "id": "546cb7a2-9502-4666-a403-0000eea5b95d"
142
+ },
143
+ {
144
+ "parameters": {
145
+ "url": "=https://api.kie.ai/api/v1/veo/record-info?taskId={{ $json.data.taskId }}\n",
146
+ "sendHeaders": true,
147
+ "headerParameters": {
148
+ "parameters": [
149
+ {
150
+ "name": "Authorization",
151
+ "value": "Bearer {{ $env.API_KEY }}"
152
+ },
153
+ {
154
+ "name": "Content-Type",
155
+ "value": "application/json"
156
+ }
157
+ ]
158
+ },
159
+ "options": {}
160
+ },
161
+ "name": "Get Video File",
162
+ "type": "n8n-nodes-base.httpRequest",
163
+ "typeVersion": 4.2,
164
+ "position": [
165
+ -1408,
166
+ 16
167
+ ],
168
+ "id": "83062bfd-a67a-47bd-a98b-8944a968eb02"
169
+ },
170
+ {
171
+ "parameters": {
172
+ "jsCode": "return [{\n json: {\n video_url: $json.data?.response?.resultUrls?.[0] || null,\n status: ($json.data?.successFlag === 1 && ($json.data?.errorCode == null)) ? 'completed' : 'unknown',\n task_id: $json.data?.taskId,\n resolution: $json.data?.response?.resolution || null\n }\n}];\n"
173
+ },
174
+ "name": "Output Result",
175
+ "type": "n8n-nodes-base.code",
176
+ "typeVersion": 2,
177
+ "position": [
178
+ -1216,
179
+ 16
180
+ ],
181
+ "id": "0d3f9890-60ba-45f0-bd92-8b19073bf26d"
182
+ },
183
+ {
184
+ "parameters": {
185
+ "method": "POST",
186
+ "url": "https://api.anthropic.com/v1/messages",
187
+ "authentication": "genericCredentialType",
188
+ "genericAuthType": "httpHeaderAuth",
189
+ "sendHeaders": true,
190
+ "headerParameters": {
191
+ "parameters": [
192
+ {
193
+ "name": "x-api-key",
194
+ "value": "Bearer {{ $env.API_KEY }}",
195
+ {
196
+ "name": "anthropic-version",
197
+ "value": "2023-06-01"
198
+ }
199
+ ]
200
+ },
201
+ "sendBody": true,
202
+ "specifyBody": "json",
203
+ "jsonBody": "={\n \"model\": \"claude-sonnet-4-5\",\n \"max_tokens\": 200,\n \"messages\": [{\n \"role\": \"user\",\n \"content\": \"Generate a casual UGC script for: {{ $json.video_description }}. Influencer type: {{ $json.influencer_type }}. Keep it under 200 characters, natural and conversational.\"\n }]\n}\n",
204
+ "options": {}
205
+ },
206
+ "type": "n8n-nodes-base.httpRequest",
207
+ "typeVersion": 4.2,
208
+ "position": [
209
+ -2448,
210
+ 128
211
+ ],
212
+ "id": "c0c75304-7527-4ff1-ba9e-83909fb4c5d4",
213
+ "name": "HTTP Request",
214
+ "credentials": {
215
+ "httpHeaderAuth": {
216
+ "id": "L6V0FSG3iJYjCx9v",
217
+ "name": "Header Auth account"
218
+ }
219
+ }
220
+ },
221
+ {
222
+ "parameters": {
223
+ "httpMethod": "POST",
224
+ "path": "UGC Video Generator",
225
+ "responseMode": "lastNode",
226
+ "options": {}
227
+ },
228
+ "type": "n8n-nodes-base.webhook",
229
+ "typeVersion": 2.1,
230
+ "position": [
231
+ -944,
232
+ 0
233
+ ],
234
+ "id": "5a4ed71f-82fb-45b9-ba06-12e971cf6e5d",
235
+ "name": "Webhook",
236
+ "webhookId": "2d2f24ff-f822-4786-a865-fd0f162b5db3"
237
+ },
238
+ {
239
+ "parameters": {
240
+ "formTitle": "UGC Video Creator",
241
+ "formDescription": "Create UGC (User Generated Videos) instantly — just enter your product details, influencer type, and script (or let the tool generate it automatically).",
242
+ "formFields": {
243
+ "values": [
244
+ {
245
+ "fieldLabel": "Briefly describe what happens in your video",
246
+ "fieldType": "textarea",
247
+ "placeholder": "Man reviewing a beer brand CherryBrew, holding bottle of CherryBrew and speaking enthusiastically to camera",
248
+ "requiredField": true
249
+ },
250
+ {
251
+ "fieldLabel": "Describe the type of influencer or person you’d like to promote your product — for example, their age, gender, style, tone, or audience.",
252
+ "fieldType": "textarea",
253
+ "placeholder": "28-year-old German male with short blond hair, casual tshirt, friendly and approachable appearance, speaking in English",
254
+ "requiredField": true
255
+ },
256
+ {
257
+ "fieldLabel": "Generate script automatically based on video description",
258
+ "fieldType": "checkbox",
259
+ "fieldOptions": {
260
+ "values": [
261
+ {
262
+ "option": "Generate script automatically based on video description"
263
+ }
264
+ ]
265
+ },
266
+ "limitSelection": "exact"
267
+ },
268
+ {
269
+ "fieldLabel": "Add custom script",
270
+ "placeholder": "Hey everyone! Just tried CherryBrew for the first time — and wow, it’s honestly refreshing! The cherry flavor is bold but not too sweet, and it has that perfect smooth finish. If you’re looking for something new to kick back with this weekend, CherryBrew is a must-try!"
271
+ },
272
+ {
273
+ "fieldLabel": "Choose an aspect ratio of the video",
274
+ "fieldType": "dropdown",
275
+ "fieldOptions": {
276
+ "values": [
277
+ {
278
+ "option": "9:16"
279
+ },
280
+ {
281
+ "option": "16:9"
282
+ }
283
+ ]
284
+ },
285
+ "requiredField": true
286
+ }
287
+ ]
288
+ },
289
+ "options": {}
290
+ },
291
+ "type": "n8n-nodes-base.formTrigger",
292
+ "typeVersion": 2.3,
293
+ "position": [
294
+ -3088,
295
+ 144
296
+ ],
297
+ "id": "0a537c3d-49ca-4109-8ee0-34510a5e2260",
298
+ "name": "On form submission",
299
+ "webhookId": "e835f6da-50a3-46e4-a69f-d5731b9f9323"
300
+ },
301
+ {
302
+ "parameters": {
303
+ "assignments": {
304
+ "assignments": [
305
+ {
306
+ "id": "32e61eab-e624-49fd-a4d3-f8e5231601a9",
307
+ "name": "model",
308
+ "value": "veo3_fast",
309
+ "type": "string"
310
+ }
311
+ ]
312
+ },
313
+ "includeOtherFields": true,
314
+ "options": {}
315
+ },
316
+ "type": "n8n-nodes-base.set",
317
+ "typeVersion": 3.4,
318
+ "position": [
319
+ -2912,
320
+ 144
321
+ ],
322
+ "id": "2a1ce673-e4c8-4f26-a68f-05025a1bf2fe",
323
+ "name": "Edit Fields"
324
+ }
325
+ ],
326
+ "pinData": {},
327
+ "connections": {
328
+ "Script Decision": {
329
+ "main": [
330
+ [
331
+ {
332
+ "node": "HTTP Request",
333
+ "type": "main",
334
+ "index": 0
335
+ }
336
+ ],
337
+ []
338
+ ]
339
+ },
340
+ "Create Prompts": {
341
+ "main": [
342
+ [
343
+ {
344
+ "node": "Generate Video",
345
+ "type": "main",
346
+ "index": 0
347
+ }
348
+ ]
349
+ ]
350
+ },
351
+ "Generate Video": {
352
+ "main": [
353
+ [
354
+ {
355
+ "node": "Check Video Success",
356
+ "type": "main",
357
+ "index": 0
358
+ }
359
+ ]
360
+ ]
361
+ },
362
+ "Check Video Success": {
363
+ "main": [
364
+ [
365
+ {
366
+ "node": "Get Video File",
367
+ "type": "main",
368
+ "index": 0
369
+ }
370
+ ]
371
+ ]
372
+ },
373
+ "Get Video File": {
374
+ "main": [
375
+ [
376
+ {
377
+ "node": "Output Result",
378
+ "type": "main",
379
+ "index": 0
380
+ }
381
+ ]
382
+ ]
383
+ },
384
+ "Determine Final Script": {
385
+ "main": [
386
+ [
387
+ {
388
+ "node": "Create Prompts",
389
+ "type": "main",
390
+ "index": 0
391
+ }
392
+ ]
393
+ ]
394
+ },
395
+ "HTTP Request": {
396
+ "main": [
397
+ [
398
+ {
399
+ "node": "Determine Final Script",
400
+ "type": "main",
401
+ "index": 0
402
+ }
403
+ ]
404
+ ]
405
+ },
406
+ "Edit Fields": {
407
+ "main": [
408
+ [
409
+ {
410
+ "node": "Script Decision",
411
+ "type": "main",
412
+ "index": 0
413
+ }
414
+ ]
415
+ ]
416
+ },
417
+ "On form submission": {
418
+ "main": [
419
+ [
420
+ {
421
+ "node": "Edit Fields",
422
+ "type": "main",
423
+ "index": 0
424
+ }
425
+ ]
426
+ ]
427
+ }
428
+ },
429
+ "active": false,
430
+ "settings": {
431
+ "executionOrder": "v1"
432
+ },
433
+ "versionId": "c83f8247-8049-43bd-9946-b5217115f904",
434
+ "meta": {
435
+ "templateCredsSetupCompleted": true,
436
+ "instanceId": "33add492471a02583742713d5a307b5c67421a0d97bd40b5c07ae1b0d78c2bd4"
437
+ },
438
+ "id": "eiLgIhaurAVr1z1g",
439
+ "tags": []
440
+ }
image.png ADDED