{
  "name": "ساخت و انتشار ویدیوی یوتیوب با هوش مصنوعی (Gemini + fal.ai) — v2.0",
  "nodes": [
    {
      "parameters": {
        "content": "# 📘 ساخت و انتشار ویدیوی یوتیوب با هوش مصنوعی — نسخه 2.0\n\nیک **ایده‌ی فارسی** بدهید؛ ورکفلو خودش:\n1. 🧠 با **Gemini** پرامپت حرفه‌ی ویدیو، **عنوان، توضیحات و تگ** سئو‌شده می‌نویسد\n2. 🎥 با **fal.ai** (مدل PixVerse) ویدیوی کوتاه می‌سازد\n3. ⏳ تا آماده شدن ویدیو **صبر و وضعیت را چک** می‌کند (نه یک انتظار ثابت)\n4. 📤 مستقیم در **یوتیوب** آپلود می‌کند (Shorts یا افقی) و لینک را نشان می‌دهد\n\n## مسیر کلی\n```\nفرم → Gemini (پرامپت + عنوان + توضیحات + تگ) → آماده‌سازی\n  → fal.ai: شروع ساخت → صبر ۲۰ ثانیه → وضعیت؟\n        آماده نیست → دوباره صبر (حداکثر ۱۵ دقیقه)\n        آماده شد  → دریافت نتیجه → دانلود ویدیو → آپلود یوتیوب → لینک\n```\n\n## اعتبارنامه‌ها\n| نوع | کجا | مقدار |\n|---|---|---|\n| Header Auth «Gemini API Key» | Gemini – Plan Video | `x-goog-api-key` = کلید Gemini |\n| Header Auth «fal.ai» | ۳ گره fal | Name: `Authorization` · Value: `Key کلید_fal` |\n| YouTube OAuth2 API | Upload to YouTube | Client ID/Secret از Google Cloud |\n\n---\nطراحی و آموزش: **مرتضی عظیمی** — mortezaazimi.ir",
        "height": 1120,
        "width": 700,
        "color": 4
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1320,
        -520
      ],
      "id": "272d619d-bdc5-4dd9-86ae-e32022769f82",
      "name": "📘 راهنمای کلی"
    },
    {
      "parameters": {
        "content": "## 1️⃣ از ایده تا متن\n\n**YouTube Video Form** — ایده، سبک تصویر، قالب (Shorts یا افقی)، زبان و وضعیت انتشار\n\n**Gemini – Plan Video** همه را یک‌جا می‌سازد:\n- پرامپت انگلیسی دقیق برای مدل ویدیو (یک نما، حرکت دوربین، نور، حس)\n- عنوان جذاب، توضیحات و ۸ تا ۱۲ تگ\n\n**Prepare Video** (کد):\n- برای Shorts، `#Shorts` را به عنوان و توضیحات اضافه می‌کند\n- سقف‌های یوتیوب را رعایت می‌کند (عنوان ۱۰۰، تگ‌ها ۵۰۰ کاراکتر)\n- وضعیت فارسی را به public / private / unlisted تبدیل می‌کند",
        "height": 900,
        "width": 640,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -580,
        -520
      ],
      "id": "e205a031-96c0-44ea-81c5-20ea940c30d4",
      "name": "۱ — ایده تا متن"
    },
    {
      "parameters": {
        "content": "## 2️⃣ ساخت ویدیو با fal.ai\n\n1. **fal – Start Video** درخواست را در صف fal ثبت می‌کند\n2. **Wait 20s** ← **fal – Check Status** ← **Ready?**\n   - `COMPLETED` → ادامه\n   - هنوز در صف/در حال ساخت → دوباره صبر (حداکثر ۴۵ بار ≈ ۱۵ دقیقه، بعد خطای واضح)\n3. **fal – Get Result** لینک ویدیو را می‌گیرد و **Download Video** فایل را دانلود می‌کند\n\n💡 مدل پیش‌فرض: `pixverse/v4.5/text-to-video/fast` (۷۲۰p). مدل دیگری می‌خواهید؟ فقط آدرس گره Start Video را عوض کنید؛ بقیه خودکار کار می‌کند.\n💰 هزینه‌ی هر ویدیو را در صفحه‌ی مدل در fal.ai ببینید.",
        "height": 1000,
        "width": 1020,
        "color": 5
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        100,
        -620
      ],
      "id": "767dc81b-8bdd-48c8-b29b-dc910ff3d6a9",
      "name": "۲ — ساخت ویدیو"
    },
    {
      "parameters": {
        "content": "## 3️⃣ آپلود در یوتیوب\n\n**Upload to YouTube** — فایل را با عنوان، توضیحات، تگ‌ها و وضعیت انتشار آپلود می‌کند.\n- `Region Code` و `Category` را به دلخواه تغییر دهید (پیش‌فرض: US و 24 = Entertainment)\n\n**Done Page** — لینک ویدیو را نشان می‌دهد.\n\n⚠️ پروژه‌های تأییدنشده‌ی Google Cloud فقط می‌توانند ویدیوی **خصوصی** آپلود کنند تا وقتی که API Audit یوتیوب را بگذرانید. تا آن موقع، ویدیو را بعد از آپلود از YouTube Studio عمومی کنید.\n⚠️ برای ویدیوهای واقع‌نما، در Studio گزینه‌ی **Altered or synthetic content** را بزنید.",
        "height": 900,
        "width": 560,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1160,
        -520
      ],
      "id": "387bd751-6a12-40b9-91f9-66a88098799e",
      "name": "۳ — یوتیوب"
    },
    {
      "parameters": {
        "formTitle": "ساخت ویدیوی یوتیوب با هوش مصنوعی",
        "formDescription": "ایده‌ی ویدیو را به فارسی بنویسید؛ هوش مصنوعی ویدیو، عنوان، توضیحات و تگ‌ها را می‌سازد و در یوتیوب آپلود می‌کند. ساخت ویدیو چند دقیقه طول می‌کشد؛ این صفحه را نبندید.",
        "formFields": {
          "values": [
            {
              "fieldLabel": "ایده‌ی ویدیو",
              "fieldType": "textarea",
              "requiredField": true,
              "placeholder": "مثلاً: یک فنجان قهوه که در یک صبح بارانی کنار پنجره بخار می‌کند"
            },
            {
              "fieldLabel": "سبک تصویر",
              "fieldType": "dropdown",
              "requiredField": true,
              "fieldOptions": {
                "values": [
                  {
                    "option": "Cinematic realistic"
                  },
                  {
                    "option": "Anime"
                  },
                  {
                    "option": "3D animation (Pixar-like)"
                  },
                  {
                    "option": "Claymation"
                  },
                  {
                    "option": "Comic book"
                  },
                  {
                    "option": "Cyberpunk neon"
                  },
                  {
                    "option": "Watercolor painting"
                  }
                ]
              }
            },
            {
              "fieldLabel": "قالب ویدیو",
              "fieldType": "dropdown",
              "requiredField": true,
              "fieldOptions": {
                "values": [
                  {
                    "option": "Shorts عمودی (9:16)"
                  },
                  {
                    "option": "ویدیوی افقی (16:9)"
                  }
                ]
              }
            },
            {
              "fieldLabel": "زبان عنوان و توضیحات",
              "fieldType": "dropdown",
              "requiredField": true,
              "fieldOptions": {
                "values": [
                  {
                    "option": "فارسی"
                  },
                  {
                    "option": "English"
                  }
                ]
              }
            },
            {
              "fieldLabel": "وضعیت انتشار",
              "fieldType": "dropdown",
              "requiredField": true,
              "fieldOptions": {
                "values": [
                  {
                    "option": "خصوصی (برای بازبینی)"
                  },
                  {
                    "option": "فهرست‌نشده (فقط با لینک)"
                  },
                  {
                    "option": "عمومی"
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "appendAttribution": false,
          "buttonLabel": "بساز و آپلود کن 🎬"
        }
      },
      "type": "n8n-nodes-base.formTrigger",
      "typeVersion": 2.2,
      "position": [
        -520,
        40
      ],
      "id": "70e7697e-42f9-45f6-8252-10b4e24c25d2",
      "name": "YouTube Video Form",
      "webhookId": "8ab64698-95b6-42a6-9014-cdd462295e08"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash-lite:generateContent",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({\n  systemInstruction: { parts: [{ text: \"You are a YouTube video producer and a prompt engineer for text-to-video AI models.\\nFrom the user's idea, create:\\n\\n1. \\\"prompt\\\": an English text-to-video prompt (60-110 words) for a ~5 second clip.\\n   - ONE continuous shot. Describe subject, action, setting, camera movement, lighting, mood and the requested visual style.\\n   - Concrete, visual and vivid. No on-screen text, captions, logos, watermarks or real celebrities.\\n2. \\\"title\\\": an attention-grabbing YouTube title in the requested language, max 80 characters, curiosity-driven, no clickbait lies, no hashtags.\\n3. \\\"description\\\": 2-4 short lines in the requested language that describe the video and invite viewers to like and subscribe, then 3 relevant hashtags on the last line.\\n4. \\\"tags\\\": 8 to 12 relevant search tags in the requested language (and a few English ones), no # sign.\\n\\nReturn JSON only.\" }] },\n  contents: [{ role: 'user', parts: [{ text:\n    'Video idea: ' + $('YouTube Video Form').first().json['ایده‌ی ویدیو'] + '\\n' +\n    'Visual style: ' + $('YouTube Video Form').first().json['سبک تصویر'] + '\\n' +\n    'Format: ' + $('YouTube Video Form').first().json['قالب ویدیو'] + '\\n' +\n    'Language for title, description and tags: ' + ($('YouTube Video Form').first().json['زبان عنوان و توضیحات'] === 'English' ? 'English' : 'Persian (Farsi)')\n  }] }],\n  generationConfig: {\n    responseMimeType: 'application/json',\n    responseSchema: { type: 'OBJECT', properties: {\n      prompt: { type: 'STRING' }, title: { type: 'STRING' }, description: { type: 'STRING' },\n      tags: { type: 'ARRAY', items: { type: 'STRING' } }\n    }, required: ['prompt', 'title', 'description', 'tags'] }\n  }\n}) }}",
        "options": {
          "timeout": 60000
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -300,
        40
      ],
      "id": "30b01963-c04c-48e0-b266-d0a9fe6d842a",
      "name": "Gemini – Plan Video"
    },
    {
      "parameters": {
        "jsCode": "// خروجی Gemini را برای fal.ai و یوتیوب آماده می‌کند\nconst f = $('YouTube Video Form').first().json;\nconst parts = $input.first().json.candidates?.[0]?.content?.parts || [];\nconst raw = parts.filter(p => p.text && !p.thought).map(p => p.text).join('').replace(/^```(?:json)?/i, '').replace(/```$/, '').trim();\nlet ai;\ntry { ai = JSON.parse(raw); } catch (e) { throw new Error('خروجی Gemini قابل خواندن نبود: ' + raw.slice(0, 200)); }\nif (!ai.prompt || !ai.title) throw new Error('Gemini پرامپت یا عنوان برنگرداند.');\n\nconst vertical = String(f['قالب ویدیو'] || '').includes('9:16');\nconst privacy = { 'عمومی': 'public', 'خصوصی': 'private', 'فهرست‌نشده': 'unlisted' }[String(f['وضعیت انتشار'] || '').split(' ')[0]] || 'private';\nconst clean = s => String(s || '').replace(/[<>]/g, '').trim();               // یوتیوب < و > را قبول نمی‌کند\n\nlet title = clean(ai.title);\nif (vertical && !/#shorts/i.test(title) && title.length <= 90) title += ' #Shorts';\ntitle = title.slice(0, 100);\n\nlet description = clean(ai.description);\nif (vertical && !/#shorts/i.test(description)) description += '\\n\\n#Shorts';\ndescription = description.slice(0, 4900);\n\n// تگ‌ها: بدون # و کاما، مجموع کمتر از ۵۰۰ کاراکتر\nconst tags = []; let len = 0;\nfor (const t of (Array.isArray(ai.tags) ? ai.tags : String(ai.tags || '').split(','))) {\n  const s = clean(t).replace(/^#/, '').replace(/,/g, ' ').replace(/\\s+/g, ' ').trim();\n  if (!s || tags.includes(s) || len + s.length + 1 > 480) continue;\n  tags.push(s); len += s.length + 1;\n}\n\nreturn [{ json: {\n  videoPrompt: ai.prompt.trim(),\n  aspectRatio: vertical ? '9:16' : '16:9',\n  privacy, title, description, tags: tags.join(','),\n} }];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -80,
        40
      ],
      "id": "f51ecbd0-b00b-4857-91e1-b4ad5496d44b",
      "name": "Prepare Video"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://queue.fal.run/fal-ai/pixverse/v4.5/text-to-video/fast",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({\n  prompt: $json.videoPrompt,\n  aspect_ratio: $json.aspectRatio,\n  resolution: '720p',\n  negative_prompt: 'blurry, low quality, low resolution, pixelated, noisy, distorted faces, extra limbs, text, watermark, logo'\n}) }}"
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        160,
        40
      ],
      "id": "505c4359-3ab1-4aad-abe9-944cf7d4da39",
      "name": "fal – Start Video"
    },
    {
      "parameters": {
        "amount": 20,
        "unit": "seconds"
      },
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        380,
        40
      ],
      "id": "cdbc39d7-8b6d-4908-87bd-90faa1f159c3",
      "name": "Wait 20s",
      "webhookId": "56fb891b-6507-4f65-b046-bec9ec063e5a"
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{ $('fal – Start Video').first().json.status_url }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        600,
        40
      ],
      "id": "1992f41e-ab34-4fec-b925-e98de38def65",
      "name": "fal – Check Status"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "0db34365-6f6b-42c4-bdc4-3f7d5b346152",
              "leftValue": "={{ $json.status }}",
              "rightValue": "COMPLETED",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        820,
        40
      ],
      "id": "a64b2d77-e335-47d6-9d19-a032e9412ca0",
      "name": "Ready?"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "17d26048-4388-4526-9084-bc67303038fd",
              "leftValue": "={{ $runIndex }}",
              "rightValue": 45,
              "operator": {
                "type": "number",
                "operation": "gte"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        820,
        280
      ],
      "id": "a10095fc-1b20-4ef9-af48-fb2abdef0856",
      "name": "Timed Out?"
    },
    {
      "parameters": {
        "errorMessage": "ساخت ویدیو بیش از ۱۵ دقیقه طول کشید. وضعیت درخواست را در داشبورد fal.ai بررسی کنید."
      },
      "type": "n8n-nodes-base.stopAndError",
      "typeVersion": 1,
      "position": [
        1040,
        360
      ],
      "id": "62453345-0d04-4ef3-8c77-b0f210853976",
      "name": "Stop: Too Slow"
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{ $('fal – Start Video').first().json.response_url }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1040,
        -60
      ],
      "id": "7ad43068-052c-431a-9df4-7730c2bd627a",
      "name": "fal – Get Result"
    },
    {
      "parameters": {
        "url": "={{ $json.video.url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          },
          "timeout": 120000
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1260,
        -60
      ],
      "id": "0293dcdb-69ea-4b28-9c0c-2015c51418fc",
      "name": "Download Video"
    },
    {
      "parameters": {
        "resource": "video",
        "operation": "upload",
        "title": "={{ $('Prepare Video').first().json.title }}",
        "regionCode": "US",
        "categoryId": "24",
        "options": {
          "description": "={{ $('Prepare Video').first().json.description }}",
          "privacyStatus": "={{ $('Prepare Video').first().json.privacy }}",
          "tags": "={{ $('Prepare Video').first().json.tags }}",
          "selfDeclaredMadeForKids": false
        }
      },
      "type": "n8n-nodes-base.youTube",
      "typeVersion": 1,
      "position": [
        1480,
        -60
      ],
      "id": "42a262bb-890e-4ec6-a7fa-5f8148b62f66",
      "name": "Upload to YouTube"
    },
    {
      "parameters": {
        "operation": "completion",
        "respondWith": "showText",
        "responseText": "=<div dir=\"rtl\" style=\"font-family:Tahoma,Vazirmatn,sans-serif;text-align:center;padding:24px;color:#0f0f0f\">\n<div style=\"font-size:52px;line-height:1\">🎬</div>\n<h2 style=\"margin:10px 0 6px\">ویدیو در یوتیوب آپلود شد</h2>\n<p style=\"margin:0 0 6px\"><b>{{ $('Prepare Video').first().json.title }}</b></p>\n<p style=\"color:#606060;margin:0 0 18px\">وضعیت: {{ { public: 'عمومی', private: 'خصوصی', unlisted: 'فهرست‌نشده' }[$('Prepare Video').first().json.privacy] }}</p>\n<a href=\"https://youtu.be/{{ $json.uploadId }}\" target=\"_blank\" style=\"display:inline-block;padding:12px 28px;border-radius:999px;background:#ff0033;color:#fff;text-decoration:none;font-weight:bold\">مشاهده در یوتیوب ↗</a>\n<p style=\"color:#909090;font-size:13px;margin-top:14px\">ممکن است پردازش ویدیو در یوتیوب چند دقیقه طول بکشد.</p>\n</div>"
      },
      "type": "n8n-nodes-base.form",
      "typeVersion": 1,
      "position": [
        1700,
        -60
      ],
      "id": "de0709ca-5cef-407a-9335-f1532228dcb7",
      "name": "Done Page",
      "webhookId": "05dbbf2c-d58a-4ddb-b227-65652578a3e5"
    }
  ],
  "pinData": {},
  "connections": {
    "YouTube Video Form": {
      "main": [
        [
          {
            "node": "Gemini – Plan Video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini – Plan Video": {
      "main": [
        [
          {
            "node": "Prepare Video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Video": {
      "main": [
        [
          {
            "node": "fal – Start Video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fal – Start Video": {
      "main": [
        [
          {
            "node": "Wait 20s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 20s": {
      "main": [
        [
          {
            "node": "fal – Check Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fal – Check Status": {
      "main": [
        [
          {
            "node": "Ready?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ready?": {
      "main": [
        [
          {
            "node": "fal – Get Result",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Timed Out?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Timed Out?": {
      "main": [
        [
          {
            "node": "Stop: Too Slow",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait 20s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fal – Get Result": {
      "main": [
        [
          {
            "node": "Download Video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Video": {
      "main": [
        [
          {
            "node": "Upload to YouTube",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to YouTube": {
      "main": [
        [
          {
            "node": "Done Page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "tags": []
}