This workflow corresponds to n8n.io template #9710 — we link there as the canonical source.
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 →
{
"id": "E7Npvta2ZCEtC6U7",
"name": "Transcribe and Summarize Podcast Episodes to X (Twitter) with Slack Approval",
"tags": [],
"nodes": [
{
"id": "ad312cb5-6f9a-44bd-bca6-595eccd6b466",
"name": "\u4ed8\u7b8b9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-720,
-288
],
"parameters": {
"width": 644,
"height": 640,
"content": "# Podcast Summary & Social Post with Human-in-the-Loop\n\nThis workflow automatically fetches the latest podcast episode, transcribes the audio, generates a summary using AI, and posts it to X (Twitter) after your approval in Slack.\n\n## How it works\n1. **Trigger:** The workflow runs on a schedule (e.g., daily) to fetch the latest episode from a Podcast RSS feed.\n2. **Process:** It handles large audio files by downloading them in chunks. It then transcribes the audio using OpenAI Whisper and generates a bullet-point summary using GPT-4o-mini.\n3. **Approval:** The drafted post is sent to Slack. The workflow pauses and waits for you to approve.\n4. **Action:** Once approved in Slack, the content is automatically posted to X (Twitter).\n\n## Setup steps\n1. **Configure RSS:** Open the node `[Step 1] RSS` and replace the URL with your target Podcast RSS feed.\n2. **Credentials:** Connect your OpenAI, Slack, and Twitter (X) credentials in the respective nodes.\n3. **Slack Setup:** In the node `[Step 12] Slack`, select the Channel ID where you want to receive the approval request.\n4. **Customize:** You can adjust the system prompt in `[Step 11] LLM` to change the tone or format of the summary."
},
"typeVersion": 1
},
{
"id": "e0655577-b632-4075-8720-de523c2d429a",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-48,
-128
],
"parameters": {
"color": 7,
"width": 1072,
"height": 384,
"content": "## RSS Fetch & Date Formatting"
},
"typeVersion": 1
},
{
"id": "33590a87-32cc-46dc-874b-56ec01b886b5",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1056,
-128
],
"parameters": {
"color": 7,
"width": 640,
"height": 384,
"content": "## Audio Chunking\nHandles large file downloads by splitting them into chunks."
},
"typeVersion": 1
},
{
"id": "9242f889-8bac-4285-a911-cb3097e9949a",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1712,
-128
],
"parameters": {
"color": 7,
"width": 1024,
"height": 384,
"content": "## Transcribe & Summarize (AI)\nUses Whisper for transcription and GPT-4o for summarization."
},
"typeVersion": 1
},
{
"id": "4d004742-6874-442f-9667-6396f58279f4",
"name": "[Step 0] Schedule \u2014 Daily 09:",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
16,
32
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 9
}
]
}
},
"typeVersion": 1.2
},
{
"id": "9a4b1f61-0446-4ea4-af42-7022469284d5",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2752,
-128
],
"parameters": {
"color": 7,
"width": 528,
"height": 384,
"content": "## Approval & Posting\nWait for Slack approval before posting to X."
},
"typeVersion": 1
},
{
"id": "4e445fa6-a33b-400d-a1f8-6264a5384036",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2448,
-112
],
"parameters": {
"color": 7,
"width": 288,
"height": 352,
"content": "## Prompt Customization\n\nYou can change the prompt language to match your podcast (e.g., Japanese, Spanish)."
},
"typeVersion": 1
},
{
"id": "a22f2cbd-ae46-4936-86cb-81cf2555b1bf",
"name": "[Step 11] LLM \u2014 Summarize as News Bullets",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
2480,
32
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"messages": {
"values": [
{
"content": "=You are an expert copywriter. Please summarize the podcast transcript below, strictly following the summary rules. Output in the specified format.\n\n# Podcast Transcript\n{{ $json.fullText }}\n\n# Summary Rules\n1. Summarize each news item in 1-2 concise sentences.\n2. Include key facts (dates, places, people, numbers).\n3. Prioritize news based on its importance in the episode.\n4. Exclude intros, weather forecasts, and ads.\n5. Format today's date as \"YYYY-MM-DD\".\n\n# Output Format\n{{ $json.date }} Podcast Summary\ud83d\udc47\n\n- Content 1 \n- Content 2\n- Content 3 "
}
]
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.8
},
{
"id": "4a0b4604-15fa-4f5f-ab1a-9d5297be36a4",
"name": "[Step 12] Slack \u2014 Review & Approve",
"type": "n8n-nodes-base.slack",
"position": [
2832,
32
],
"parameters": {
"select": "channel",
"message": "=The podcast summary is ready. Here is the drafted tweet content:\n\n---\n\n{{ $json.message.content }}",
"options": {},
"channelId": {
"__rl": true,
"mode": "name",
"value": "#example"
},
"operation": "sendAndWait"
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "7abdbb60-1889-4ae8-940f-a8ac8465d0de",
"name": "[Step 13] X (Twitter) \u2014 Post Tweet",
"type": "n8n-nodes-base.twitter",
"position": [
3056,
32
],
"parameters": {
"text": "={{ $('[Step 11] LLM \u2014 Summarize as News Bullets').item.json.message.content }}",
"additionalFields": {}
},
"credentials": {
"twitterOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "0b26a5a8-28a8-4e73-ba7e-954b2444c108",
"name": "[Step 10] Text \u2014 Merge Transcript & Pass Date",
"type": "n8n-nodes-base.code",
"position": [
2256,
32
],
"parameters": {
"jsCode": "// Sort by part number if available\nitems.sort((a, b) => (a.json.part || 0) - (b.json.part || 0));\n\n// Join transcript texts with newlines\nconst fullText = items.map(item => item.json.text).join(\"\\n\");\nconst date = $('[Step 4] Item \u2014 Select Enclosure URL & Date').first().json.date;\n\nreturn [{ json: { fullText, date } }];"
},
"typeVersion": 2
},
{
"id": "d7c60c9a-6bf6-4eec-8c71-8b1f76a6cd26",
"name": "[Step 9] Text \u2014 Attach Part Number",
"type": "n8n-nodes-base.set",
"position": [
2032,
32
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "5e8e0908-df6a-404f-bf9b-38170c7a2f3a",
"name": "text",
"type": "string",
"value": "={{ $json.text }}"
},
{
"id": "b56e6282-4b36-48d9-af4c-aef6d5c201dd",
"name": "part",
"type": "number",
"value": "={{ $('[Step 6] Chunk \u2014 Plan Byte Ranges').item.json.part }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "9a0fd855-8305-43da-b633-8468436ba500",
"name": "[Step 8] Speech-to-Text \u2014 Transcribe Chunks",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1808,
32
],
"parameters": {
"options": {},
"resource": "audio",
"operation": "transcribe"
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.8
},
{
"id": "ab38e80b-96ec-4416-916d-038b09398797",
"name": "[Step 7] HTTP \u2014 Download Chunk",
"type": "n8n-nodes-base.httpRequest",
"position": [
1584,
32
],
"parameters": {
"url": "={{ $('[Step 4] Item \u2014 Select Enclosure URL & Date').item.json.enclosure.url }}",
"options": {
"timeout": 30000,
"redirect": {
"redirect": {
"maxRedirects": 10
}
},
"response": {
"response": {
"responseFormat": "file"
}
}
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "Mozilla/5.0"
},
{
"name": "Accept",
"value": "audio/mpeg"
},
{
"name": "Connection",
"value": "close"
},
{
"name": "Range",
"value": "={{ $json.end !== '' && $json.end !== null && $json.end !== undefined ? 'bytes=' + $json.start + '-' + $json.end : 'bytes=' + $json.start + '-' }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "6e506503-d297-43f6-b072-f8fd2c6e75e4",
"name": "[Step 6] Chunk \u2014 Plan Byte Ranges",
"type": "n8n-nodes-base.code",
"position": [
1360,
32
],
"parameters": {
"jsCode": "const url = $('[Step 4] Item \u2014 Select Enclosure URL & Date').first().json.enclosure.url; // \u2190 Always present\nconst cr = $json.headers?.['content-range'];\n\nif (!cr) throw new Error('No content-range header found. Check if \"Return Full Response\" is ON in the HTTP(0-0) node or if the status is 206.');\n\nconst total = Number(cr.split('/')[1]);\nconst CHUNK = 24 * 1024 * 1024; // 24MB chunks\nconst out = [];\nlet start = 0, part = 1;\n\nwhile (start < total) {\n const end = Math.min(start + CHUNK - 1, total - 1);\n out.push({ json: { url, part, start, end } });\n start = end + 1; part++;\n}\nreturn out;"
},
"typeVersion": 2
},
{
"id": "f864aaf4-a53b-467b-98e4-f483d47f5d0d",
"name": "[Step 5] HTTP \u2014 Probe Content-Range (0\u20130)",
"type": "n8n-nodes-base.httpRequest",
"position": [
1136,
32
],
"parameters": {
"url": "={{ $json.enclosure.url }}",
"options": {
"timeout": 30000,
"redirect": {
"redirect": {
"maxRedirects": 10
}
},
"response": {
"response": {
"fullResponse": true,
"responseFormat": "text"
}
}
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Range",
"value": "=bytes=0-0"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "0db83e42-83c7-44da-89a9-79ddbba85f45",
"name": "[Step 4] Item \u2014 Select Enclosure URL & Date",
"type": "n8n-nodes-base.set",
"position": [
912,
32
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "28b25795-0f2a-4bcf-bf31-b4e6242ecabe",
"name": "enclosure.url",
"type": "string",
"value": "={{ $('[Step 2] RSS \u2014 Take Latest Item').item.json.enclosure.url }}"
},
{
"id": "bd3f2f40-2868-47ca-8874-ab18943025ab",
"name": "date",
"type": "string",
"value": "={{ $json.formatted }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "5367e60e-b3e6-4165-9254-248783aec81b",
"name": "[Step 3] Date \u2014 Format as YYYY-MM-DD",
"type": "n8n-nodes-base.code",
"position": [
688,
32
],
"parameters": {
"jsCode": "// Get the date string from the RSS node\nconst dateStr = $('[Step 1] RSS \u2014 Fetch Feed').first().json.pubDate; \n\n// Convert to Date object\nconst date = new Date(dateStr);\n\n// Get year, month, and day\nconst year = date.getFullYear();\nconst month = date.getMonth() + 1; // Month is 0-indexed\nconst day = date.getDate();\n\n// Return formatted string (YYYY-MM-DD)\nreturn [\n { json: {\n original: dateStr,\n formatted: `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "da3005f1-35b0-4e57-a8ea-19b10ff514e7",
"name": "[Step 2] RSS \u2014 Take Latest Item",
"type": "n8n-nodes-base.limit",
"position": [
464,
32
],
"parameters": {},
"typeVersion": 1
},
{
"id": "1bf40255-13f7-45e7-8e4a-9e848f893a31",
"name": "[Step 1] RSS \u2014 Fetch Feed",
"type": "n8n-nodes-base.rssFeedRead",
"position": [
240,
32
],
"parameters": {
"url": "https://feeds.feedburner.com/tedtalks_audio",
"options": {}
},
"typeVersion": 1.2
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "68e862cf-1513-4a35-83eb-cb419c8c773d",
"connections": {
"[Step 1] RSS \u2014 Fetch Feed": {
"main": [
[
{
"node": "[Step 2] RSS \u2014 Take Latest Item",
"type": "main",
"index": 0
}
]
]
},
"[Step 0] Schedule \u2014 Daily 09:": {
"main": [
[
{
"node": "[Step 1] RSS \u2014 Fetch Feed",
"type": "main",
"index": 0
}
]
]
},
"[Step 7] HTTP \u2014 Download Chunk": {
"main": [
[
{
"node": "[Step 8] Speech-to-Text \u2014 Transcribe Chunks",
"type": "main",
"index": 0
}
]
]
},
"[Step 2] RSS \u2014 Take Latest Item": {
"main": [
[
{
"node": "[Step 3] Date \u2014 Format as YYYY-MM-DD",
"type": "main",
"index": 0
}
]
]
},
"[Step 6] Chunk \u2014 Plan Byte Ranges": {
"main": [
[
{
"node": "[Step 7] HTTP \u2014 Download Chunk",
"type": "main",
"index": 0
}
]
]
},
"[Step 12] Slack \u2014 Review & Approve": {
"main": [
[
{
"node": "[Step 13] X (Twitter) \u2014 Post Tweet",
"type": "main",
"index": 0
}
]
]
},
"[Step 9] Text \u2014 Attach Part Number": {
"main": [
[
{
"node": "[Step 10] Text \u2014 Merge Transcript & Pass Date",
"type": "main",
"index": 0
}
]
]
},
"[Step 3] Date \u2014 Format as YYYY-MM-DD": {
"main": [
[
{
"node": "[Step 4] Item \u2014 Select Enclosure URL & Date",
"type": "main",
"index": 0
}
]
]
},
"[Step 11] LLM \u2014 Summarize as News Bullets": {
"main": [
[
{
"node": "[Step 12] Slack \u2014 Review & Approve",
"type": "main",
"index": 0
}
]
]
},
"[Step 4] Item \u2014 Select Enclosure URL & Date": {
"main": [
[
{
"node": "[Step 5] HTTP \u2014 Probe Content-Range (0\u20130)",
"type": "main",
"index": 0
}
]
]
},
"[Step 5] HTTP \u2014 Probe Content-Range (0\u20130)": {
"main": [
[
{
"node": "[Step 6] Chunk \u2014 Plan Byte Ranges",
"type": "main",
"index": 0
}
]
]
},
"[Step 8] Speech-to-Text \u2014 Transcribe Chunks": {
"main": [
[
{
"node": "[Step 9] Text \u2014 Attach Part Number",
"type": "main",
"index": 0
}
]
]
},
"[Step 10] Text \u2014 Merge Transcript & Pass Date": {
"main": [
[
{
"node": "[Step 11] LLM \u2014 Summarize as News Bullets",
"type": "main",
"index": 0
}
]
]
}
}
}
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.
openAiApislackApitwitterOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Turn your favorite podcast episodes into engaging social media content automatically. This workflow fetches new episodes from an RSS feed, transcribes the audio using OpenAI Whisper, generates a concise summary using GPT-4o, and drafts a tweet. It then sends the draft to Slack…
Source: https://n8n.io/workflows/9710/ — 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 n8n workflow collects and summarizes news from multiple RSS feeds, using OpenAI to generate a concise summary that can be sent to WhatsApp or other destinations. Perfect for automating your daily
This n8n template automates the process of curating and sharing the latest cryptocurrency news on X (formerly Twitter) and Telegram. By leveraging AI for content summarization, this workflow allows yo
Stay on top of your competition with this powerful n8n workflow that automatically fetches and summarizes your competitors’ latest tweets every day. Using the official X (formerly Twitter) API and Ope
This workflow is designed for Japanese-speaking professionals, and learners who want to efficiently stay up to date with practical productivity, lifehack, and efficiency-related insights from Japanese
This fully automated AI Twin Viral News system researches the latest trending news in any niche or industry, then generates talking-head AI clone videos WITHOUT having to film or edit yourself. This c