{
  "id": "G4Tu4Kv4tN0OH9Jp",
  "name": "Faceless YouTube Shorts \u2014 Daily Autopilot (Groq + SamAutomation)",
  "tags": [],
  "nodes": [
    {
      "id": "99962acb-93b6-4c11-ab57-f97987a9bebb",
      "name": "Daily Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        48,
        816
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 10 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "d8041c0b-cdda-440e-a612-23eac0c79840",
      "name": "Read Config",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        304,
        816
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Config"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "bdf6fe4b-d53e-401b-bc13-8999c98ad863",
      "name": "Generate Topics",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        560,
        816
      ],
      "parameters": {
        "url": "https://api.groq.com/openai/v1/chat/completions",
        "method": "POST",
        "options": {
          "timeout": 30000
        },
        "jsonBody": "={\n  \"model\": \"llama-3.3-70b-versatile\",\n  \"temperature\": 0.9,\n  \"max_tokens\": 2000,\n  \"response_format\": { \"type\": \"json_object\" },\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"You are a viral YouTube Shorts strategist. Generate unique scroll-stopping topics. Respond in valid JSON only.\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"Generate 3 YouTube Shorts topics.\\nNiche: {{ $json.selected_niche }}\\nSub-niche: {{ $json.selected_sub_niche }}\\n\\nFor EACH topic:\\n- topic_title (max 60 chars, curiosity-driven)\\n- hook_line (first 3 sec, max 10 words)\\n- angle (unique spin)\\n- target_emotion (curiosity/shock/awe/fear/humor)\\n- search_keywords (5 SEO keywords array)\\n\\nReturn: { \\\"topics\\\": [...] }\"\n    }\n  ]\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "e7df6c01-8a6e-4f0e-a0f0-f146773f2dbd",
      "name": "Parse Topic",
      "type": "n8n-nodes-base.code",
      "position": [
        800,
        816
      ],
      "parameters": {
        "jsCode": "const resp = $input.first().json;\nconst topics = JSON.parse(resp.choices[0].message.content).topics;\nconst t = topics[0];\nconst cfg = $('Read Config').first().json;\n\nreturn [{ json: {\n  topic_title: t.topic_title,\n  hook_line: t.hook_line,\n  angle: t.angle,\n  target_emotion: t.target_emotion,\n  search_keywords: t.search_keywords,\n  selected_niche: cfg.selected_niche || '',\n  selected_sub_niche: cfg.selected_sub_niche || '',\n  voice_id: cfg.voice_id || 'en-US-ChristopherNeural'\n}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "86d8a973-8dad-4012-bbe0-47460aca521a",
      "name": "Log Topic",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1056,
        816
      ],
      "parameters": {
        "columns": {
          "value": {
            "date": "={{ $now.format('yyyy-MM-dd') }}",
            "angle": "={{ $json.angle }}",
            "niche": "={{ $json.selected_niche }}",
            "status": "scripting",
            "hook_line": "={{ $json.hook_line }}",
            "topic_title": "={{ $json.topic_title }}",
            "target_emotion": "={{ $json.target_emotion }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Topic Bank"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "6baa3160-d53a-4199-9638-ed6fac145e49",
      "name": "Write Script",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1312,
        816
      ],
      "parameters": {
        "url": "https://api.groq.com/openai/v1/chat/completions",
        "method": "POST",
        "options": {
          "timeout": 30000
        },
        "jsonBody": "={\n  \"model\": \"llama-3.3-70b-versatile\",\n  \"temperature\": 0.7,\n  \"max_tokens\": 2500,\n  \"response_format\": { \"type\": \"json_object\" },\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"You write viral YouTube Shorts scripts for faceless channels. Punchy, conversational, optimized for retention. Respond in valid JSON only.\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"Write a YouTube Shorts script.\\nTopic: {{ $json.topic_title }}\\nHook: {{ $json.hook_line }}\\nAngle: {{ $json.angle }}\\nEmotion: {{ $json.target_emotion }}\\nNiche: {{ $json.selected_niche }}\\n\\nRULES:\\n- 80-130 words (30-60 sec)\\n- HOOK (5-8 words) then BODY (3-4 short paras) then CTA\\n- Short sentences, no filler\\n- Add [SCENE: description] tags between paragraphs for AI image generation\\n- Scene descriptions must be SPECIFIC and VISUAL\\n\\nALSO GENERATE:\\n- youtube_title (max 60 chars, 1 emoji)\\n- youtube_description (150 words with keywords)\\n- tags (15 YouTube tags array)\\n- hashtags (3 including #shorts)\\n\\nReturn JSON: { \\\"clean_script\\\": \\\"narration only\\\", \\\"scenes\\\": [{\\\"scene_number\\\":1,\\\"description\\\":\\\"...\\\",\\\"narration\\\":\\\"...\\\"}], \\\"youtube_title\\\":\\\"...\\\", \\\"youtube_description\\\":\\\"...\\\", \\\"tags\\\":[...], \\\"hashtags\\\":[...] }\\n\\nIMPORTANT: Each scene object MUST have a \\\"narration\\\" field with that scene's voiceover text.\"\n    }\n  ]\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "bbbebccc-6fd4-485f-b782-54cea5cdab14",
      "name": "Build Video Payload",
      "type": "n8n-nodes-base.code",
      "position": [
        1552,
        816
      ],
      "parameters": {
        "jsCode": "const resp = $input.first().json;\nconst script = JSON.parse(resp.choices[0].message.content);\nconst prev = $('Parse Topic').first().json;\n\n// Build SamAutomation scenes with built-in AI image generation\n// No external Pollinations needed \u2014 SamAutomation generates images via Flux\nconst scenes = script.scenes.map((scene, i) => {\n  return {\n    \"elements\": [\n      {\n        \"type\": \"image\",\n        \"model\": \"flux-pro\",\n        \"prompt\": scene.description + ', photorealistic, cinematic lighting, 8K, vertical 9:16, no text, vivid colors',\n        \"aspect-ratio\": \"vertical\",\n        \"resize\": \"cover\",\n        \"zoom\": 5,\n        \"duration\": -1\n      },\n      {\n        \"type\": \"voice\",\n        \"text\": scene.narration || script.clean_script.split('.').slice(i, i+2).join('.'),\n        \"voice\": prev.voice_id || \"en-US-ChristopherNeural\"\n      }\n    ]\n  };\n});\n\n// Build full SamAutomation render payload\nconst payload = {\n  \"comment\": script.youtube_title || prev.topic_title,\n  \"resolution\": \"custom\",\n  \"width\": 1080,\n  \"height\": 1920,\n  \"quality\": \"high\",\n  \"scenes\": scenes,\n  \"elements\": [\n    {\n      \"type\": \"subtitles\",\n      \"settings\": {\n        \"type\": \"word\",\n        \"position\": \"bottom-center\",\n        \"font-family\": \"Montserrat\",\n        \"font-weight\": \"800\",\n        \"font-size\": \"8vw\",\n        \"font-color\": \"#FFFFFF\",\n        \"outline-color\": \"#000000\",\n        \"outline-width\": 3,\n        \"margin-bottom\": \"15vh\"\n      }\n    }\n  ]\n};\n\nreturn [{ json: {\n  render_payload: payload,\n  youtube_title: script.youtube_title,\n  youtube_description: script.youtube_description,\n  tags: script.tags,\n  hashtags: script.hashtags,\n  topic_title: prev.topic_title,\n  selected_niche: prev.selected_niche\n}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "06aa7164-8cde-49f9-b507-8197cc0f4293",
      "name": "Render Video \u2014 SamAutomation",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1808,
        816
      ],
      "parameters": {
        "url": "https://samautomation.work/api/render",
        "method": "POST",
        "options": {
          "timeout": 60000
        },
        "jsonBody": "={{ JSON.stringify($json.render_payload) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "853b38d6-4742-41c9-b057-b08af1886256",
      "name": "Wait 30s",
      "type": "n8n-nodes-base.wait",
      "position": [
        2048,
        816
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "d57e734a-4ef9-4520-9dda-55056db28f34",
      "name": "Check Render Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2304,
        816
      ],
      "parameters": {
        "url": "=https://samautomation.work/api/render/{{ $('Render Video \u2014 SamAutomation').first().json.project }}",
        "options": {
          "timeout": 30000
        },
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "1038ec5b-cc9e-4588-80c2-4548f4bb492c",
      "name": "Video Ready?",
      "type": "n8n-nodes-base.if",
      "position": [
        2560,
        816
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond1",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "done"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "4cfb3a36-b78a-4c89-8902-ce13d7705e2d",
      "name": "Wait More",
      "type": "n8n-nodes-base.wait",
      "position": [
        2800,
        1024
      ],
      "parameters": {
        "amount": 15
      },
      "typeVersion": 1.1
    },
    {
      "id": "1671d570-59f4-408f-98d1-685d054d54b1",
      "name": "Prepare Upload",
      "type": "n8n-nodes-base.code",
      "position": [
        2816,
        816
      ],
      "parameters": {
        "jsCode": "const status = $input.first().json;\nconst meta = $('Build Video Payload').first().json;\n\nreturn [{ json: {\n  video_url: status.url,\n  video_duration: status.duration,\n  youtube_title: meta.youtube_title,\n  youtube_description: meta.youtube_description,\n  tags: meta.tags,\n  hashtags: meta.hashtags,\n  topic_title: meta.topic_title,\n  selected_niche: meta.selected_niche\n}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "3852ba9e-fe87-43af-86e3-e0d266de79a5",
      "name": "Upload to YouTube",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3056,
        816
      ],
      "parameters": {
        "url": "https://www.googleapis.com/upload/youtube/v3/videos?uploadType=multipart&part=snippet,status",
        "method": "POST",
        "options": {
          "timeout": 120000
        },
        "jsonBody": "={\n  \"snippet\": {\n    \"title\": \"{{ $json.youtube_title }}\",\n    \"description\": \"{{ $json.youtube_description }}\",\n    \"tags\": {{ JSON.stringify($json.tags || []) }},\n    \"categoryId\": \"22\",\n    \"defaultLanguage\": \"en\"\n  },\n  \"status\": {\n    \"privacyStatus\": \"public\",\n    \"selfDeclaredMadeForKids\": false\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api"
      },
      "typeVersion": 4.2
    },
    {
      "id": "5056345f-9a83-42e0-856d-c78d1a0f6ed6",
      "name": "Update Topic Bank",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3312,
        816
      ],
      "parameters": {
        "columns": {
          "value": {
            "status": "published",
            "published_at": "={{ $now.toISO() }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {
          "cellFormat": "USER_ENTERED"
        },
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Topic Bank"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "ed2ed14e-c15d-4360-91da-5cb6f0e8a5e9",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        336
      ],
      "parameters": {
        "color": 5,
        "width": 552,
        "height": 796,
        "content": "## Faceless YouTube Shorts - Daily Autopilot\n\nFully automated pipeline that generates and uploads 1 faceless YouTube Short per day. Zero camera, zero editing, zero manual work.\n\nPipeline: Schedule (10 AM daily) - Groq topic - Groq script - SamAutomation (AI images + TTS + subtitles + render) -YouTube upload - Google Sheets tracking\n\nMonthly cost: ~$33 (SamAutomation plan). Groq and YouTube API are free.\n\nSamAutomation handles AI image generation (Flux), voiceover (TTS), AutoCaptions, and video rendering- all in one API call."
      },
      "typeVersion": 1
    },
    {
      "id": "b8474c53-03fe-4f46-b8c6-f66b29d4cea3",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        336
      ],
      "parameters": {
        "color": 3,
        "width": 928,
        "height": 796,
        "content": "### AI Script Engine\n\nGenerate Topics - Groq LLaMA generates 3 unique topic ideas with hooks, angles, and target emotions. Parse Topic picks the first one.\n\nLog Topic - Saves the selected topic to your Google Sheet \"Topic Bank\" tab with today's date and status \"scripting\". Helps you track what has been posted and avoid repeats.\n\nWrite Script - Groq writes the full voiceover script with scene-by-scene image descriptions, plus YouTube title, description, 15 tags, and hashtags. Each scene has a \"narration\" field for the voiceover and a \"description\" field for AI image generation.\n\nCustomization: Change your niche and sub-niche directly in the Google Sheet Config tab. No workflow editing needed. Voice options: en-US-ChristopherNeural (deep, default), en-US-GuyNeural (calm), en-GB-RyanNeural (British), en-US-JennyNeural (female)."
      },
      "typeVersion": 1
    },
    {
      "id": "1ffee3fa-066c-448b-87ad-160093351342",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1504,
        336
      ],
      "parameters": {
        "color": 4,
        "width": 672,
        "height": 804,
        "content": "### Video Rendering - SamAutomation\n\nBuild Video Payload - Converts the script into a SamAutomation render payload. Each scene gets:\n\n- AI-generated image via Flux model (1080x1920, photorealistic, cinematic)\n- TTS voiceover using Microsoft Neural voice\n- Word-level animated subtitles (Montserrat Bold, white + black outline)\n\nNo external image API needed. SamAutomation generates images, adds voice, burns subtitles, and renders the final MP4 \u2014 all in one API call.\n\nRender + Poll \u2014 SamAutomation renders the video in the cloud, usually 30-60 seconds. The polling loop checks every 15 seconds until status is \"done\". Once ready, the hosted MP4 URL passes to YouTube upload."
      },
      "typeVersion": 1
    },
    {
      "id": "d8134ecf-f038-4684-9e95-9208cf8deba3",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2784,
        336
      ],
      "parameters": {
        "color": 6,
        "width": 648,
        "height": 828,
        "content": "### YouTube Upload + Tracking\n\nUpload - Posts the rendered video to YouTube with AI-generated title, description, tags, and category. Privacy is set to public by default. Change to \"private\" or \"unlisted\" in the Upload to YouTube node if you want to review before publishing.\n\nTopic Bank - Google Sheet automatically updates the topic status from \"scripting\" to \"published\" with a timestamp after successful upload. Use this to track your content calendar and spot repeats.\n\nSchedule - Runs at 10 AM daily. Each run generates a fresh topic and publishes one Short. 30 Shorts per month stays well within SamAutomation's 50 render limit.\n\nRate limits: YouTube allows ~6 uploads/day, Groq gives 14,400 requests/day, SamAutomation gives 50 renders + ~245 AI generations per month. At 1 Short/day you are well within all limits."
      },
      "typeVersion": 1
    },
    {
      "id": "bf4f4587-b8a5-4f8e-b4b0-2e55a6a822a1",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -704,
        480
      ],
      "parameters": {
        "width": 560,
        "height": 432,
        "content": "## Credentials needed :\n1. Groq API Key - Header Auth, name: Authorization, value: Bearer YOUR_KEY (free at console.groq.com)\n2. SamAutomation API Key - Header Auth, name: X-API-Key, value: YOUR_KEY (from samautomation.work/register)\n3. Google Sheets - OAuth2, connect your Google account\n4. YouTube Upload - OAuth2, enable YouTube Data API v3 in Google Cloud, scopes: youtube.upload + youtube\n\n### Google Sheet setup:\nCreate one Google Sheet with 2 tabs.\nTab 1 \"Config\" - columns: selected_niche, selected_sub_niche, voice_id\nTab 2 \"Topic Bank\" - columns: date, niche, topic_title, hook_line, angle, target_emotion, status, published_at\n\nPaste your Sheet URL into all 3 Google Sheets nodes (Read Config, Log Topic, Update Topic Bank)."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "7fe56779-d60e-417e-9021-7c74bcc4a845",
  "connections": {
    "Wait 30s": {
      "main": [
        [
          {
            "node": "Check Render Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Topic": {
      "main": [
        [
          {
            "node": "Write Script",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait More": {
      "main": [
        [
          {
            "node": "Check Render Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Topic": {
      "main": [
        [
          {
            "node": "Log Topic",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Config": {
      "main": [
        [
          {
            "node": "Generate Topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Video Ready?": {
      "main": [
        [
          {
            "node": "Prepare Upload",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait More",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write Script": {
      "main": [
        [
          {
            "node": "Build Video Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Schedule": {
      "main": [
        [
          {
            "node": "Read Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Upload": {
      "main": [
        [
          {
            "node": "Upload to YouTube",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Topics": {
      "main": [
        [
          {
            "node": "Parse Topic",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to YouTube": {
      "main": [
        [
          {
            "node": "Update Topic Bank",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Video Payload": {
      "main": [
        [
          {
            "node": "Render Video \u2014 SamAutomation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Render Status": {
      "main": [
        [
          {
            "node": "Video Ready?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Render Video \u2014 SamAutomation": {
      "main": [
        [
          {
            "node": "Wait 30s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}