Automate YouTube Video Promotion to X with OpenAI
Automatically generate and publish engaging X (Twitter) posts for new YouTube videos using OpenAI. This workflow fetches videos, creates unique content, validates length, posts to X, and logs everything in Google Sheets.
Overview
Automate your social media by transforming new YouTube videos into engaging, character-limit-compliant X posts with OpenAI, and track your content pipeline in Google Sheets.
🧠 Description & Use Case
This workflow automates the promotion of new YouTube videos on X (formerly Twitter). It fetches your latest video, uses OpenAI to generate a witty and engaging post, validates its length, publishes it to X, and keeps a detailed log in a Google Sheet.
🔄 How It Works:
-
Trigger & Fetch:
- The workflow can be triggered manually or on a schedule (e.g., every 2 hours).
- The
Fetch Latest Videosnode retrieves the most recent videos from a specified YouTube channel.
-
Deduplication:
- The
Remove Duplicatesnode ensures that each video is processed only once, preventing duplicate posts for the same content. - An
Ifnode checks if any new videos were found. If not, the workflow stops.
- The
-
AI-Powered Content Generation:
- The
Generate X Postnode sends the video's title and description to OpenAI'sgpt-4o-minimodel. - It prompts the AI to write a witty, humanized X post of no more than 220 characters, including the video link at the end.
- The
-
Content Validation:
- The
Verify character limit constraintsIf node checks if the generated post exceeds X's character limit. - If the post is too long, the
Rewrite X Postnode asks OpenAI to shorten it, ensuring it meets the platform's requirements.
- The
-
Logging and Posting:
- The
GS - Add Tweetnode adds a new row to a Google Sheet, logging the generated post with a status of "Post written." - The
Post to Xnode then publishes the content to your connected X account.
- The
-
Final Update:
- After a successful post, the
GS - Update Tweetnode updates the corresponding row in the Google Sheet, changing the status to "Posted to X" and adding the direct URL to the live post.
- After a successful post, the
✅ Real-World Use Cases:
- Content Creator Automation: Save hours of manual work by automatically promoting every new YouTube video to your X audience.
- Consistent Social Media Presence: Ensure a steady stream of promotional content without needing to manually craft posts for each video.
- Content Pipeline Tracking: Use the integrated Google Sheet as a content calendar and a log of all social media activity, complete with performance metrics (like post URLs).
- Brand Voice Consistency: Leverage AI to maintain a consistent tone and style across all your promotional posts.
Instructions
Basic steps
- Download workflow JSON
- Import into n8n
- Configure node parameters as needed
- Test and enable the workflow
💡 Tips
After importing, verify all connectors and credentials match your environment.
Preview
Workflow Visualization
Nodes
Post to X
Sticky Note
stickyNote
Fetch Latest Videos
youTube
Calculator
@n8n/langchain.toolCalculator
Wikipedia
@n8n/langchain.toolWikipedia
Check Every 2 Hours
scheduleTrigger
Sticky Note4
stickyNote
Calculator2
@n8n/langchain.toolCalculator
GS - Add Tweet
googleSheets
GS - Update Tweet
googleSheets
When clicking "Test workflow"
manualTrigger
Discord
discord
Remove Duplicates
removeDuplicates
Sticky Note1
stickyNote
Generate X Post
@n8n/langchain.openAi
Set Fields
set
Wikipedia1
@n8n/langchain.toolWikipedia
Rewrite X Post to 220 Characters
@n8n/langchain.openAi
Verify character limit constraints
if
Sticky Note3
stickyNote
Sticky Note6
stickyNote
Slack
slack
Sticky Note7
stickyNote
Gmail
gmail
Set Final Fields
set
If Array is empty?
if
Sticky Note8
stickyNote
Sticky Note9
stickyNote
Statistics
View full JSON structure
{
"nodes": [
{
"id": "6aef04f2-b744-4749-99bd-4ad8aa21ad09",
"name": "Post to X",
"type": "n8n-nodes-base.twitter",
"position": [
1400,
100
],
"parameters": {
"text": "={{ $('Verify character limit constraints').item.json.message.content.post }}",
"additionalFields": {}
},
"credentials": {
"twitterOAuth2Api": {
"id": "0VkIx1OfmRAYb4Az",
"name": "Alex Kim X account"
}
},
"typeVersion": 2
},
{
"id": "827ab988-786a-490e-8831-cfee3851a9ac",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-560,
-100
],
"parameters": {
"color": 4,
"width": 450,
"height": 970,
"content": "## Fetch the latest YouTube video and dedupe\n\nEnter your YouTube Channel ID in the \"Channel ID\" field of this node. You can find your [Channel ID here](https://youtube.com/account_advanced)."
},
"typeVersion": 1
},
{
"id": "8e99c377-7d14-473b-a6e4-a190702ad8a9",
"name": "Fetch Latest Videos",
"type": "n8n-nodes-base.youTube",
"position": [
-500,
100
],
"parameters": {
"limit": 2,
"filters": {
"channelId": "UC3JB8Cnync-WCDYKwOYSQUg",
"publishedAfter": "={{ new Date(new Date().getTime() - 1200 * 60000).toISOString() }}"
},
"options": {},
"resource": "video"
},
"credentials": {
"youTubeOAuth2Api": {
"id": "xwcVTsTddECg5vyd",
"name": "AlexK1919 YouTube account"
}
},
"typeVersion": 1
},
{
"id": "c9ea0b72-2293-4aab-84b4-5e6599f5e04d",
"name": "Calculator",
"type": "@n8n/n8n-nodes-langchain.toolCalculator",
"position": [
0,
300
],
"parameters": {},
"typeVersion": 1
},
{
"id": "e81decde-6a60-4ea0-a3ff-64cbdccc1f88",
"name": "Wikipedia",
"type": "@n8n/n8n-nodes-langchain.toolWikipedia",
"position": [
120,
300
],
"parameters": {},
"typeVersion": 1
},
{
"id": "870a58ba-6d0f-42e5-ad07-040b8d81e780",
"name": "Check Every 2 Hours",
"type": "n8n-nodes-base.scheduleTrigger",
"disabled": true,
"position": [
-900,
100
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 2,
"triggerAtMinute": "={{ Math.floor(Math.random() * 60) }}"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "4af4e893-7c94-4a73-9d88-1426be8725f7",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
380,
-100
],
"parameters": {
"color": 4,
"width": 637,
"height": 969,
"content": "## Validate: Is Post under 240 characters?\nIf the generated tweet does not meet length constraints, regenerate it."
},
"typeVersion": 1
},
{
"id": "8c4f51cd-3e25-4d45-a677-1bf27277c2f8",
"name": "Calculator2",
"type": "@n8n/n8n-nodes-langchain.toolCalculator",
"position": [
680,
240
],
"parameters": {},
"typeVersion": 1
},
{
"id": "2eff94c8-5ab8-4fba-8480-39d34077784c",
"name": "GS - Add Tweet",
"type": "n8n-nodes-base.googleSheets",
"position": [
1120,
100
],
"parameters": {
"columns": {
"value": {
"xid": "={{ Math.random().toString(36).substr(2, 12) }}",
"date": "={{ new Date().toISOString().split('T')[0] }}",
"post": "={{ $json.message.content.post }}",
"time": "={{ new Date().toLocaleTimeString('en-US', { hour12: false }) }}",
"status": "Post written",
"channel": "X"
},
"schema": [
{
"id": "xid",
"type": "string",
"display": true,
"required": false,
"displayName": "xid",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "date",
"type": "string",
"display": true,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "time",
"type": "string",
"display": true,
"required": false,
"displayName": "time",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "channel",
"type": "string",
"display": true,
"required": false,
"displayName": "channel",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "post",
"type": "string",
"display": true,
"required": false,
"displayName": "post",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "image_url",
"type": "string",
"display": true,
"required": false,
"displayName": "image_url",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "video_url",
"type": "string",
"display": true,
"required": false,
"displayName": "video_url",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": []
},
"options": {
"useAppend": true
},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Ql9TGAzZCSdSqrHvkZLcsBPoNMAjNpPVsELkumP2heM/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1Ql9TGAzZCSdSqrHvkZLcsBPoNMAjNpPVsELkumP2heM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Ql9TGAzZCSdSqrHvkZLcsBPoNMAjNpPVsELkumP2heM/edit?usp=drivesdk",
"cachedResultName": "AlexK1919 Social Posts"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "IpY8N9VFCXJLC1hv",
"name": "AlexK1919 Google Sheets account"
}
},
"typeVersion": 4.3
},
{
"id": "21f25b2d-e9d3-46df-a2c9-53f3a8c14b8b",
"name": "GS - Update Tweet",
"type": "n8n-nodes-base.googleSheets",
"position": [
1400,
300
],
"parameters": {
"columns": {
"value": {
"xid": "={{ $('GS - Add Tweet').item.json.xid }}",
"date": "={{ new Date().toISOString().split('T')[0] }}",
"post": "={{ $json.text }}",
"time": "={{ new Date().toLocaleTimeString('en-US', { hour12: false }) }}",
"status": "Posted to X",
"channel": "X",
"post_url": "=https://twitter.com/alexkim/status/{{ $json.id }}"
},
"schema": [
{
"id": "xid",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "xid",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "date",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "time",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "time",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "channel",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "channel",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "post",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "post",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "post_url",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "post_url",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "image_url",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "image_url",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "video_url",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "video_url",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"xid"
]
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Ql9TGAzZCSdSqrHvkZLcsBPoNMAjNpPVsELkumP2heM/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1Ql9TGAzZCSdSqrHvkZLcsBPoNMAjNpPVsELkumP2heM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Ql9TGAzZCSdSqrHvkZLcsBPoNMAjNpPVsELkumP2heM/edit?usp=drivesdk",
"cachedResultName": "AlexK1919 Social Posts"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "IpY8N9VFCXJLC1hv",
"name": "AlexK1919 Google Sheets account"
}
},
"typeVersion": 4.3
},
{
"id": "8ce4484b-a7fd-4988-8240-e9c09a4a00be",
"name": "When clicking \"Test workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-900,
300
],
"parameters": {},
"typeVersion": 1
},
{
"id": "24f9bc85-8892-4418-8ab6-ef73986adc79",
"name": "Discord",
"type": "n8n-nodes-base.discord",
"position": [
1680,
100
],
"parameters": {
"content": "=New X Post:\n{{ $('GS - Add Tweet Again').item.json.Content }}\n\n{{ $json.URL }} ",
"options": {},
"authentication": "webhook"
},
"typeVersion": 2
},
{
"id": "3526581f-7b71-4396-a3a3-4c676cf1c69b",
"name": "Remove Duplicates",
"type": "n8n-nodes-base.removeDuplicates",
"position": [
-500,
300
],
"parameters": {
"options": {
"scope": "workflow",
"historySize": 10000
},
"operation": "removeItemsSeenInPreviousExecutions",
"dedupeValue": "={{ $json.id.videoId }}"
},
"typeVersion": 2
},
{
"id": "c152651f-12d3-4766-8b4b-43f93b7b06ee",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-60,
-100
],
"parameters": {
"color": 4,
"width": 390,
"height": 970,
"content": "## Generate X Post"
},
"typeVersion": 1
},
{
"id": "af1dd938-81f9-464a-865a-2a89882bae90",
"name": "Generate X Post",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
0,
100
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"messages": {
"values": [
{
"content": "=Write an engaging post about my latest YouTube video for X (Twitter) of no more than 220 characters in length. Link to the video at https://youtu.be/{{ $('Set Fields').first().json.id.videoId }} use this title and description: {{ $('Set Fields').first().json.snippet.title }} {{ $('Set Fields').first().json.snippet.description }}. If there is no description available, use your best guess as to the context of the video. Make sure the YouTube link is at the end of the content."
},
{
"role": "assistant",
"content": "Be witty. Humanize the content. No emojis."
}
]
},
"jsonOutput": true
},
"credentials": {
"openAiApi": {
"id": "ysxujEYFiY5ozRTS",
"name": "AlexK OpenAi Key"
}
},
"typeVersion": 1.3
},
{
"id": "a522b20c-9cb1-47ec-ab26-d7a444154a51",
"name": "Set Fields",
"type": "n8n-nodes-base.set",
"position": [
-300,
100
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c2e2eecd-ca73-40c9-a364-4713030ab451",
"name": "id.videoId",
"type": "string",
"value": "={{ $json.id.videoId }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "82139047-3ed5-4cc3-9e7e-9567e2f51c20",
"name": "Wikipedia1",
"type": "@n8n/n8n-nodes-langchain.toolWikipedia",
"position": [
800,
240
],
"parameters": {},
"typeVersion": 1
},
{
"id": "6ad77986-f18f-44f0-aff6-fe77282bf55a",
"name": "Rewrite X Post to 220 Characters",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
680,
40
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"messages": {
"values": [
{
"content": "=Rewrite the content so it is less than 220 characters long in total length. Content: {{ $('Generate X Post').item.json.message.content.post }}\nMake sure the YouTube Link is at the end of the content."
},
{
"role": "assistant",
"content": "Be witty. Humanize the content. No emojis."
}
]
},
"jsonOutput": true
},
"credentials": {
"openAiApi": {
"id": "ysxujEYFiY5ozRTS",
"name": "AlexK OpenAi Key"
}
},
"typeVersion": 1.3
},
{
"id": "e55adf1f-8d1d-4bb6-aa6a-89459fd81773",
"name": "Verify character limit constraints",
"type": "n8n-nodes-base.if",
"position": [
440,
100
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0a6ebbb6-4b14-4c7e-9390-215e32921663",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.message.content.post.length }}",
"rightValue": 280
}
]
}
},
"typeVersion": 2
},
{
"id": "00beb197-aed5-472d-9515-9f0002cc22ae",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1060,
-100
],
"parameters": {
"color": 4,
"width": 230,
"height": 970,
"content": "## Add to Google Sheet"
},
"typeVersion": 1
},
{
"id": "f871304f-b39f-46ee-8b22-5f0050eb2b8e",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1340,
-100
],
"parameters": {
"color": 4,
"width": 230,
"height": 970,
"content": "## Post to X and update Google Sheet with Post Link"
},
"typeVersion": 1
},
{
"id": "c4d0c37b-658d-4208-9d94-39d27c7d7f36",
"name": "Slack",
"type": "n8n-nodes-base.slack",
"position": [
1680,
300
],
"webhookId": "f2269822-19a4-43a4-9a91-06bc69d183b4",
"parameters": {
"otherOptions": {}
},
"typeVersion": 2.2
},
{
"id": "6caf1d2d-49d2-4b28-9f23-04389bdaa079",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1620,
-100
],
"parameters": {
"color": 5,
"width": 230,
"height": 970,
"content": "## Optional functions"
},
"typeVersion": 1
},
{
"id": "c5528fc1-0416-4295-bdaa-12441099f037",
"name": "Gmail",
"type": "n8n-nodes-base.gmail",
"position": [
1680,
500
],
"webhookId": "3404c1a8-9118-48aa-ba03-e9e436f5a7a6",
"parameters": {
"options": {}
},
"credentials": {
"gmailOAuth2": {
"id": "7eQtesjR8Fht0INE",
"name": "AlexK1919 Gmail"
}
},
"typeVersion": 2.1
},
{
"id": "e9ac1049-9b87-47a5-8fd1-333cc8c77664",
"name": "Set Final Fields",
"type": "n8n-nodes-base.set",
"position": [
680,
440
],
"parameters": {
"options": {},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "955d51f0-3de9-41f7-a92f-8e7bf9e4d53c",
"name": "If Array is empty?",
"type": "n8n-nodes-base.if",
"position": [
-300,
300
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "adfea7c7-ed64-4e1e-a9c3-dc5e33aa1147",
"operator": {
"type": "array",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $('Remove Duplicates').all() }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "c088bbe1-2008-4473-9874-dc5595f082b7",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1000,
-100
],
"parameters": {
"color": 5,
"width": 390,
"height": 970,
"content": "# Use AI to Promote Your Latest YouTube Video on X"
},
"typeVersion": 1
},
{
"id": "03adde36-d864-486a-9190-2e7d27b9f3f2",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1300,
-100
],
"parameters": {
"color": 6,
"width": 250,
"height": 970,
"content": "# AlexK1919 \n\n\n#### I’m Alex Kim, an AI-Native Workflow Automation Architect Building Solutions to Optimize your Personal and Professional Life.\n\n### About Me\nhttps://beacons.ai/alexk1919\n\n### Products Used \n[OpenAI](https://openai.com)\n[X](https://x.com/)\n[YouTube](https://youtube.com/)\n"
},
"typeVersion": 1
}
],
"connections": {
"Post to X": {
"main": [
[
{
"node": "GS - Update Tweet",
"type": "main",
"index": 0
}
]
]
},
"Wikipedia": {
"ai_tool": [
[
{
"node": "Generate X Post",
"type": "ai_tool",
"index": 0
}
]
]
},
"Calculator": {
"ai_tool": [
[
{
"node": "Generate X Post",
"type": "ai_tool",
"index": 0
}
]
]
},
"Set Fields": {
"main": [
[
{
"node": "Remove Duplicates",
"type": "main",
"index": 0
}
]
]
},
"Wikipedia1": {
"ai_tool": [
[
{
"node": "Rewrite X Post to 220 Characters",
"type": "ai_tool",
"index": 0
}
]
]
},
"Calculator2": {
"ai_tool": [
[
{
"node": "Rewrite X Post to 220 Characters",
"type": "ai_tool",
"index": 0
}
]
]
},
"GS - Add Tweet": {
"main": [
[
{
"node": "Post to X",
"type": "main",
"index": 0
}
]
]
},
"Generate X Post": {
"main": [
[
{
"node": "Verify character limit constraints",
"type": "main",
"index": 0
}
]
]
},
"Set Final Fields": {
"main": [
[
{
"node": "GS - Add Tweet",
"type": "main",
"index": 0
}
]
]
},
"GS - Update Tweet": {
"main": [
[]
]
},
"Remove Duplicates": {
"main": [
[
{
"node": "If Array is empty?",
"type": "main",
"index": 0
}
]
]
},
"If Array is empty?": {
"main": [
[],
[
{
"node": "Generate X Post",
"type": "main",
"index": 0
}
]
]
},
"Check Every 2 Hours": {
"main": [
[]
]
},
"Fetch Latest Videos": {
"main": [
[
{
"node": "Set Fields",
"type": "main",
"index": 0
}
]
]
},
"When clicking \"Test workflow\"": {
"main": [
[
{
"node": "Fetch Latest Videos",
"type": "main",
"index": 0
}
]
]
},
"Rewrite X Post to 220 Characters": {
"main": [
[
{
"node": "Verify character limit constraints",
"type": "main",
"index": 0
}
]
]
},
"Verify character limit constraints": {
"main": [
[
{
"node": "Rewrite X Post to 220 Characters",
"type": "main",
"index": 0
}
],
[
{
"node": "Set Final Fields",
"type": "main",
"index": 0
}
]
]
}
}
}Actions
Technical Specs
Compatibility
License
This workflow template follows MIT license, you can freely use, modify and distribute.
Please comply with relevant third-party service terms when using.