AutomationFlowsSocial Media › Youtube Upload → Notify All Platforms

Youtube Upload → Notify All Platforms

08 - YouTube Upload → Notify All Platforms. Uses httpRequest, slack. Webhook trigger; 8 nodes.

Webhook trigger★★★★☆ complexity8 nodesHTTP RequestSlack
Social Media Trigger: Webhook Nodes: 8 Complexity: ★★★★☆ Added:

This workflow follows the HTTP Request → Slack recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "08 - YouTube Upload \u2192 Notify All Platforms",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "youtube-upload",
        "responseMode": "onReceived",
        "options": {}
      },
      "id": "node-webhook",
      "name": "YouTube Webhook (PubSubHubbub)",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        260,
        300
      ],
      "notes": "Subscribe at: https://pubsubhubbub.appspot.com/subscribe\nHub URL: https://pubsubhubbub.appspot.com/\nTopic: https://www.youtube.com/xml/feeds/videos.xml?channel_id=YOUR_CHANNEL_ID"
    },
    {
      "parameters": {
        "jsCode": "// Parse YouTube PubSubHubbub XML notification\nconst body = $input.first().json.body || $input.first().json;\nconst rawXml = typeof body === 'string' ? body : JSON.stringify(body);\n\n// Extract video ID from XML\nconst videoIdMatch = rawXml.match(/<yt:videoId>([^<]+)<\\/yt:videoId>/);\nconst titleMatch = rawXml.match(/<title>([^<]+)<\\/title>/);\nconst publishedMatch = rawXml.match(/<published>([^<]+)<\\/published>/);\nconst channelIdMatch = rawXml.match(/<yt:channelId>([^<]+)<\\/yt:channelId>/);\n\nconst videoId = videoIdMatch ? videoIdMatch[1].trim() : null;\nconst title = titleMatch ? titleMatch[1].replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').trim() : 'New Video';\nconst published = publishedMatch ? publishedMatch[1].trim() : new Date().toISOString();\nconst channelId = channelIdMatch ? channelIdMatch[1].trim() : $env['YOUTUBE_CHANNEL_ID'];\n\nif (!videoId) {\n  throw new Error('Could not parse video ID from YouTube notification');\n}\n\nconst videoUrl = `https://youtu.be/${videoId}`;\nconst thumbnailUrl = `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`;\n\nreturn [{\n  json: {\n    videoId,\n    videoUrl,\n    thumbnailUrl,\n    title,\n    published,\n    channelId,\n    channelUrl: `https://www.youtube.com/channel/${channelId}`\n  }\n}];"
      },
      "id": "node-parse-xml",
      "name": "Code - Parse YouTube XML",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        300
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://www.googleapis.com/youtube/v3/videos",
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "id",
              "value": "={{ $json.videoId }}"
            },
            {
              "name": "part",
              "value": "snippet,statistics,contentDetails"
            }
          ]
        },
        "options": {}
      },
      "id": "node-yt-api",
      "name": "HTTP Request - Get Video Details",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        700,
        300
      ],
      "credentials": {
        "oAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const webhook = $('Code - Parse YouTube XML').first().json;\nconst ytData = $input.first().json;\nconst video = ytData.items?.[0]?.snippet || {};\nconst stats = ytData.items?.[0]?.statistics || {};\n\nconst description = (video.description || '').substring(0, 300);\nconst tags = (video.tags || []).slice(0, 10).join(', ');\n\n// Generate platform-specific content\nconst tweetText = `\ud83c\udfac New video just dropped!\\n\\n\"${webhook.title}\"\\n\\nWatch now \ud83d\udc47\\n${webhook.videoUrl}\\n\\n#YouTube #NewVideo`;\nconst slackMessage = `\ud83c\udfac *New YouTube Video Published!*\\n\\n*${webhook.title}*\\n${description ? description + '...' : ''}\\n\\n\ud83d\udc49 ${webhook.videoUrl}`;\nconst instagramCaption = `\ud83c\udfac New video is LIVE!\\n\\n${webhook.title}\\n\\n${description.substring(0, 150)}...\\n\\n\ud83d\udd17 Link in bio!\\n\\n${tags.split(', ').map(t => '#' + t.replace(/\\s+/g, '')).join(' ')}`;\n\nreturn [{\n  json: {\n    ...webhook,\n    channelTitle: video.channelTitle || '',\n    description,\n    tags,\n    categoryId: video.categoryId,\n    tweetText: tweetText.substring(0, 280),\n    slackMessage,\n    instagramCaption: instagramCaption.substring(0, 2200),\n    thumbnailHq: video.thumbnails?.maxres?.url || video.thumbnails?.high?.url || webhook.thumbnailUrl\n  }\n}];"
      },
      "id": "node-set-messages",
      "name": "Set - Format Platform Messages",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        920,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.twitter.com/2/tweets",
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth1Api",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "text",
              "value": "={{ $json.tweetText }}"
            }
          ]
        },
        "options": {}
      },
      "id": "node-twitter",
      "name": "HTTP - Post to Twitter/X",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1140,
        160
      ],
      "credentials": {
        "oAuth1Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "C_CONTENT_CHANNEL",
          "mode": "id"
        },
        "messageType": "block",
        "blocksUi": {
          "blocksValues": [
            {
              "type": "header",
              "text": {
                "type": "plain_text",
                "text": "\ud83c\udfac New YouTube Video Published!"
              }
            },
            {
              "type": "section",
              "text": {
                "type": "mrkdwn",
                "text": "*{{ $json.title }}*\n{{ $json.description }}..."
              },
              "accessory": {
                "type": "image",
                "image_url": "={{ $json.thumbnailHq }}",
                "alt_text": "Video thumbnail"
              }
            },
            {
              "type": "actions",
              "elements": [
                {
                  "type": "button",
                  "text": {
                    "type": "plain_text",
                    "text": "Watch Now \u25b6"
                  },
                  "url": "={{ $json.videoUrl }}",
                  "style": "primary"
                }
              ]
            }
          ]
        }
      },
      "id": "node-slack",
      "name": "Slack - Notify Team",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        1140,
        300
      ],
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://graph.instagram.com/v19.0/{{ $env['INSTAGRAM_BUSINESS_ID'] }}/media",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "image_url",
              "value": "={{ $json.thumbnailHq }}"
            },
            {
              "name": "caption",
              "value": "={{ $json.instagramCaption }}"
            },
            {
              "name": "access_token",
              "value": "={{ $env['INSTAGRAM_ACCESS_TOKEN'] }}"
            }
          ]
        },
        "options": {}
      },
      "id": "node-instagram-media",
      "name": "HTTP - Instagram Create Media",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1140,
        440
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://graph.instagram.com/v19.0/{{ $env['INSTAGRAM_BUSINESS_ID'] }}/media_publish",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "creation_id",
              "value": "={{ $json.id }}"
            },
            {
              "name": "access_token",
              "value": "={{ $env['INSTAGRAM_ACCESS_TOKEN'] }}"
            }
          ]
        },
        "options": {}
      },
      "id": "node-instagram-publish",
      "name": "HTTP - Instagram Publish Post",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1360,
        440
      ]
    }
  ],
  "connections": {
    "YouTube Webhook (PubSubHubbub)": {
      "main": [
        [
          {
            "node": "Code - Parse YouTube XML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Parse YouTube XML": {
      "main": [
        [
          {
            "node": "HTTP Request - Get Video Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request - Get Video Details": {
      "main": [
        [
          {
            "node": "Set - Format Platform Messages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set - Format Platform Messages": {
      "main": [
        [
          {
            "node": "HTTP - Post to Twitter/X",
            "type": "main",
            "index": 0
          },
          {
            "node": "Slack - Notify Team",
            "type": "main",
            "index": 0
          },
          {
            "node": "HTTP - Instagram Create Media",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP - Instagram Create Media": {
      "main": [
        [
          {
            "node": "HTTP - Instagram Publish Post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "tags": [
    {
      "name": "youtube"
    },
    {
      "name": "social-media"
    },
    {
      "name": "content"
    }
  ],
  "meta": {
    "description": "Receives YouTube PubSubHubbub webhook when video is uploaded, fetches full details via YouTube Data API, then simultaneously posts to Twitter/X, notifies Slack team, and publishes on Instagram (2-step media create \u2192 publish).",
    "prerequisites": [
      "YouTube Data API v3 OAuth2 credentials",
      "Twitter OAuth1 credentials",
      "Slack Bot Token",
      "Instagram Business Account with Graph API access token",
      "Set env variables: YOUTUBE_CHANNEL_ID, INSTAGRAM_BUSINESS_ID, INSTAGRAM_ACCESS_TOKEN",
      "Subscribe webhook to PubSubHubbub: https://pubsubhubbub.appspot.com/subscribe",
      "Instagram thumbnail must be publicly accessible URL"
    ],
    "testingScenario": {
      "happy_path": "Upload private YouTube video \u2192 verify all 3 platforms notified within 30 seconds",
      "test_manually": "POST fake PubSubHubbub XML to webhook: <?xml version='1.0'?><feed xmlns:yt='http://www.youtube.com/xml/schemas/2015'><entry><yt:videoId>dQw4w9WgXcQ</yt:videoId><title>Test Video</title><published>2026-06-13T09:00:00Z</published><yt:channelId>UCxxxxxx</yt:channelId></entry></feed>"
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

08 - YouTube Upload → Notify All Platforms. Uses httpRequest, slack. Webhook trigger; 8 nodes.

Source: https://github.com/satmakuru222/TheAIStackk/blob/main/n8n-workflows/08-youtube-upload-notify-platforms.json — original creator credit. Request a take-down →

More Social Media workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Social Media

Automate your post-event Instagram carousel using a fan-out and merge pattern. One Code node splits the photos array into individual n8n items. Every photo then flows through HTTP Fetch, Upload to URL

HTTP Request, N8N Nodes Uploadtourl, Airtable +1
Social Media

Instagram - Fluxo de mensagens. Uses rabbitmq, rabbitmqTrigger, googleSheets, httpRequest. Webhook trigger; 74 nodes.

Rabbitmq, Rabbitmq Trigger, Google Sheets +1
Social Media

This enterprise-grade n8n workflow automates the Instagram complaint handling process — from detection to resolution — using Claude AI, dynamic ticket assignment, and SLA enforcement. It converts cust

HTTP Request, Google Sheets, Slack
Social Media

This enterprise-grade n8n workflow automates influencer contract compliance for Instagram campaigns — from deadline tracking to breach detection — using Claude AI, Instagram API, and smart reminders.

Google Sheets, Slack, HTTP Request
Social Media

Content creators, AI video enthusiasts, and digital marketers who want to analyze successful short-form videos and understand their production techniques. Perfect for anyone looking to reverse-enginee

Form Trigger, HTTP Request, Slack