This workflow follows the HTTP Request → OpenAI 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 →
{
"name": "TagDrop Content Automation",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "tagdrop-start",
"responseMode": "responseNode",
"options": {}
},
"id": "webhook-trigger",
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
200,
300
]
},
{
"parameters": {
"jsCode": "// Parse input parameters\nconst input = $json.body || $json;\nconst videoFolder = input.videoFolder || '';\nconst startDate = input.startDate || '';\nconst platforms = input.platforms || [];\nconst driveUrl = input.driveUrl || '';\n\n// Validate inputs\nif (!startDate) {\n throw new Error('Start date is required');\n}\nif (platforms.length === 0) {\n throw new Error('At least one platform must be selected');\n}\nif (!videoFolder && !driveUrl) {\n throw new Error('Either video folder or Google Drive URL is required');\n}\n\n// Mock video files for demo (replace with actual file reading)\nconst mockFiles = [\n 'dark-forest-figure-emerges-horror-dread.mp4',\n 'cafe-woman-'taylor-swift'-reveal-pop-whimsy.mp4',\n 'beach-dog-running-comedy-funny.mp4',\n 'space-station-floating-scifi-wonder.mp4'\n];\n\nconst files = mockFiles;\nconst results = [];\n\n// Parse each filename\nfor (const file of files) {\n const parsed = parseFilename(file);\n if (parsed) {\n results.push({\n filename: file,\n ...parsed,\n startDate,\n platforms\n });\n }\n}\n\nfunction parseFilename(fname) {\n const base = fname.replace(/\\.mp4$/i, '');\n const parts = base.split('-');\n \n if (parts.length < 5) {\n return null;\n }\n \n return {\n location: parts[0],\n subject: parts[1], \n action: parts[2],\n genre: parts[3],\n vibe: parts[4],\n raw: base,\n hasReveal: base.toLowerCase().includes('reveal'),\n hasPopCulture: base.includes(\"'\"),\n hasFunny: base.toLowerCase().includes('funny')\n };\n}\n\nreturn results.map(item => ({ json: item }));"
},
"id": "parse-inputs",
"name": "Parse Inputs & Files",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
400,
300
]
},
{
"parameters": {
"model": "gpt-4",
"messages": {
"messageType": "multipleMessages",
"messages": [
{
"role": "system",
"message": "You are a social media copywriter with a quiet, strange, lightly funny or magical voice. Describe a fleeting cinematic moment without spoilers."
},
{
"role": "user",
"message": "=Metadata:\n- Location: {{ $json.location }}\n- Subject: {{ $json.subject }}\n- Action: {{ $json.action }}\n- Genre: {{ $json.genre }}\n- Vibe: {{ $json.vibe }}\n\n{{ $json.hasReveal ? \"Note: filename contains 'Reveal'. Tease without revealing.\\n\" : \"\" }}{{ $json.hasPopCulture ? \"Note: single quotes mark pop-culture references. Include subtly.\\n\" : \"\" }}{{ $json.hasFunny ? \"Note: filename contains 'funny'. Add a gentle pun.\\n\" : \"\" }}\nInstructions:\n1. TITLE (3\u20136 words, under 60 chars, no hashtags, no spoilers)\n2. CAPTION (1 sentence, rich in tone)\n3. DESCRIPTION (1\u20132 sentences, deepen intrigue)\n4. TAGS (5 lowercase, comma-separated keywords)\n\nStyle:\n- Avoid clickbait, CTAs, summaries\n- Match genre & vibe: dread\u2192horror, wonder\u2192surreal, whimsy\u2192cute\n- No repeated key phrases across posts\n\nFormat your response exactly as:\nTITLE: [your title]\nCAPTION: [your caption]\nDESCRIPTION: [your description]\nTAGS: [your tags]"
}
]
},
"options": {
"temperature": 0.8
}
},
"id": "generate-content",
"name": "Generate Content (GPT-4)",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1,
"position": [
600,
300
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Parse GPT-4 response\nconst response = $json.message?.content || $json.response || '';\nconst lines = response.split('\\n');\n\nconst content = {\n title: '',\n caption: '', \n description: '',\n tags: ''\n};\n\nfor (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.startsWith('TITLE:')) {\n content.title = trimmed.replace('TITLE:', '').trim();\n } else if (trimmed.startsWith('CAPTION:')) {\n content.caption = trimmed.replace('CAPTION:', '').trim();\n } else if (trimmed.startsWith('DESCRIPTION:')) {\n content.description = trimmed.replace('DESCRIPTION:', '').trim();\n } else if (trimmed.startsWith('TAGS:')) {\n content.tags = trimmed.replace('TAGS:', '').trim();\n }\n}\n\n// Calculate next weekday for scheduling\nconst startDate = new Date($('parse-inputs').item.json.startDate);\nconst currentIndex = $itemIndex;\n\n// Add days, skipping weekends\nlet scheduleDate = new Date(startDate);\nlet daysAdded = 0;\nwhile (daysAdded < currentIndex) {\n scheduleDate.setDate(scheduleDate.getDate() + 1);\n // Skip weekends (Saturday = 6, Sunday = 0)\n if (scheduleDate.getDay() !== 0 && scheduleDate.getDay() !== 6) {\n daysAdded++;\n }\n}\n\nreturn {\n json: {\n filename: $json.filename,\n location: $json.location,\n subject: $json.subject,\n action: $json.action,\n genre: $json.genre,\n vibe: $json.vibe,\n platforms: $json.platforms,\n scheduleDate: scheduleDate.toISOString().split('T')[0],\n scheduleTime: '09:00',\n ...content\n }\n};"
},
"id": "parse-content",
"name": "Parse Content & Schedule",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
800,
300
]
},
{
"parameters": {
"url": "https://app.metricool.com/api/v2/media/videos",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-Mc-Auth",
"value": "={{ $credentials.metricoolApi.token }}"
}
]
},
"sendBody": true,
"bodyContentType": "multipart-form-data",
"bodyParameters": {
"parameters": [
{
"parameterType": "formBinaryData",
"name": "file",
"inputDataFieldName": "video"
}
]
},
"options": {
"retry": {
"enabled": true,
"maxTries": 5,
"waitBetweenTries": 1000
}
}
},
"id": "upload-video",
"name": "Upload Video to Metricool",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1000,
300
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"fieldsToSplitOut": "platforms",
"options": {}
},
"id": "split-platforms",
"name": "Split by Platform",
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
1200,
300
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "instagram-condition",
"leftValue": "={{ $json.platforms }}",
"rightValue": "instagram",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "or"
},
"looseTypeValidation": true
},
"id": "instagram-check",
"name": "Instagram Check",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1400,
200
]
},
{
"parameters": {
"url": "https://app.metricool.com/api/v2/scheduler/posts",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-Mc-Auth",
"value": "={{ $credentials.metricoolApi.token }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyContentType": "json",
"jsonBody": "={\n \"network\": \"instagram\",\n \"title\": \"{{ $json.title }}\",\n \"content\": \"{{ $json.caption }}\\n\\n{{ $json.description }}\", \n \"media_url\": \"{{ $('upload-video').item.json.data.url }}\",\n \"tags\": {{ $json.tags.split(',').map(tag => tag.trim()) }},\n \"publish_at\": \"{{ $json.scheduleDate }}T{{ $json.scheduleTime }}:00Z\",\n \"post_type\": \"reel\"\n}",
"options": {
"retry": {
"enabled": true,
"maxTries": 3,
"waitBetweenTries": 2000
}
}
},
"id": "schedule-instagram",
"name": "Schedule Instagram Post",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1600,
150
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "tiktok-condition",
"leftValue": "={{ $json.platforms }}",
"rightValue": "tiktok",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "or"
},
"looseTypeValidation": true
},
"id": "tiktok-check",
"name": "TikTok Check",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1400,
350
]
},
{
"parameters": {
"url": "https://app.metricool.com/api/v2/scheduler/posts",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-Mc-Auth",
"value": "={{ $credentials.metricoolApi.token }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyContentType": "json",
"jsonBody": "={\n \"network\": \"tiktok\",\n \"title\": \"{{ $json.title }}\",\n \"content\": \"{{ $json.caption }} #{{ $json.tags.split(',').join(' #') }}\",\n \"media_url\": \"{{ $('upload-video').item.json.data.url }}\",\n \"publish_at\": \"{{ $json.scheduleDate }}T{{ $json.scheduleTime }}:00Z\",\n \"privacy\": \"Public\",\n \"allow_duet\": \"Yes\"\n}",
"options": {
"retry": {
"enabled": true,
"maxTries": 3,
"waitBetweenTries": 2000
}
}
},
"id": "schedule-tiktok",
"name": "Schedule TikTok Post",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1600,
300
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "youtube-condition",
"leftValue": "={{ $json.platforms }}",
"rightValue": "youtube",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "or"
},
"looseTypeValidation": true
},
"id": "youtube-check",
"name": "YouTube Check",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1400,
500
]
},
{
"parameters": {
"url": "https://app.metricool.com/api/v2/scheduler/posts",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-Mc-Auth",
"value": "={{ $credentials.metricoolApi.token }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyContentType": "json",
"jsonBody": "={\n \"network\": \"youtube\",\n \"title\": \"{{ $json.title }}\",\n \"content\": \"{{ $json.description }}\",\n \"media_url\": \"{{ $('upload-video').item.json.data.url }}\",\n \"tags\": {{ $json.tags.split(',').map(tag => tag.trim()) }},\n \"publish_at\": \"{{ $json.scheduleDate }}T{{ $json.scheduleTime }}:00Z\",\n \"video_type\": \"short\",\n \"audience\": \"No\",\n \"privacy\": \"Public\",\n \"category\": \"Film & Animation\"\n}",
"options": {
"retry": {
"enabled": true,
"maxTries": 3,
"waitBetweenTries": 2000
}
}
},
"id": "schedule-youtube",
"name": "Schedule YouTube Short",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1600,
450
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Collect all results\nconst allResults = [];\n\n// Get results from all platform scheduling nodes\nconst instagramResults = $('schedule-instagram').all() || [];\nconst tiktokResults = $('schedule-tiktok').all() || [];\nconst youtubeResults = $('schedule-youtube').all() || [];\n\nconst allScheduleResults = [...instagramResults, ...tiktokResults, ...youtubeResults];\n\n// Process each result\nfor (const result of allScheduleResults) {\n const success = result.json && !result.json.error;\n allResults.push({\n filename: $('parse-content').item.json.filename,\n platform: result.json?.network || 'unknown',\n scheduleDate: $('parse-content').item.json.scheduleDate,\n status: success ? 'Success' : 'Failed',\n error: result.json?.error || '',\n postId: result.json?.id || ''\n });\n}\n\n// Return summary\nreturn {\n json: {\n totalProcessed: allResults.length,\n successful: allResults.filter(r => r.status === 'Success').length,\n failed: allResults.filter(r => r.status === 'Failed').length,\n results: allResults,\n completedAt: new Date().toISOString()\n }\n};"
},
"id": "collect-results",
"name": "Collect Results",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1800,
300
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={\n \"success\": true,\n \"message\": \"TagDrop workflow completed successfully\",\n \"summary\": {\n \"totalFiles\": {{ $json.totalProcessed }},\n \"successful\": {{ $json.successful }},\n \"failed\": {{ $json.failed }},\n \"completedAt\": \"{{ $json.completedAt }}\"\n },\n \"results\": {{ $json.results }}\n}",
"options": {}
},
"id": "webhook-response",
"name": "Send Response",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
2000,
300
]
}
],
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "Parse Inputs & Files",
"type": "main",
"index": 0
}
]
]
},
"Parse Inputs & Files": {
"main": [
[
{
"node": "Generate Content (GPT-4)",
"type": "main",
"index": 0
}
]
]
},
"Generate Content (GPT-4)": {
"main": [
[
{
"node": "Parse Content & Schedule",
"type": "main",
"index": 0
}
]
]
},
"Parse Content & Schedule": {
"main": [
[
{
"node": "Upload Video to Metricool",
"type": "main",
"index": 0
}
]
]
},
"Upload Video to Metricool": {
"main": [
[
{
"node": "Split by Platform",
"type": "main",
"index": 0
}
]
]
},
"Split by Platform": {
"main": [
[
{
"node": "Instagram Check",
"type": "main",
"index": 0
},
{
"node": "TikTok Check",
"type": "main",
"index": 0
},
{
"node": "YouTube Check",
"type": "main",
"index": 0
}
]
]
},
"Instagram Check": {
"main": [
[
{
"node": "Schedule Instagram Post",
"type": "main",
"index": 0
}
]
]
},
"TikTok Check": {
"main": [
[
{
"node": "Schedule TikTok Post",
"type": "main",
"index": 0
}
]
]
},
"YouTube Check": {
"main": [
[
{
"node": "Schedule YouTube Short",
"type": "main",
"index": 0
}
]
]
},
"Schedule Instagram Post": {
"main": [
[
{
"node": "Collect Results",
"type": "main",
"index": 0
}
]
]
},
"Schedule TikTok Post": {
"main": [
[
{
"node": "Collect Results",
"type": "main",
"index": 0
}
]
]
},
"Schedule YouTube Short": {
"main": [
[
{
"node": "Collect Results",
"type": "main",
"index": 0
}
]
]
},
"Collect Results": {
"main": [
[
{
"node": "Send Response",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [],
"triggerCount": 0,
"updatedAt": "2025-01-01T00:00:00.000Z",
"versionId": "1"
}
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.
httpHeaderAuthopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
TagDrop Content Automation. Uses openAi, httpRequest. Webhook trigger; 14 nodes.
Source: https://gist.github.com/sanandreasfault/fe36daa995f08b39bab2c3ca15263ab9 — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This powerful n8n automation workflow is designed to execute advanced B2B lead enrichment and hyper-personalization for cold email outreach. By orchestrating a complex chain of data scraping, AI analy
Propulsar — Content Engine v3. Uses openAi, httpRequest, googleSheets. Webhook trigger; 73 nodes.
Eu Clara – Funil Kiwify Completo. Uses postgres, openAi, httpRequest, gmail. Webhook trigger; 70 nodes.
This workflow bridges the gap between raw product data and revenue sales tools. It automates the entire Product Qualified Lead (PQL) lifecycle—from real-time intent routing to churn prevention—reducin
Lua Nova - Sistema Completo. Uses postgres, httpRequest, openAi. Webhook trigger; 55 nodes.