{
  "id": "aj7L45Zqn586ui0I",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true
  },
  "name": "Hacker News to video content with Blotato",
  "tags": [],
  "nodes": [
    {
      "id": "94b28c63-653b-450e-b954-abb56c809006",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -576,
        16
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "5c9641f8-1f0f-4471-8e2e-6f3aa31d3712",
      "name": "Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -384,
        16
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cfg-01",
              "name": "topic_keyword",
              "type": "string",
              "value": "AI"
            },
            {
              "id": "cfg-02",
              "name": "articles_to_scan",
              "type": "number",
              "value": 20
            },
            {
              "id": "cfg-03",
              "name": "atlas_model",
              "type": "string",
              "value": "google/veo3.1-fast/text-to-video"
            },
            {
              "id": "cfg-04",
              "name": "video_duration",
              "type": "number",
              "value": 8
            },
            {
              "id": "cfg-05",
              "name": "aspect_ratio",
              "type": "string",
              "value": "9:16"
            },
            {
              "id": "cfg-06",
              "name": "resolution",
              "type": "string",
              "value": "720p"
            },
            {
              "id": "cfg-07",
              "name": "poll_wait_seconds",
              "type": "number",
              "value": 30
            },
            {
              "id": "cfg-08",
              "name": "tiktok_privacy_level",
              "type": "string",
              "value": "PUBLIC_TO_EVERYONE"
            },
            {
              "id": "cfg-09",
              "name": "output_language",
              "type": "string",
              "value": "English"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "c5d083bb-0d0c-43e0-8353-d5818769a75d",
      "name": "Fetch Hacker News front page",
      "type": "n8n-nodes-base.hackerNews",
      "position": [
        -160,
        16
      ],
      "parameters": {
        "limit": "={{ $(\"Configuration\").item.json.articles_to_scan }}",
        "resource": "all",
        "additionalFields": {
          "tags": [
            "front_page"
          ],
          "keyword": "={{ $(\"Configuration\").item.json.topic_keyword }}"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ffb24fa1-fa6f-4dbe-8206-7cc54e7af885",
      "name": "Combine stories into one item",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        64,
        16
      ],
      "parameters": {
        "include": "specifiedFields",
        "options": {},
        "aggregate": "aggregateAllItemData",
        "fieldsToInclude": "title,url,num_comments,created_at",
        "destinationFieldName": "stories"
      },
      "typeVersion": 1
    },
    {
      "id": "f83d7f8d-7a6b-478e-81f9-73df9b61c992",
      "name": "Pick best story and write video brief",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        256,
        16
      ],
      "parameters": {
        "text": "=Here are the trending Hacker News stories right now:\n{{ JSON.stringify($json.stories) }}\n\n1. Pick the ONE story that is the most exciting for an audience passionate about AI and automation.\n2. Write a cinematic, visually rich text-to-video prompt (max 80 words) that illustrates this story for a {{ $(\"Configuration\").item.json.aspect_ratio }} short-form video. Describe scenes, camera movement and mood. No text overlays, no logos, no real people.\n3. Write a catchy video title (under 90 characters) and a short caption with a hook, both in {{ $(\"Configuration\").item.json.output_language }}.\n4. Return 3-5 relevant hashtags.",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "You are a viral short-form video strategist for a tech media brand. You turn tech news into scroll-stopping AI video concepts. Always follow the requested output format exactly."
            }
          ]
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.9
    },
    {
      "id": "e6a6e4d2-8f23-4d9b-bc1e-95ed7511390a",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        256,
        176
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-mini",
          "cachedResultName": "gpt-5-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "c195eaf3-7739-4b89-8740-5228379a8e91",
      "name": "Video Brief Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        400,
        208
      ],
      "parameters": {
        "jsonSchemaExample": "{\"selected_title\": \"The chosen Hacker News story title\", \"selected_url\": \"https://example.com/story\", \"video_prompt\": \"Cinematic vertical video prompt describing scenes, camera moves and mood\", \"video_title\": \"Catchy YouTube Shorts title under 90 characters\", \"video_caption\": \"Short engaging caption for YouTube and TikTok\", \"hashtags\": \"#AI #automation #technews\"}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "b9966e68-0c39-4fba-9497-f1d52036d4b8",
      "name": "Start AI video generation",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        640,
        16
      ],
      "parameters": {
        "url": "https://api.atlascloud.ai/api/v1/model/generateVideo",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"model\": \"{{ $(\"Configuration\").item.json.atlas_model }}\",\n  \"prompt\": {{ JSON.stringify($json.output.video_prompt) }},\n  \"duration\": {{ $(\"Configuration\").item.json.video_duration }},\n  \"aspect_ratio\": \"{{ $(\"Configuration\").item.json.aspect_ratio }}\",\n  \"resolution\": \"{{ $(\"Configuration\").item.json.resolution }}\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "10f503fe-d3cf-4b5c-9cf6-84358f69206a",
      "name": "Wait before checking status",
      "type": "n8n-nodes-base.wait",
      "position": [
        832,
        16
      ],
      "parameters": {
        "amount": "={{ $(\"Configuration\").item.json.poll_wait_seconds }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "838acb5b-6637-497b-9630-19d43537c06b",
      "name": "Check video status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1024,
        16
      ],
      "parameters": {
        "url": "=https://api.atlascloud.ai/api/v1/model/prediction/{{ $(\"Start AI video generation\").first().json.data.id }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "3d9d6b39-36e9-497b-bc0f-d78ccef79c12",
      "name": "Route on video status",
      "type": "n8n-nodes-base.switch",
      "position": [
        1200,
        0
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "completed",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "or",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.status }}",
                    "rightValue": "completed"
                  },
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.status }}",
                    "rightValue": "succeeded"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "failed",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "or",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.status }}",
                    "rightValue": "failed"
                  },
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.status }}",
                    "rightValue": "error"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "still processing"
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "45a90406-c168-4699-a9d5-dc094c64a838",
      "name": "Prepare post content",
      "type": "n8n-nodes-base.set",
      "position": [
        1696,
        -16
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "post-01",
              "name": "video_url",
              "type": "string",
              "value": "={{ $json.data.outputs[0] }}"
            },
            {
              "id": "post-02",
              "name": "video_title",
              "type": "string",
              "value": "={{ $(\"Pick best story and write video brief\").first().json.output.video_title }}"
            },
            {
              "id": "post-03",
              "name": "video_caption",
              "type": "string",
              "value": "={{ $(\"Pick best story and write video brief\").first().json.output.video_caption }} {{ $(\"Pick best story and write video brief\").first().json.output.hashtags }}"
            },
            {
              "id": "post-04",
              "name": "source_title",
              "type": "string",
              "value": "={{ $(\"Pick best story and write video brief\").first().json.output.selected_title }}"
            },
            {
              "id": "post-05",
              "name": "source_url",
              "type": "string",
              "value": "={{ $(\"Pick best story and write video brief\").first().json.output.selected_url }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "3a7d6ee0-6ec4-4d9c-8101-c44b34270559",
      "name": "Publish video to YouTube",
      "type": "@blotato/n8n-nodes-blotato.blotato",
      "position": [
        1888,
        -16
      ],
      "parameters": {
        "options": {},
        "platform": "youtube",
        "accountId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "postContentText": "={{ $json.video_caption }}",
        "postContentMediaUrls": "={{ $json.video_url }}",
        "postCreateYoutubeOptionTitle": "={{ $json.video_title }}",
        "postCreateYoutubeOptionContainsSyntheticMedia": true
      },
      "credentials": {
        "blotatoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "0865af0e-e818-4cad-b957-c7944007a1d9",
      "name": "Publish video to TikTok",
      "type": "@blotato/n8n-nodes-blotato.blotato",
      "position": [
        2096,
        -16
      ],
      "parameters": {
        "options": {},
        "platform": "tiktok",
        "accountId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "postContentText": "={{ $(\"Prepare post content\").first().json.video_caption }}",
        "postContentMediaUrls": "={{ $(\"Prepare post content\").first().json.video_url }}",
        "postCreateTiktokOptionPrivacyLevel": "={{ $(\"Configuration\").item.json.tiktok_privacy_level }}",
        "postCreateTiktokOptionIsAiGenerated": true
      },
      "credentials": {
        "blotatoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "b56921cd-ad57-493f-9520-9754058275ca",
      "name": "Stop - video generation failed",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        1376,
        112
      ],
      "parameters": {
        "errorMessage": "=AtlasCloud video generation failed with status \"{{ $json.data.status }}\". Check your AtlasCloud dashboard and credits."
      },
      "typeVersion": 1
    },
    {
      "id": "1edf725e-437e-4321-ae62-58266a7f779e",
      "name": "Sticky Note 563f6678",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1424,
        -224
      ],
      "parameters": {
        "color": 4,
        "width": 760,
        "height": 1720,
        "content": "# Hacker News to video content with Blotato\n# \ud83d\udce5  [Open full documentation on Notion](https://automatisation.notion.site/Course-Hacker-News-to-video-content-with-Blotato-39d3d6550fd981398f88f9f12210c942)\n\n## How it works\n1. Fetches the trending Hacker News front-page stories matching your keyword.\n2. One OpenAI call picks the most exciting AI/automation story and writes a cinematic video prompt, a video title, a caption and hashtags.\n3. [AtlasCloud](https://www.atlascloud.ai/?ref=8QKPJE) (Veo 3.1 Fast) turns the prompt into a short AI video; a Wait \u2192 Check \u2192 Route loop polls until the video is ready.\n4. [Blotato](https://blotato.com/?ref=firas) publishes the finished video to YouTube and TikTok, correctly flagged as AI-generated content.\n\n## Setup\n1. Select your OpenAI credential on the OpenAI Chat Model node.\n2. Create a Header Auth credential for AtlasCloud (Name: Authorization / Value: Bearer YOUR_KEY) and select it on the two AtlasCloud HTTP nodes. Get your key on [AtlasCloud](https://www.atlascloud.ai/?ref=8QKPJE).\n3. Select your Blotato credential on both publish nodes, then pick your YouTube and TikTok accounts in each Account dropdown.\n4. Open the Configuration node and adjust the keyword, model, duration, format and privacy level. This is the only node you need to edit.\n\n## Requirements\n- OpenAI API key\n- AtlasCloud account \u2014 Veo 3.1 Fast costs about $0.10\u20130.15 per second of generated video\n- [Blotato](https://blotato.com/?ref=firas) account with YouTube and TikTok connected\n- Self-hosted n8n, or n8n Cloud with Verified Community Nodes enabled (Blotato is a community node)\n\n## Customization\n- Change topic_keyword to target another niche (crypto, robotics, cybersecurity...).\n- Swap atlas_model for any other AtlasCloud text-to-video model.\n- Duplicate a Blotato node to also publish on Instagram, Facebook or LinkedIn.\n- Replace the manual trigger with a Schedule Trigger to publish one video per day.\n\nNeed help customizing?\nContact me for consulting and support : [Linkedin](https://www.linkedin.com/in/doctor-firass/)\n\n# MY NEW YOUTUBE CHANNEL\n\ud83d\udc49 [Subscribe to my new YouTube channel](https://www.youtube.com/@DrFiras_AI). Here I'll share videos and Shorts with practical tutorials and FREE templates for n8n.\n\n[![The AI Doctor](https://www.dr-firas.com/the-ai-doctor.png)](https://www.youtube.com/@DrFiras_AI)"
      },
      "typeVersion": 1
    },
    {
      "id": "969b0efc-12ec-444e-8ac8-31e66ffb7318",
      "name": "Sticky Note fca499af",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -640,
        -224
      ],
      "parameters": {
        "color": 7,
        "width": 408,
        "height": 424,
        "content": "## 1. Trigger & configuration\nAll adjustable variables (keyword, model, duration, format, privacy) live in the Configuration node \u2014 the single place a beginner needs to edit."
      },
      "typeVersion": 1
    },
    {
      "id": "c84d2fcc-2dbe-404c-a4f2-239cbb7cca3a",
      "name": "Sticky Note 8a613881",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -192,
        -224
      ],
      "parameters": {
        "color": 7,
        "width": 760,
        "height": 424,
        "content": "## 2. Fetch & pick the best story\nHacker News front page \u2192 stories combined into one item \u2192 a single OpenAI call selects the best AI/automation story and writes the full video brief."
      },
      "typeVersion": 1
    },
    {
      "id": "58ed98ba-f110-4005-ac8e-c2f9c706a391",
      "name": "Sticky Note 43047404",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        592,
        -224
      ],
      "parameters": {
        "color": 7,
        "width": 960,
        "height": 424,
        "content": "## 3. Generate the AI video (AtlasCloud)\nThe brief is sent to AtlasCloud text-to-video. The Wait \u2192 Check \u2192 Route loop polls every 30s until the status is completed (or fails safely)."
      },
      "typeVersion": 1
    },
    {
      "id": "601cd8a3-a7d2-4eb2-a015-9c80a0965b95",
      "name": "Sticky Note 1964e390",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1568,
        -224
      ],
      "parameters": {
        "color": 7,
        "width": 760,
        "height": 424,
        "content": "## 4. Publish with Blotato\nThe finished video URL is posted to YouTube (with title + synthetic media flag) and TikTok (with privacy level + AI-generated flag)."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "6eeb0eae-e745-45dd-a4a4-cf112bb11d87",
  "nodeGroups": [],
  "connections": {
    "Configuration": {
      "main": [
        [
          {
            "node": "Fetch Hacker News front page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Pick best story and write video brief",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Check video status": {
      "main": [
        [
          {
            "node": "Route on video status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Video Brief Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Pick best story and write video brief",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Prepare post content": {
      "main": [
        [
          {
            "node": "Publish video to YouTube",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route on video status": {
      "main": [
        [
          {
            "node": "Prepare post content",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Stop - video generation failed",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait before checking status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Publish video to YouTube": {
      "main": [
        [
          {
            "node": "Publish video to TikTok",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start AI video generation": {
      "main": [
        [
          {
            "node": "Wait before checking status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait before checking status": {
      "main": [
        [
          {
            "node": "Check video status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Hacker News front page": {
      "main": [
        [
          {
            "node": "Combine stories into one item",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine stories into one item": {
      "main": [
        [
          {
            "node": "Pick best story and write video brief",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pick best story and write video brief": {
      "main": [
        [
          {
            "node": "Start AI video generation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}