{ "id": "TApiWf05Monitor01", "name": "New-Upload Monitor → Transcript → Key Points → Slack (TranscriptAPI)", "nodes": [ { "parameters": { "rule": { "interval": [ { "field": "hours", "hoursInterval": 6 } ] } }, "id": "55555555-5555-4555-8555-555555555501", "name": "Every 6 Hours", "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.2, "position": [ -220, 0 ] }, { "parameters": { "assignments": { "assignments": [ { "id": "a5555555-5555-4555-8555-555555555aaa", "name": "channel", "value": "REPLACE_WITH_CHANNEL_HANDLE_OR_ID", "type": "string" } ] }, "options": {} }, "id": "55555555-5555-4555-8555-555555555502", "name": "Set Channel", "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [ 0, 0 ] }, { "parameters": { "url": "https://transcriptapi.com/api/v2/youtube/channel/latest", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendQuery": true, "queryParameters": { "parameters": [ { "name": "channel", "value": "={{ $json.channel }}" } ] }, "options": {} }, "id": "55555555-5555-4555-8555-555555555503", "name": "Get Latest Videos (TranscriptAPI)", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 220, 0 ], "credentials": { "httpHeaderAuth": { "id": "REPLACE_TRANSCRIPTAPI_CRED_ID", "name": "TranscriptAPI - Authorization Bearer" } } }, { "parameters": { "jsCode": "// channel/latest returns videos newest-first. Take the most recent upload and\n// flag whether it is \"new\" (published within the lookback window) so scheduled\n// re-runs don't re-digest the same video. Stateless — no storage required.\nconst LOOKBACK_HOURS = 24;\nconst data = $input.first().json;\nconst videos = data.results || [];\nif (videos.length === 0) { return []; }\nconst v = videos[0];\nconst publishedMs = v.published ? new Date(v.published).getTime() : 0;\nconst ageHours = (Date.now() - publishedMs) / 36e5;\nreturn [\n {\n json: {\n videoId: v.videoId,\n title: v.title || null,\n videoUrl: v.link || ('https://www.youtube.com/watch?v=' + v.videoId),\n published: v.published || null,\n channelTitle: (data.channel && data.channel.title) || null,\n ageHours: Math.round(ageHours * 10) / 10,\n isNewUpload: publishedMs > 0 && ageHours <= LOOKBACK_HOURS,\n },\n },\n];" }, "id": "55555555-5555-4555-8555-555555555504", "name": "Pick Newest Video", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 440, 0 ] }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" }, "conditions": [ { "id": "c5555555-5555-4555-8555-555555555ccc", "leftValue": "={{ $json.isNewUpload }}", "rightValue": true, "operator": { "type": "boolean", "operation": "true", "singleValue": true } } ], "combinator": "and" }, "options": {} }, "id": "55555555-5555-4555-8555-555555555505", "name": "Is New Upload?", "type": "n8n-nodes-base.filter", "typeVersion": 2, "position": [ 660, 0 ] }, { "parameters": { "url": "https://transcriptapi.com/api/v2/youtube/transcript", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendQuery": true, "queryParameters": { "parameters": [ { "name": "video_url", "value": "={{ $json.videoUrl }}" }, { "name": "format", "value": "json" } ] }, "options": {} }, "id": "55555555-5555-4555-8555-555555555506", "name": "Get Transcript (TranscriptAPI)", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 880, 0 ], "credentials": { "httpHeaderAuth": { "id": "REPLACE_TRANSCRIPTAPI_CRED_ID", "name": "TranscriptAPI - Authorization Bearer" } }, "onError": "continueRegularOutput" }, { "parameters": { "mode": "runOnceForEachItem", "jsCode": "// Join transcript segments and carry the video display fields forward.\nconst d = $json;\nconst transcriptText = (d.transcript || []).map((s) => s.text).join(' ');\nconst src = $('Pick Newest Video').item.json;\nreturn {\n json: {\n title: src.title,\n videoUrl: src.videoUrl,\n channelTitle: src.channelTitle,\n published: src.published,\n transcriptText,\n hasTranscript: transcriptText.length > 0,\n },\n};" }, "id": "55555555-5555-4555-8555-555555555507", "name": "Build Transcript Text", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1100, 0 ] }, { "parameters": { "method": "POST", "url": "https://api.openai.com/v1/chat/completions", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify({ model: 'gpt-4o-mini', messages: [ { role: 'system', content: 'You extract the 5-7 most important, concrete takeaways from a YouTube video transcript. Reply with short Markdown bullet points only, each starting with \"- \". No preamble.' }, { role: 'user', content: 'Video: ' + ($json.title || '') + '\\n\\nTranscript:\\n' + $json.transcriptText } ] }) }}", "options": {} }, "id": "55555555-5555-4555-8555-555555555508", "name": "Extract Key Points (LLM)", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 1320, 0 ], "credentials": { "httpHeaderAuth": { "id": "REPLACE_OPENAI_CRED_ID", "name": "OpenAI - Authorization Bearer" } } }, { "parameters": { "method": "POST", "url": "https://slack.com/api/chat.postMessage", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify({ channel: 'REPLACE_WITH_SLACK_CHANNEL_ID', text: '*🎬 New upload from ' + ($('Build Transcript Text').item.json.channelTitle || 'channel') + '*\\n*' + ($('Build Transcript Text').item.json.title || '') + '*\\n' + $('Build Transcript Text').item.json.videoUrl + '\\n\\n*Key points:*\\n' + $json.choices[0].message.content }) }}", "options": {} }, "id": "55555555-5555-4555-8555-555555555509", "name": "Send Slack Digest", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 1540, 0 ], "credentials": { "httpHeaderAuth": { "id": "REPLACE_SLACK_CRED_ID", "name": "Slack - Authorization Bearer" } } } ], "connections": { "Every 6 Hours": { "main": [ [ { "node": "Set Channel", "type": "main", "index": 0 } ] ] }, "Set Channel": { "main": [ [ { "node": "Get Latest Videos (TranscriptAPI)", "type": "main", "index": 0 } ] ] }, "Get Latest Videos (TranscriptAPI)": { "main": [ [ { "node": "Pick Newest Video", "type": "main", "index": 0 } ] ] }, "Pick Newest Video": { "main": [ [ { "node": "Is New Upload?", "type": "main", "index": 0 } ] ] }, "Is New Upload?": { "main": [ [ { "node": "Get Transcript (TranscriptAPI)", "type": "main", "index": 0 } ] ] }, "Get Transcript (TranscriptAPI)": { "main": [ [ { "node": "Build Transcript Text", "type": "main", "index": 0 } ] ] }, "Build Transcript Text": { "main": [ [ { "node": "Extract Key Points (LLM)", "type": "main", "index": 0 } ] ] }, "Extract Key Points (LLM)": { "main": [ [ { "node": "Send Slack Digest", "type": "main", "index": 0 } ] ] } }, "active": false, "settings": { "executionOrder": "v1" }, "pinData": {} }