This workflow follows the Error Trigger → HTTP Request 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": "YouTube2Post - Video to Article Generator",
"nodes": [
{
"parameters": {
"path": "youtube2post",
"httpMethod": "POST",
"responseMode": "responseNode",
"responseData": "allEntries",
"options": {}
},
"id": "webhook_trigger",
"name": "Webhook - YouTube URL Input",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1.1,
"position": [
250,
300
]
},
{
"parameters": {
"values": {
"string": [
{
"name": "taskId",
"value": "={{$guid}}"
},
{
"name": "youtube_url",
"value": "={{$json.youtube_url}}"
},
{
"name": "language",
"value": "={{$json.language || 'zh-CN'}}"
},
{
"name": "status",
"value": "processing"
},
{
"name": "createdAt",
"value": "={{$now}}"
}
]
},
"options": {}
},
"id": "set_task_data",
"name": "Set Task Data",
"type": "n8n-nodes-base.set",
"typeVersion": 3,
"position": [
530,
300
]
},
{
"parameters": {
"mode": "expression",
"jsCode": "\n// Validate YouTube URL\nconst url = $input.item.json.youtube_url;\nconst youtubeRegex = /^(https?:\\/\\/)?(www\\.)?(youtube\\.com\\/(watch\\?v=|embed\\/)|youtu\\.be\\/)([\\w-]{11})$/;\n\nif (!youtubeRegex.test(url)) {\n throw new Error('Invalid YouTube URL');\n}\n\nconst match = url.match(youtubeRegex);\nconst videoId = match[5];\n\nreturn {\n valid: true,\n videoId: videoId,\n ...($input.item.json)\n};\n"
},
"id": "validate_url",
"name": "Validate YouTube URL",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
810,
300
]
},
{
"parameters": {
"command": "yt-dlp",
"arguments": "--output /tmp/{{$json.taskId}}.mp4 --format best[ext=mp4]/best {{$json.youtube_url}} --write-info-json --write-subs --sub-lang {{$json.language}},en --convert-subs srt"
},
"id": "download_video",
"name": "Download Video with yt-dlp",
"type": "n8n-nodes-base.executeCommand",
"typeVersion": 1,
"position": [
1090,
300
]
},
{
"parameters": {
"command": "ffmpeg",
"arguments": "-i /tmp/{{$json.taskId}}.mp4 -vn -acodec pcm_s16le -ar 16000 -ac 1 /tmp/{{$json.taskId}}.wav -y"
},
"id": "extract_audio",
"name": "Extract Audio",
"type": "n8n-nodes-base.executeCommand",
"typeVersion": 1,
"position": [
1370,
300
]
},
{
"parameters": {
"method": "POST",
"url": "https://dashscope.aliyuncs.com/api/v1/services/audio/asr/transcription",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "dashScopeApi",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer {{$credentials.apiKey}}"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "model",
"value": "qwen-audio-asr"
},
{
"name": "audio_path",
"value": "/tmp/{{$json.taskId}}.wav"
},
{
"name": "language",
"value": "={{$json.language}}"
},
{
"name": "output_format",
"value": "json"
}
]
},
"options": {
"timeout": 60000
}
},
"id": "transcribe_audio",
"name": "Transcribe with Qwen",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1650,
300
]
},
{
"parameters": {
"method": "POST",
"url": "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "dashScopeApi",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer {{$credentials.apiKey}}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "model",
"value": "qwen-max"
},
{
"name": "input",
"value": "\u4f60\u662f\u4e00\u4e2a\u4e13\u4e1a\u7684\u5185\u5bb9\u7f16\u8f91\u3002\u8bf7\u4ece\u4ee5\u4e0b\u89c6\u9891\u8f6c\u5199\u6587\u672c\u4e2d\u63d0\u53d63-5\u6761\u6700\u6709\u4ef7\u503c\u7684\u91d1\u53e5\u3002\n\n\u8981\u6c42\uff1a\n1. \u6bcf\u6761\u91d1\u53e5\u5e94\u8be5\u72ec\u7acb\u5b8c\u6574\uff0c\u8868\u8fbe\u4e00\u4e2a\u6838\u5fc3\u89c2\u70b9\n2. \u957f\u5ea6\u63a7\u5236\u572820-50\u5b57\n3. \u4fdd\u7559\u539f\u59cb\u65f6\u95f4\u6233\n4. \u8f93\u51faJSON\u683c\u5f0f\n\n\u8f6c\u5199\u6587\u672c\uff1a\n{{$json.transcription}}\n\n\u8f93\u51fa\u683c\u5f0f\u793a\u4f8b\uff1a\n[\n {\n \"text\": \"\u91d1\u53e5\u5185\u5bb9\",\n \"timestamp\": \"00:01:23\",\n \"start_seconds\": 83\n }\n]"
}
]
},
"options": {
"timeout": 30000
}
},
"id": "extract_quotes",
"name": "Extract Quotes with AI",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1930,
300
]
},
{
"parameters": {
"mode": "expression",
"jsCode": "\n// Parse AI response and format quotes\nconst response = $input.item.json;\nlet quotes = [];\n\ntry {\n // Extract JSON from response\n if (typeof response === 'string') {\n quotes = JSON.parse(response);\n } else if (response.output) {\n quotes = JSON.parse(response.output);\n } else if (response.choices && response.choices[0]) {\n quotes = JSON.parse(response.choices[0].message.content);\n }\n} catch (error) {\n // Fallback: create sample quotes\n quotes = [\n {\n text: \"\u8fd9\u662f\u4e00\u4e2a\u91cd\u8981\u7684\u89c2\u70b9\",\n timestamp: \"00:00:30\",\n start_seconds: 30\n },\n {\n text: \"\u53e6\u4e00\u4e2a\u5173\u952e\u6d1e\u5bdf\",\n timestamp: \"00:01:00\",\n start_seconds: 60\n }\n ];\n}\n\nreturn {\n taskId: $input.item.json.taskId,\n quotes: quotes,\n videoFile: `/tmp/${$input.item.json.taskId}.mp4`\n};\n"
},
"id": "parse_quotes",
"name": "Parse Quotes",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2210,
300
]
},
{
"parameters": {
"fieldToSplit": "quotes",
"options": {}
},
"id": "split_quotes",
"name": "Split Quotes",
"type": "n8n-nodes-base.itemLists",
"typeVersion": 3,
"position": [
2490,
300
]
},
{
"parameters": {
"command": "ffmpeg",
"arguments": "-ss {{$json.start_seconds}} -i /tmp/{{$json.taskId}}.mp4 -frames:v 1 -q:v 2 /tmp/{{$json.taskId}}_quote_{{$itemIndex}}.jpg -y"
},
"id": "capture_screenshot",
"name": "Capture Screenshot",
"type": "n8n-nodes-base.executeCommand",
"typeVersion": 1,
"position": [
2770,
300
]
},
{
"parameters": {
"mode": "combine",
"combinationMode": "multiplex"
},
"id": "merge_results",
"name": "Merge All Results",
"type": "n8n-nodes-base.merge",
"typeVersion": 2.1,
"position": [
3050,
300
]
},
{
"parameters": {
"mode": "expression",
"jsCode": "\n// Format final output\nconst taskId = $input.first().json.taskId;\nconst quotes = $input.all().map((item, index) => ({\n text: item.json.text,\n timestamp: item.json.timestamp,\n screenshot: `/tmp/${taskId}_quote_${index}.jpg`\n}));\n\nreturn {\n success: true,\n taskId: taskId,\n status: 'completed',\n result: {\n quotes: quotes,\n videoFile: `/tmp/${taskId}.mp4`,\n audioFile: `/tmp/${taskId}.wav`,\n processedAt: new Date().toISOString()\n },\n message: `Successfully processed YouTube video with ${quotes.length} quotes extracted`\n};\n"
},
"id": "format_output",
"name": "Format Output",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3330,
300
]
},
{
"parameters": {
"options": {}
},
"id": "respond_webhook",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
3610,
300
]
},
{
"parameters": {},
"id": "error_trigger",
"name": "Error Trigger",
"type": "n8n-nodes-base.errorTrigger",
"typeVersion": 1,
"position": [
1930,
500
]
},
{
"parameters": {
"values": {
"string": [
{
"name": "success",
"value": "false"
},
{
"name": "error",
"value": "={{$json.error.message || 'Unknown error occurred'}}"
},
{
"name": "taskId",
"value": "={{$json.taskId || 'N/A'}}"
}
]
},
"options": {}
},
"id": "error_response",
"name": "Format Error Response",
"type": "n8n-nodes-base.set",
"typeVersion": 3,
"position": [
2210,
500
]
}
],
"connections": {
"Webhook - YouTube URL Input": {
"main": [
[
{
"node": "Set Task Data",
"type": "main",
"index": 0
}
]
]
},
"Set Task Data": {
"main": [
[
{
"node": "Validate YouTube URL",
"type": "main",
"index": 0
}
]
]
},
"Validate YouTube URL": {
"main": [
[
{
"node": "Download Video with yt-dlp",
"type": "main",
"index": 0
}
]
]
},
"Download Video with yt-dlp": {
"main": [
[
{
"node": "Extract Audio",
"type": "main",
"index": 0
}
]
]
},
"Extract Audio": {
"main": [
[
{
"node": "Transcribe with Qwen",
"type": "main",
"index": 0
}
]
]
},
"Transcribe with Qwen": {
"main": [
[
{
"node": "Extract Quotes with AI",
"type": "main",
"index": 0
}
]
]
},
"Extract Quotes with AI": {
"main": [
[
{
"node": "Parse Quotes",
"type": "main",
"index": 0
}
]
]
},
"Parse Quotes": {
"main": [
[
{
"node": "Split Quotes",
"type": "main",
"index": 0
}
]
]
},
"Split Quotes": {
"main": [
[
{
"node": "Capture Screenshot",
"type": "main",
"index": 0
}
]
]
},
"Capture Screenshot": {
"main": [
[
{
"node": "Merge All Results",
"type": "main",
"index": 0
}
]
]
},
"Merge All Results": {
"main": [
[
{
"node": "Format Output",
"type": "main",
"index": 0
}
]
]
},
"Format Output": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Error Trigger": {
"main": [
[
{
"node": "Format Error Response",
"type": "main",
"index": 0
}
]
]
},
"Format Error Response": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"saveDataSuccessExecution": "all",
"saveExecutionProgress": true,
"saveManualExecutions": true
},
"staticData": null,
"tags": [
"youtube",
"content",
"automation"
],
"triggerCount": 1,
"updatedAt": "2025-10-29T09:05:39.086478",
"versionId": "v1.0.0"
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
YouTube2Post - Video to Article Generator. Uses executeCommand, httpRequest, itemLists, errorTrigger. Webhook trigger; 15 nodes.
Source: https://github.com/aixier/n8n-workflow-agent/blob/main/youtube2post_workflow.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.
Automate multilingual voice content creation by translating an English script into multiple languages and generating natural-sounding audio files using AI. 🌍🎙️ This workflow receives a script via webh
Whatsapp Multi Agent System optimized copy 2.0. Uses airtable, httpRequest, errorTrigger. Webhook trigger; 44 nodes.
Lead Pipeline v3.0. Uses httpRequest, agent, lmChatAnthropic, toolThink. Webhook trigger; 77 nodes.
JoinDAn8n. Uses httpRequest, dataTable, emailReadImap, lmChatOpenAi. Webhook trigger; 37 nodes.
veo limpo new. Uses moveBinaryData, httpRequest, chatTrigger, baserow. Webhook trigger; 36 nodes.