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": "YouTube \u2192 Audio \u2192 Transcribe \u2192 Summarize (Deepgram)",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "yt-audio-sum",
"responseMode": "lastNode",
"options": {
"responseData": {
"responsePropertyName": "data"
}
}
},
"id": "Webhook_1",
"name": "Webhook (trigger)",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
-1400,
0
]
},
{
"parameters": {
"functionCode": "const body = items[0].json || {};\nconst url = body.url || body.input || body.link || '';\nif (!url) throw new Error('\u8bf7\u5728 JSON body \u91cc\u4f20\u5165 { \"url\": \"<YouTube\u5730\u5740>\" }');\nconst m = url.match(/(?:v=|youtu\\.be\\/|shorts\\/)([A-Za-z0-9_-]{11})/);\nif (!m) throw new Error('\u65e0\u6cd5\u4ece\u94fe\u63a5\u4e2d\u89e3\u6790\u51fa videoId');\nreturn [{ url, videoId: m[1] }];"
},
"id": "Function_ExtractId",
"name": "Extract videoId",
"type": "n8n-nodes-base.function",
"typeVersion": 2,
"position": [
-1150,
0
]
},
{
"parameters": {
"url": "https://piped.video/api/v1/streams/{{$json.videoId}}",
"options": {
"timeout": 30000
}
},
"id": "HTTP_GetStreams",
"name": "Get Streams (Piped)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 3,
"position": [
-900,
0
]
},
{
"parameters": {
"functionCode": "const res = items[0].json;\nif (!res || !Array.isArray(res.audioStreams)) {\n throw new Error('\u672a\u83b7\u53d6\u5230\u97f3\u9891\u6d41\u4fe1\u606f');\n}\n// \u9009\u7801\u7387\u6700\u9ad8\u7684\u97f3\u9891\uff1b\u4f18\u5148 opus/webm \u5176\u540e m4a/mp4a\nconst prefer = s => ({\n codec: (s.codec || '').toLowerCase(),\n mime: (s.mimeType || '').toLowerCase(),\n br: Number(s.bitrate || 0),\n});\nlet best = null;\nfor (const s of res.audioStreams) {\n const p = prefer(s);\n const score = (p.br || 0)\n + (p.codec.includes('opus') ? 50000 : 0)\n + (p.mime.includes('webm') ? 20000 : 0)\n + (p.mime.includes('mp4') || p.mime.includes('m4a') ? 10000 : 0);\n if (!best || score > best._score) {\n best = { ...s, _score: score };\n }\n}\nif (!best || !best.url) throw new Error('\u6ca1\u6709\u53ef\u7528\u7684\u97f3\u9891\u76f4\u94fe');\nreturn [{\n videoId: $json.videoId,\n sourceUrl: $json.url,\n audioUrl: best.url,\n audioInfo: best\n}];"
},
"id": "Function_PickAudio",
"name": "Pick Best Audio",
"type": "n8n-nodes-base.function",
"typeVersion": 2,
"position": [
-650,
0
]
},
{
"parameters": {
"url": "https://api.deepgram.com/v1/listen?model=nova-2&punctuate=true¶graphs=true&detect_language=true&smart_format=true",
"options": {
"timeout": 180000
},
"sendBody": true,
"jsonParameters": true,
"bodyParametersJson": "{\"url\":\"{{$json.audioUrl}}\"}",
"headerParametersJson": "{\"Authorization\":\"Token YOUR_DEEPGRAM_API_KEY\",\"Content-Type\":\"application/json\"}",
"responseFormat": "json"
},
"id": "HTTP_Deepgram",
"name": "Transcribe (Deepgram)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 3,
"position": [
-390,
0
]
},
{
"parameters": {
"functionCode": "const dg = items[0].json;\n// \u517c\u5bb9\u4e0d\u540c\u8fd4\u56de\u7ed3\u6784\uff0c\u5c3d\u91cf\u53d6\u6bb5\u843d\nlet text = '';\ntry {\n const alt = dg.results?.channels?.[0]?.alternatives?.[0];\n const paras = alt?.paragraphs?.paragraphs;\n if (Array.isArray(paras) && paras.length) {\n text = paras.map(p => p.text).join('\\n\\n');\n }\n if (!text) text = alt?.transcript || '';\n} catch (e) {}\nif (!text) throw new Error('\u8f6c\u5199\u7ed3\u679c\u4e3a\u7a7a');\n// \u7b80\u5355\u6e05\u6d17\u4e0e\u5206\u5757\ntext = text.replace(/\\s+/g,' ').trim();\nconst chunks = [];\nconst chunkSize = 10000;\nfor (let i = 0; i < text.length; i += chunkSize) {\n chunks.push(text.slice(i, i + chunkSize));\n}\nreturn [{\n videoId: $json.videoId,\n sourceUrl: $json.sourceUrl,\n audioUrl: $json.audioUrl,\n transcript: text,\n chunks\n}];"
},
"id": "Function_CleanChunks",
"name": "Clean & Chunk Transcript",
"type": "n8n-nodes-base.function",
"typeVersion": 2,
"position": [
-140,
0
]
},
{
"parameters": {
"operation": "chat",
"model": "gpt-4o",
"systemMessage": "\u4f60\u662f\u4e13\u4e1a\u7684\u89c6\u9891\u7b14\u8bb0\u4e0e\u6458\u8981\u52a9\u624b\u3002\u8bf7\u57fa\u4e8e\u7528\u6237\u63d0\u4f9b\u7684\u9010\u5b57\u7a3f\uff0c\u8f93\u51fa\u7ed3\u6784\u5316\u4e2d\u6587\u603b\u7ed3\u3002\u8981\u6c42\uff1a\u51c6\u786e\u3001\u51dd\u7ec3\u3001\u53ef\u626b\u8bfb\uff1b\u5fc5\u8981\u65f6\u52a0\u5165\u7b80\u77ed\u65f6\u95f4\u6233\uff08\u5982\u679c\u80fd\u4ece\u8f6c\u5199\u91cc\u63a8\u65ad\uff09\u3002\u8f93\u51fa Markdown\uff0c\u5305\u542b\uff1a\\n1) 30 \u79d2\u901f\u89c8\uff083-6\u6761\u8981\u70b9\uff09\\n2) \u5173\u952e\u89c2\u70b9\u4e0e\u4e8b\u5b9e\uff08\u5206\u9879\u5217\u51fa\uff09\\n3) \u7ae0\u8282\u5927\u7eb2\uff08\u82e5\u80fd\uff0c\u7ed9\u51fa\u5927\u81f4\u65f6\u95f4\u70b9/\u8303\u56f4\uff09\\n4) \u884c\u52a8\u6e05\u5355 / \u5efa\u8bae\\n5) \u82e5\u4e3a\u6559\u7a0b/\u8bc4\u6d4b\uff1a\u7ed9\u51fa\u5de5\u5177/\u53c2\u6570/\u4f18\u7f3a\u70b9/\u7ed3\u8bba",
"messages": {
"messageUi": {
"message": [
{
"text": "<TRANSCRIPT>\\n{{$json.transcript}}\\n</TRANSCRIPT>",
"type": "user"
}
]
}
},
"additionalFields": {
"temperature": 0.3,
"maxTokens": 2200
}
},
"id": "OpenAI_Summarize",
"name": "Summarize (OpenAI)",
"type": "n8n-nodes-base.openAi",
"typeVersion": 4,
"position": [
120,
0
],
"credentials": {}
},
{
"parameters": {
"responseBody": "{{$json.choices[0].message.content}}",
"statusCode": 200,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "text/markdown; charset=utf-8"
}
]
}
},
"id": "Webhook_Response",
"name": "Respond",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
370,
0
]
}
],
"connections": {
"Webhook (trigger)": {
"main": [
[
{
"node": "Extract videoId",
"type": "main",
"index": 0
}
]
]
},
"Extract videoId": {
"main": [
[
{
"node": "Get Streams (Piped)",
"type": "main",
"index": 0
}
]
]
},
"Get Streams (Piped)": {
"main": [
[
{
"node": "Pick Best Audio",
"type": "main",
"index": 0
}
]
]
},
"Pick Best Audio": {
"main": [
[
{
"node": "Transcribe (Deepgram)",
"type": "main",
"index": 0
}
]
]
},
"Transcribe (Deepgram)": {
"main": [
[
{
"node": "Clean & Chunk Transcript",
"type": "main",
"index": 0
}
]
]
},
"Clean & Chunk Transcript": {
"main": [
[
{
"node": "Summarize (OpenAI)",
"type": "main",
"index": 0
}
]
]
},
"Summarize (OpenAI)": {
"main": [
[
{
"node": "Respond",
"type": "main",
"index": 0
}
]
]
}
},
"meta": {
"templateCredsSetup": true
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
YouTube → Audio → Transcribe → Summarize (Deepgram). Uses httpRequest, openAi. Webhook trigger; 8 nodes.
Source: https://gist.github.com/mervinyx/e7a394322f1bdfea587e590c39d532f7 — 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.
Who this is for
🧠 How it works This workflow lets users generate structured summaries from YouTube videos directly inside Slack using n8n, AssemblyAI, and OpenAI.
This n8n template automatically transcribes GoHighLevel (GHL) call recordings and creates an AI-generated summary that is added as a note directly to the related contact in your GHL CRM.
summarize_day. Uses googleCalendar, gmail, notion, httpRequest. Webhook trigger; 13 nodes.
A fully automated content engine that researches, writes, scores, and visualizes LinkedIn posts — built with n8n, OpenAI, Perplexity, and Replicate.