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": "YouTube Processor - Full Version",
"nodes": [
{
"parameters": {
"content": "## YouTube Video Processor\n\n\u529f\u80fd\uff1a\n1. \u9a8c\u8bc1YouTube URL\n2. \u63d0\u53d6\u89c6\u9891ID\n3. \u83b7\u53d6\u89c6\u9891\u5143\u6570\u636e\uff08\u6a21\u62df\uff09\n4. \u751f\u6210\u6587\u7ae0\u5185\u5bb9\n5. \u8fd4\u56de\u5904\u7406\u7ed3\u679c",
"height": 150,
"width": 400,
"color": "#FF6B6B"
},
"id": "note_doc",
"name": "Documentation",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
250,
50
]
},
{
"parameters": {
"httpMethod": "POST",
"path": "youtube-processor-full",
"responseMode": "lastNode",
"options": {
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Access-Control-Allow-Origin",
"value": "*"
}
]
}
}
},
"id": "webhook_trigger",
"name": "\u63a5\u6536YouTube URL",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1.1,
"position": [
250,
250
]
},
{
"parameters": {
"jsCode": "// \u9a8c\u8bc1URL\u5e76\u63d0\u53d6YouTube\u89c6\u9891ID\nconst input = $input.item.json.body || $input.item.json;\nconst url = input.youtube_url || input.url || '';\n\nif (!url) {\n return {\n success: false,\n error: {\n code: 'MISSING_URL',\n message: 'YouTube URL is required',\n timestamp: new Date().toISOString()\n }\n };\n}\n\n// \u652f\u6301\u591a\u79cdYouTube URL\u683c\u5f0f\nconst patterns = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/shorts\\/)([\\w-]{11})/,\n /youtube\\.com\\/embed\\/([\\w-]{11})/,\n /youtube\\.com\\/v\\/([\\w-]{11})/\n];\n\nlet videoId = null;\nlet urlType = 'unknown';\n\nfor (const pattern of patterns) {\n const match = url.match(pattern);\n if (match) {\n videoId = match[1];\n if (pattern.source.includes('watch\\?v')) urlType = 'standard';\n else if (pattern.source.includes('youtu\\.be')) urlType = 'short';\n else if (pattern.source.includes('shorts')) urlType = 'shorts';\n else if (pattern.source.includes('embed')) urlType = 'embed';\n break;\n }\n}\n\nif (!videoId) {\n return {\n success: false,\n error: {\n code: 'INVALID_URL',\n message: 'Invalid YouTube URL format',\n supportedFormats: [\n 'https://www.youtube.com/watch?v=VIDEO_ID',\n 'https://youtu.be/VIDEO_ID',\n 'https://youtube.com/shorts/VIDEO_ID',\n 'https://www.youtube.com/embed/VIDEO_ID'\n ],\n timestamp: new Date().toISOString()\n }\n };\n}\n\n// \u9a8c\u8bc1videoId\u683c\u5f0f\uff0811\u4e2a\u5b57\u7b26\u7684\u5b57\u6bcd\u6570\u5b57\u7ec4\u5408\uff09\nif (!/^[\\w-]{11}$/.test(videoId)) {\n return {\n success: false,\n error: {\n code: 'INVALID_VIDEO_ID',\n message: 'Invalid YouTube video ID',\n videoId: videoId,\n timestamp: new Date().toISOString()\n }\n };\n}\n\nreturn {\n success: true,\n videoId: videoId,\n originalUrl: url,\n urlType: urlType,\n language: input.language || 'zh-CN',\n requestId: Math.random().toString(36).substr(2, 9),\n processStep: 'url_validated',\n timestamp: new Date().toISOString()\n};"
},
"id": "validate_url",
"name": "\u9a8c\u8bc1URL\u5e76\u63d0\u53d6ID",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
450,
250
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json.success }}",
"value2": true
}
]
}
},
"id": "check_validation",
"name": "\u68c0\u67e5\u9a8c\u8bc1\u7ed3\u679c",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
650,
250
]
},
{
"parameters": {
"jsCode": "// \u6a21\u62df\u83b7\u53d6YouTube\u89c6\u9891\u5143\u6570\u636e\n// \u5728\u5b9e\u9645\u5e94\u7528\u4e2d\uff0c\u8fd9\u91cc\u4f1a\u8c03\u7528YouTube Data API v3\nconst data = $input.item.json;\n\n// \u6a21\u62df\u89c6\u9891\u5143\u6570\u636e\uff08\u57fa\u4e8evideoId\u751f\u6210\u786e\u5b9a\u6027\u6570\u636e\uff09\nconst videoId = data.videoId;\nconst hash = videoId.split('').reduce((a, b) => ((a << 5) - a + b.charCodeAt(0)) & 0xffffffff, 0);\n\n// \u4f7f\u7528videoID\u751f\u6210\u4f2a\u968f\u673a\u7684\u89c6\u9891\u4fe1\u606f\nconst mockVideos = {\n '_ss8tOxWAuo': {\n title: '2024\u5e74AI\u6280\u672f\u53d1\u5c55\u603b\u7ed3',\n description: '\u672c\u89c6\u9891\u5168\u9762\u56de\u987e\u4e862024\u5e74\u4eba\u5de5\u667a\u80fd\u9886\u57df\u7684\u91cd\u8981\u7a81\u7834\uff0c\u5305\u62ec\u5927\u6a21\u578b\u7684\u53d1\u5c55\u3001AI\u5728\u5404\u884c\u4e1a\u7684\u5e94\u7528\u3001\u4ee5\u53ca\u5bf9\u672a\u6765\u7684\u5c55\u671b\u3002',\n channelTitle: '\u79d1\u6280\u524d\u6cbf',\n duration: '15:30',\n viewCount: Math.floor((hash % 1000000) + 50000),\n likeCount: Math.floor((hash % 50000) + 1000),\n publishDate: '2024-01-15T10:00:00Z',\n tags: ['AI', '\u4eba\u5de5\u667a\u80fd', '\u79d1\u6280', '2024\u603b\u7ed3', '\u6280\u672f\u8d8b\u52bf']\n }\n};\n\n// \u83b7\u53d6\u6216\u751f\u6210\u89c6\u9891\u4fe1\u606f\nlet videoInfo = mockVideos[videoId] || {\n title: `\u89c6\u9891\u6807\u9898 - ${videoId}`,\n description: `\u8fd9\u662f\u89c6\u9891ID\u4e3a${videoId}\u7684\u63cf\u8ff0\u5185\u5bb9\u3002\u89c6\u9891\u8bb2\u8ff0\u4e86\u5173\u4e8e\u6280\u672f\u548c\u521b\u65b0\u7684\u91cd\u8981\u8bdd\u9898\u3002`,\n channelTitle: '\u79d1\u6280\u9891\u9053',\n duration: `${Math.floor(Math.abs(hash % 30) + 1)}:${String(Math.abs(hash % 60)).padStart(2, '0')}`,\n viewCount: Math.floor(Math.abs(hash % 1000000) + 10000),\n likeCount: Math.floor(Math.abs(hash % 50000) + 500),\n publishDate: new Date(Date.now() - Math.abs(hash % 365) * 24 * 60 * 60 * 1000).toISOString(),\n tags: ['\u6280\u672f', '\u521b\u65b0', '\u89c6\u9891', '\u5185\u5bb9']\n};\n\n// \u6784\u5efa\u5b8c\u6574\u7684\u89c6\u9891\u5143\u6570\u636e\nconst videoMetadata = {\n videoId: videoId,\n title: videoInfo.title,\n description: videoInfo.description,\n channelTitle: videoInfo.channelTitle,\n duration: videoInfo.duration,\n durationSeconds: parseDuration(videoInfo.duration),\n viewCount: videoInfo.viewCount,\n likeCount: videoInfo.likeCount,\n publishDate: videoInfo.publishDate,\n publishDateFormatted: formatDate(videoInfo.publishDate),\n tags: videoInfo.tags,\n thumbnails: {\n default: `https://img.youtube.com/vi/${videoId}/default.jpg`,\n medium: `https://img.youtube.com/vi/${videoId}/mqdefault.jpg`,\n high: `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`,\n maxres: `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`\n },\n urls: {\n watch: `https://www.youtube.com/watch?v=${videoId}`,\n embed: `https://www.youtube.com/embed/${videoId}`,\n share: `https://youtu.be/${videoId}`\n }\n};\n\n// \u8f85\u52a9\u51fd\u6570\nfunction parseDuration(duration) {\n const parts = duration.split(':');\n return parseInt(parts[0]) * 60 + parseInt(parts[1]);\n}\n\nfunction formatDate(dateStr) {\n const date = new Date(dateStr);\n return date.toLocaleDateString('zh-CN', { \n year: 'numeric',\n month: 'long',\n day: 'numeric'\n });\n}\n\nreturn {\n ...data,\n videoMetadata: videoMetadata,\n processStep: 'metadata_fetched',\n processTime: Date.now() - new Date(data.timestamp).getTime()\n};"
},
"id": "fetch_metadata",
"name": "\u83b7\u53d6\u89c6\u9891\u5143\u6570\u636e",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
850,
200
]
},
{
"parameters": {
"jsCode": "// \u751f\u6210\u57fa\u4e8e\u89c6\u9891\u7684\u6587\u7ae0\u5185\u5bb9\nconst data = $input.item.json;\nconst metadata = data.videoMetadata;\nconst language = data.language || 'zh-CN';\n\n// \u751f\u6210\u6587\u7ae0\u5185\u5bb9\nconst article = {\n title: metadata.title + ' - \u6df1\u5ea6\u89e3\u6790',\n summary: `\u57fa\u4e8eYouTube\u89c6\u9891\u300a${metadata.title}\u300b\u751f\u6210\u7684\u5185\u5bb9\u89e3\u6790\u3002\u672c\u6587\u4ece\u89c6\u9891\u7684\u6838\u5fc3\u89c2\u70b9\u51fa\u53d1\uff0c\u6df1\u5165\u63a2\u8ba8\u76f8\u5173\u4e3b\u9898\uff0c\u4e3a\u8bfb\u8005\u63d0\u4f9b\u8be6\u7ec6\u7684\u77e5\u8bc6\u603b\u7ed3\u548c\u89c1\u89e3\u3002`,\n \n sections: [\n {\n heading: '\u89c6\u9891\u6982\u8ff0',\n content: `\u672c\u6587\u57fa\u4e8e${metadata.channelTitle}\u9891\u9053\u53d1\u5e03\u7684\u89c6\u9891\u300a${metadata.title}\u300b\u3002\u8be5\u89c6\u9891\u65f6\u957f${metadata.duration}\uff0c\u5df2\u83b7\u5f97${metadata.viewCount.toLocaleString()}\u6b21\u89c2\u770b\uff0c\u53d1\u5e03\u4e8e${metadata.publishDateFormatted}\u3002\u89c6\u9891\u4e3b\u8981\u5185\u5bb9\u6db5\u76d6\u4e86${metadata.tags.slice(0, 3).join('\u3001')}\u7b49\u5173\u952e\u4e3b\u9898\u3002`,\n type: 'introduction'\n },\n \n {\n heading: '\u6838\u5fc3\u5185\u5bb9\u89e3\u6790',\n content: metadata.description,\n type: 'main_content',\n bulletPoints: [\n '\u8981\u70b9\u4e00\uff1a\u89c6\u9891\u5f3a\u8c03\u4e86\u6280\u672f\u521b\u65b0\u7684\u91cd\u8981\u6027',\n '\u8981\u70b9\u4e8c\uff1a\u63d0\u4f9b\u4e86\u5b9e\u7528\u7684\u89e3\u51b3\u65b9\u6848\u548c\u6848\u4f8b',\n '\u8981\u70b9\u4e09\uff1a\u5c55\u671b\u4e86\u672a\u6765\u7684\u53d1\u5c55\u8d8b\u52bf',\n '\u8981\u70b9\u56db\uff1a\u5206\u4eab\u4e86\u5b9d\u8d35\u7684\u7ecf\u9a8c\u548c\u89c1\u89e3'\n ]\n },\n \n {\n heading: '\u5173\u952e\u6570\u636e\u4e0e\u7edf\u8ba1',\n content: {\n videoId: metadata.videoId,\n duration: metadata.duration,\n views: metadata.viewCount.toLocaleString() + '\u6b21\u89c2\u770b',\n likes: metadata.likeCount.toLocaleString() + '\u4e2a\u70b9\u8d5e',\n publishDate: metadata.publishDateFormatted,\n channel: metadata.channelTitle,\n tags: metadata.tags.join(', ')\n },\n type: 'statistics'\n },\n \n {\n heading: '\u5ef6\u4f38\u601d\u8003',\n content: `\u4ece\u89c6\u9891\u5185\u5bb9\u53ef\u4ee5\u770b\u51fa\uff0c${metadata.tags[0]}\u9886\u57df\u6b63\u5728\u5feb\u901f\u53d1\u5c55\u3002\u5bf9\u4e8e\u5173\u6ce8\u8fd9\u4e00\u9886\u57df\u7684\u89c2\u4f17\u6765\u8bf4\uff0c\u7406\u89e3\u89c6\u9891\u4e2d\u7684\u6838\u5fc3\u89c2\u70b9\u5bf9\u4e8e\u628a\u63e1\u884c\u4e1a\u52a8\u6001\u81f3\u5173\u91cd\u8981\u3002\u5efa\u8bae\u89c2\u4f17\u7ed3\u5408\u81ea\u8eab\u9700\u6c42\uff0c\u6df1\u5165\u601d\u8003\u5982\u4f55\u5c06\u8fd9\u4e9b\u77e5\u8bc6\u5e94\u7528\u5230\u5b9e\u9645\u573a\u666f\u4e2d\u3002`,\n type: 'reflection'\n },\n \n {\n heading: '\u76f8\u5173\u8d44\u6e90',\n content: {\n videoLink: metadata.urls.watch,\n embedLink: metadata.urls.embed,\n thumbnails: metadata.thumbnails,\n suggestedTopics: metadata.tags.map(tag => `\u5173\u4e8e${tag}\u7684\u66f4\u591a\u8d44\u6e90`)\n },\n type: 'resources'\n }\n ],\n \n metadata: {\n generatedAt: new Date().toISOString(),\n language: language,\n wordCount: Math.floor(Math.random() * 500 + 800),\n estimatedReadTime: Math.floor(Math.random() * 3 + 3) + '\u5206\u949f',\n source: 'YouTube Video',\n sourceUrl: metadata.urls.watch,\n videoId: metadata.videoId\n }\n};\n\n// \u6dfb\u52a0\u793e\u4ea4\u5a92\u4f53\u6458\u8981\nconst socialSummary = {\n twitter: `${article.title.substring(0, 100)}... #AI #\u6280\u672f\u5206\u4eab`,\n linkedin: `\u6df1\u5165\u89e3\u6790${metadata.title}\uff0c\u63a2\u8ba8${metadata.tags[0]}\u9886\u57df\u7684\u53d1\u5c55\u8d8b\u52bf\u3002`,\n weibo: `\u3010\u89c6\u9891\u89e3\u6790\u3011${article.title} \u57fa\u4e8eYouTube\u89c6\u9891\u7684\u6df1\u5ea6\u5185\u5bb9\u89e3\u6790\uff0c${metadata.viewCount}\u6b21\u89c2\u770b\u7684\u70ed\u95e8\u5185\u5bb9\uff01`\n};\n\nreturn {\n ...data,\n article: article,\n socialSummary: socialSummary,\n processStep: 'content_generated',\n totalProcessTime: Date.now() - new Date(data.timestamp).getTime()\n};"
},
"id": "generate_content",
"name": "\u751f\u6210\u6587\u7ae0\u5185\u5bb9",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1050,
200
]
},
{
"parameters": {
"values": {
"string": [
{
"name": "status",
"value": "completed"
},
{
"name": "message",
"value": "YouTube\u89c6\u9891\u5904\u7406\u5b8c\u6210"
},
{
"name": "success",
"value": true
}
],
"number": [
{
"name": "finalProcessTime",
"value": "={{ $json.totalProcessTime }}"
}
]
},
"options": {}
},
"id": "add_final_metadata",
"name": "\u6dfb\u52a0\u6700\u7ec8\u5143\u6570\u636e",
"type": "n8n-nodes-base.set",
"typeVersion": 2,
"position": [
1250,
200
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json, null, 2) }}",
"options": {}
},
"id": "return_success",
"name": "\u8fd4\u56de\u6210\u529f\u7ed3\u679c",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
1450,
200
]
},
{
"parameters": {
"jsCode": "// \u683c\u5f0f\u5316\u9519\u8bef\u54cd\u5e94\nconst error = $input.item.json;\n\nreturn {\n success: false,\n error: error.error || {\n code: 'UNKNOWN_ERROR',\n message: '\u5904\u7406\u8fc7\u7a0b\u4e2d\u53d1\u751f\u672a\u77e5\u9519\u8bef'\n },\n requestId: error.requestId || 'unknown',\n timestamp: new Date().toISOString(),\n processStep: 'error_occurred'\n};"
},
"id": "format_error",
"name": "\u683c\u5f0f\u5316\u9519\u8bef",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
850,
400
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json) }}",
"options": {}
},
"id": "return_error",
"name": "\u8fd4\u56de\u9519\u8bef",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
1050,
400
]
}
],
"connections": {
"webhook_trigger": {
"main": [
[
{
"node": "validate_url",
"type": "main",
"index": 0
}
]
]
},
"validate_url": {
"main": [
[
{
"node": "check_validation",
"type": "main",
"index": 0
}
]
]
},
"check_validation": {
"main": [
[
{
"node": "fetch_metadata",
"type": "main",
"index": 0
}
],
[
{
"node": "format_error",
"type": "main",
"index": 0
}
]
]
},
"fetch_metadata": {
"main": [
[
{
"node": "generate_content",
"type": "main",
"index": 0
}
]
]
},
"generate_content": {
"main": [
[
{
"node": "add_final_metadata",
"type": "main",
"index": 0
}
]
]
},
"add_final_metadata": {
"main": [
[
{
"node": "return_success",
"type": "main",
"index": 0
}
]
]
},
"format_error": {
"main": [
[
{
"node": "return_error",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
YouTube Processor - Full Version. Webhook trigger; 10 nodes.
Source: https://github.com/aixier/n8n-workflow-agent/blob/main/youtube_processor_full.json — 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.
Jigsaw API key for image processing, I use this as a gatekeeper/second pair of eyes. LINK to their website https://jigsawstack.com/ SECOND A postgress DATABASE (I use Supabase) LlamaCloud for the pars
Whatsapp Multi Agent System optimized copy 2.0. Uses airtable, httpRequest, errorTrigger. Webhook trigger; 44 nodes.
Invoice Agent. Uses httpRequest, emailSend. Webhook trigger; 29 nodes.
Reputation Engine — SEO QA Agent. Uses httpRequest. Webhook trigger; 28 nodes.
This workflow handles incoming voice calls or audio messages, transcribes them using Whisper (OpenAI) or ElevenLabs, extracts booking intent and preferred time slots using AI, checks availability on C