This workflow corresponds to n8n.io template #12020 — we link there as the canonical source.
This workflow follows the Airtable → Google Drive 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": "2mr8qIqiLpfxnTWp",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Automated Podcast Generation with n8n, OpenAI & Buzzsprout",
"tags": [],
"nodes": [
{
"id": "b4b92921-b2e3-4101-a647-573ac8053c02",
"name": "Trigger: New Audio File",
"type": "n8n-nodes-base.googleDriveTrigger",
"position": [
-64,
0
],
"parameters": {
"event": "fileCreated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "list",
"value": "1vuilPY22rcrwtfC-yPV0yu4FHeIQmJZD",
"cachedResultUrl": "",
"cachedResultName": "n8n"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "754399d9-c86a-4dff-8362-715ecd7a7662",
"name": "Download Raw Audio",
"type": "n8n-nodes-base.googleDrive",
"position": [
144,
0
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "url",
"value": "={{ $json.webViewLink }}"
},
"options": {},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "6bba3052-1bd7-4f4e-b3ef-accfe9b1b147",
"name": "AI Transcription",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
448,
0
],
"parameters": {
"options": {},
"resource": "audio",
"operation": "transcribe"
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "878e20b8-4e75-47b9-86e9-e708319c0357",
"name": "AI Transcript Cleaning & QA",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
624,
0
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "GPT-4O"
},
"options": {},
"responses": {
"values": [
{
"role": "system",
"content": "=You are a professional podcast editor and transcription QA expert.\n\nClean and enhance the following transcript according to these rules:\n\n- Remove filler words: \"um\", \"uh\", \"like\", \"you know\", \"so yeah\" etc.\n- Fix grammar, punctuation, and casing.\n- Add speaker labels where appropriate.\n- Keep meaning intact.\n- Provide a 2-sentence summary.\n- Provide 3\u20134 bullet key takeaways.\n- Then provide the full cleaned transcript.\n- Your ENTIRE reply must be ONLY valid JSON. No code block. No explanations. No markdown. No backticks."
},
{
"content": "={{ $json.text }}"
}
]
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "1b8c1b9c-1b04-42ab-a127-a2212ebfa246",
"name": "Parse Cleaned Transcript JSON",
"type": "n8n-nodes-base.code",
"position": [
944,
0
],
"parameters": {
"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nreturn [\n {\n json: JSON.parse($json.output[0].content[0].text)\n }\n];"
},
"typeVersion": 2
},
{
"id": "7363897f-2230-413d-aea3-a64fc967d3ba",
"name": "AI Episode Metadata Generator",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1248,
0
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "GPT-4O"
},
"options": {},
"responses": {
"values": [
{
"role": "system",
"content": "You are a professional content writer experienced in podcast SEO. Using the provided summary and transcript, produce the following:\n\n1. episode_title \u2014 catchy, SEO-friendly, one line\n2. episode_description \u2014 2-3 short paragraphs, SEO optimized, up to 300 words\n3. show_notes \u2014 detailed, 400-800 words, suitable for a blog post\n4. episode_tags \u2014 list of relevant keywords as an array\n5. suggested_publish_date \u2014 ISO 8601 date or \"publish now\"\n\nReturn ONLY valid JSON with exactly these keys. No explanations, no markdown, no code blocks."
},
{
"content": "={\n \"summary\": \"{{ $json['summary'] }}\",\n \"transcript speaker1\": \"{{ $json.transcript['Speaker 1'] }}\",\n\"transcript speaker 2\":\"{{ $json.transcript[\"Speaker 2\"] }}\",\n \"key_takeaways\": \"{{ $json.key_takeaways }}\"\n}"
}
]
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "c9948758-a191-477e-89f0-7878caba8f4b",
"name": "Parse Episode Metadata JSON",
"type": "n8n-nodes-base.code",
"position": [
1568,
0
],
"parameters": {
"jsCode": "const items = $input.all();\nconst out = [];\n\nfor (const item of items) {\n // raw text from OpenAI\n const raw = item.json.output?.[0]?.content?.[0]?.text || \"\";\n\n // remove code fences\n const cleaned = raw.replace(/```json|```/g, \"\").trim();\n\n let parsed = {};\n try {\n parsed = JSON.parse(cleaned);\n } catch (e) {\n parsed = { error: \"JSON parse failed\", raw };\n }\n\n out.push({\n json: {\n episode_title: parsed.episode_title || null,\n episode_description: parsed.episode_description || null,\n show_notes: parsed.show_notes || null,\n episode_tags: parsed.episode_tags || [],\n suggested_publish_date: parsed.suggested_publish_date || null,\n full_parsed: parsed\n }\n });\n}\n\nreturn out;\n"
},
"typeVersion": 2
},
{
"id": "6c967b0f-adfa-4e13-b28e-9e3720333e2c",
"name": "AI Blog Article Generator",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1872,
0
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "GPT-4O"
},
"options": {},
"responses": {
"values": [
{
"content": "=You are an expert podcast content writer. Convert the following show notes into a full-length blog article.\n\nRequirements:\n- Format in clean Markdown\n- 700\u20131000 words\n- Use H2 and H3 headings\n- Add an author byline at the top (e.g., \"Written by the Daily Focus Team\")\n- Add a short SEO meta description (max 150 characters)\n- Expand concepts where useful\n- If timestamps exist, integrate them naturally. If none are present, ignore timestamps.\n- Keep tone professional, clear, and helpful.\n\nShowNotes:\n{{ $json.show_notes }}\n\nRespond ONLY with valid JSON:\n\n{\n \"blog_draft_markdown\": \"...\"\n}\n"
}
]
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "2861376e-f24f-4bd5-a110-8804f27687e2",
"name": "Parse Blog Article JSON",
"type": "n8n-nodes-base.code",
"position": [
2192,
0
],
"parameters": {
"jsCode": "// Get raw text returned by OpenAI\nconst raw = $json.output[0].content[0].text;\n\n// Remove ```json code fencing\nconst cleaned = raw\n .replace(/```json/g, '')\n .replace(/```/g, '')\n .trim();\n\n// Parse JSON safely\nlet parsed;\ntry {\n parsed = JSON.parse(cleaned);\n} catch (err) {\n throw new Error(\"Failed to parse JSON from AI output: \" + err.message);\n}\n\n// Get data coming from previous node (your JavaScript1 output)\nconst previousData = $items(\"Parse Episode Metadata JSON\")[0].json;\n\n// Create tags as a comma-separated string\nconst episodeTagsString = Array.isArray(previousData.episode_tags)\n ? previousData.episode_tags.join(\", \")\n : \"\";\n\n// Merge both results\nreturn [\n {\n json: {\n ...previousData, // all episode_* fields\n blog_draft_markdown: parsed.blog_draft_markdown,\n episode_tags_string: episodeTagsString\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "078a5e8b-58af-4dda-8a27-a06d3a2da64e",
"name": "Create Episode Draft Record",
"type": "n8n-nodes-base.airtable",
"position": [
2544,
0
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "appipUxLpxPEKRXrJ",
"cachedResultUrl": "",
"cachedResultName": "Fake Review Detector"
},
"table": {
"__rl": true,
"mode": "list",
"value": "tbln0KraNZGYXyHQc",
"cachedResultUrl": "",
"cachedResultName": "podcastData"
},
"columns": {
"value": {
"show_notes": "={{ $json.show_notes }}",
"episode_tags": "={{ $json.episode_tags_string }}",
"episode_title": "={{ $json.episode_title }}",
"blog_draft_markdown": "={{ $json.blog_draft_markdown }}",
"episode_description": "={{ $json.episode_description }}",
"suggested_publish_date": "={{ $json.suggested_publish_date }}"
},
"schema": [
{
"id": "episode_title",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "episode_title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "episode_description",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "episode_description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "show_notes",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "show_notes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "episode_tags",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "episode_tags",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "suggested_publish_date",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "suggested_publish_date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "blog_draft_markdown",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "blog_draft_markdown",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "create"
},
"credentials": {
"airtableTokenApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "e0cf1adc-63a6-4d0c-93f5-69686782053a",
"name": "AI Social Media Content Generator",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
2944,
0
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "GPT-4O"
},
"options": {},
"responses": {
"values": [
{
"content": "=You are an expert social media content repurposer. Convert the following blog article into 4 social post formats.\n\nOUTPUT STRICTLY AS A JSON OBJECT WITH THESE KEYS ONLY:\n- linkedin (long-form post up to 300 words)\n- twitter_thread (an array of exactly 5 tweets)\n- instagram_caption (short caption + include 5 hashtags)\n- tiktok_script (1\u20132 line short punchy description)\n\nNo backticks. No Markdown. Only return a JSON object and please dont add emojis.\n\nContent to repurpose:\n{{ $json.fields.blog_draft_markdown }}"
}
]
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "1a1cf90c-c67c-43c1-a6bc-10814cf4bcc8",
"name": "Parse Social Content",
"type": "n8n-nodes-base.code",
"position": [
3232,
0
],
"parameters": {
"jsCode": "// 1. Get the raw text returned by OpenAI\nconst raw = $json.output[0].content[0].text;\n\n// 2. Remove accidental JSON code fencing (if OpenAI adds any)\nconst cleaned = raw\n .replace(/```json/g, '')\n .replace(/```/g, '')\n .trim();\n\n// 3. Parse JSON safely\nlet parsed;\ntry {\n parsed = JSON.parse(cleaned);\n} catch (err) {\n throw new Error(\"Failed to parse OpenAI JSON: \" + err.message + \"\\nRaw: \" + cleaned);\n}\n\n// 4. Get previous merged data\nconst previousData = $items(\"Parse Blog Article JSON\")[0].json;\nconst record_id = $items(\"Create Episode Draft Record\")[0].json;\n\n// 5. Merge everything together and return it\nreturn [\n {\n json: {\n ...previousData,\n\n // AI social content fields\n linkedin_post: parsed.linkedin,\n twitter_thread: parsed.twitter_thread,\n instagram_caption: parsed.instagram_caption,\n tiktok_script: parsed.tiktok_script,\n record_id_data: record_id.fields.record_Id,\n\n // Convert arrays to Airtable-friendly strings\n episode_tags_string: previousData.episode_tags ? previousData.episode_tags.join(\", \") : \"\",\n twitter_thread_string: parsed.twitter_thread ? parsed.twitter_thread.join(\"\\n\\n\") : \"\"\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "28debbfe-8904-466f-9b79-0b455f2740e4",
"name": "Update Social Content",
"type": "n8n-nodes-base.airtable",
"position": [
3408,
0
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "appipUxLpxPEKRXrJ",
"cachedResultUrl": "",
"cachedResultName": "Fake Review Detector"
},
"table": {
"__rl": true,
"mode": "list",
"value": "tbln0KraNZGYXyHQc",
"cachedResultUrl": "",
"cachedResultName": "podcastData"
},
"columns": {
"value": {
"record_Id": "={{ $json.record_id_data }}",
"linkedin_post": "={{ $json.linkedin_post }}",
"tiktok_script": "={{ $json.tiktok_script }}",
"twitter_thread": "={{ $json.twitter_thread_string }}",
"instagram_caption": "={{ $json.instagram_caption }}"
},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "id",
"defaultMatch": true
},
{
"id": "episode_title",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "episode_title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "record_Id",
"type": "string",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "record_Id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "episode_description",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "episode_description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "show_notes",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "show_notes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "episode_tags",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "episode_tags",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "suggested_publish_date",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "suggested_publish_date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "blog_draft_markdown",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "blog_draft_markdown",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "linkedin_post",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "linkedin_post",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "instagram_caption",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "instagram_caption",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "twitter_thread",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "twitter_thread",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "tiktok_script",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "tiktok_script",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"record_Id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update"
},
"credentials": {
"airtableTokenApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "2f77298a-069b-4889-a770-90438aa94ffd",
"name": "Save Thumbnail URL",
"type": "n8n-nodes-base.airtable",
"position": [
3920,
0
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "appipUxLpxPEKRXrJ",
"cachedResultUrl": "",
"cachedResultName": "Fake Review Detector"
},
"table": {
"__rl": true,
"mode": "list",
"value": "tbln0KraNZGYXyHQc",
"cachedResultUrl": "",
"cachedResultName": "podcastData"
},
"columns": {
"value": {
"record_Id": "={{ $('Update Social Content').item.json.fields.record_Id }}",
"youtube_thumbnail_url": "={{ $json.url }}"
},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "id",
"defaultMatch": true
},
{
"id": "episode_title",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "episode_title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "record_Id",
"type": "string",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "record_Id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "episode_description",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "episode_description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "show_notes",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "show_notes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "episode_tags",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "episode_tags",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "suggested_publish_date",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "suggested_publish_date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "blog_draft_markdown",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "blog_draft_markdown",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "linkedin_post",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "linkedin_post",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "instagram_caption",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "instagram_caption",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "twitter_thread",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "twitter_thread",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "tiktok_script",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "tiktok_script",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "youtube_thumbnail_url",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "youtube_thumbnail_url",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"record_Id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update"
},
"credentials": {
"airtableTokenApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "36dbd273-2859-47ed-a4eb-6456c4bdcdd5",
"name": "AI Thumbnail Generator (YouTube Image)",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
3728,
0
],
"parameters": {
"model": "dall-e-2",
"prompt": "=Create a clean, bold YouTube thumbnail in 1280x720 resolution for a podcast episode titled \"{{ $json.fields.episode_title }}\".\nVisual Concept: Modern, minimal layout with bold typography. Add headline text \"{{ $json.fields.episode_title }}\".\nColor palette: high contrast, eye-catching, but clean (no clutter).\nLeave space for host/guest photos and podcast logo.\nStyle: professional YouTube thumbnail, crisp, well-lit, high-quality graphics.\nOutput must be PNG.\n",
"options": {
"size": "1024x1024",
"returnImageUrls": true
},
"resource": "image"
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "f478c01b-ee51-4ec0-b950-8b30e3c637c2",
"name": "Prepare Buzzsprout Episode Payload",
"type": "n8n-nodes-base.set",
"position": [
4224,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "19d1e185-b537-4b48-b082-3e6617f22e45",
"name": "episode_title",
"type": "string",
"value": "={{ $json.fields.episode_title }}"
},
{
"id": "3c6f9199-6b76-45d8-9a19-643ec9a2cda9",
"name": "final_description",
"type": "string",
"value": "={{ $json.fields.episode_description + \"\\n\\nThumbnail: \" + $json.fields.youtube_thumbnail_url }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "197f144d-2056-420e-922b-3c20ebcaa5e6",
"name": "Download Audio for Buzzsprout Upload",
"type": "n8n-nodes-base.googleDrive",
"position": [
4400,
0
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "url",
"value": "={{ $('Trigger: New Audio File').item.json.webViewLink }}"
},
"options": {},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "43c03363-ae11-4ed8-bd27-7986c72fc609",
"name": "Upload Episode",
"type": "n8n-nodes-base.httpRequest",
"position": [
4720,
0
],
"parameters": {
"url": "https://www.buzzsprout.com/api/{your_podcast_id}/episodes.json",
"method": "POST",
"options": {
"redirect": {
"redirect": {}
}
},
"sendBody": true,
"contentType": "multipart-form-data",
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "title",
"value": "={{ $('Prepare Buzzsprout Episode Payload').item.json.episode_title }}"
},
{
"name": "description",
"value": "={{ $('Prepare Buzzsprout Episode Payload').item.json.final_description }}"
},
{
"name": "file",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Token token={you_api_key}"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "9ad58455-db56-4bdc-881f-789bd3d050f2",
"name": "Save Buzzsprout Episode Data",
"type": "n8n-nodes-base.airtable",
"position": [
4912,
0
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "appipUxLpxPEKRXrJ",
"cachedResultUrl": "",
"cachedResultName": "Fake Review Detector"
},
"table": {
"__rl": true,
"mode": "list",
"value": "tbln0KraNZGYXyHQc",
"cachedResultUrl": "",
"cachedResultName": "podcastData"
},
"columns": {
"value": {
"guid": "={{ $json.guid }}",
"audio_url": "={{ $json.audio_url }}",
"record_Id": "={{ $('Save Thumbnail URL').item.json.fields.record_Id }}",
"published_at": "={{ $json.published_at }}",
"buzzsprout_episode_id": "={{ $json.id }}"
},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "id",
"defaultMatch": true
},
{
"id": "episode_title",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "episode_title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "record_Id",
"type": "string",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "record_Id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "episode_description",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "episode_description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "show_notes",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "show_notes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "episode_tags",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "episode_tags",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "suggested_publish_date",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "suggested_publish_date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "blog_draft_markdown",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "blog_draft_markdown",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "linkedin_post",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "linkedin_post",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "instagram_caption",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "instagram_caption",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "twitter_thread",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "twitter_thread",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "tiktok_script",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "tiktok_script",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "youtube_thumbnail_url",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "youtube_thumbnail_url",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "buzzsprout_episode_id",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "buzzsprout_episode_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "audio_url",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "audio_url",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "published_at",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "published_at",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "guid",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "guid",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"record_Id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update"
},
"credentials": {
"airtableTokenApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "3700490b-d7dd-4bd6-b489-c3bb85a31d26",
"name": "Notify Marketing Team",
"type": "n8n-nodes-base.slack",
"position": [
5456,
0
],
"parameters": {
"text": "=\ud83c\udf99\ufe0f *New Podcast Episode Successfully Uploaded to Buzzsprout!*\n\nHere are the key details from the latest automated upload \ud83d\udc47\n\n*Episode Title:* \n{{ $json[\"Episode Title\"] }}\n\n*Buzzsprout Episode ID:* \n{{ $json[\"Buzzsprout episode Id\"] }}\n\n*Published At:* \n{{ $json[\"Published at\"] }}\n\n*Thumbnail (YouTube-ready):* \n{{ $json[\"Youtube thumbnail url\"] }}\n\n---\n\nThe episode has been successfully created in Buzzsprout. \nKindly review the content, update show notes if needed, and proceed with the promotional tasks.\n\nIf you need more assets (captions, social posts, transcript, etc.), let me know!\n",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "n8n"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "330f72c0-fcca-4990-a6d0-279c35823e1e",
"name": "Prepare Slack Message",
"type": "n8n-nodes-base.set",
"position": [
5232,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "4c145549-7ffa-44e2-b4a4-a4e46d35a8e8",
"name": "Episode Title",
"type": "string",
"value": "={{ $json.fields.episode_title }}"
},
{
"id": "248a62dd-1637-44ca-9999-4ccda26363f9",
"name": "Buzzsprout episode Id",
"type": "number",
"value": "={{ $json.fields.buzzsprout_episode_id }}"
},
{
"id": "42e6eefb-3af3-4b22-8847-6afd3930dae5",
"name": "Published at",
"type": "string",
"value": "={{ $json.fields.published_at }}"
},
{
"id": "ce8c4db1-022e-40e3-b200-d3c6dac8cbf9",
"name": "Youtube thumbnail url",
"type": "string",
"value": "={{ $json.fields.youtube_thumbnail_url }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "03dc2187-c88b-4587-99fa-521cd2ab8473",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
384,
-160
],
"parameters": {
"color": 7,
"width": 720,
"height": 336,
"content": "## Transcription & Transcript Cleanup\nThe raw audio is transcribed using AI, then cleaned to remove filler words, fix formatting, and produce a structured transcript. The JSON parsing prepares the cleaned transcript for the next steps like episode title generation and notes creation."
},
"typeVersion": 1
},
{
"id": "cfae219b-a156-47b8-979d-d2da935652ba",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-112,
-160
],
"parameters": {
"color": 7,
"width": 416,
"height": 352,
"content": "## Audio Intake & Preparation\nAutomatically detects when a new audio file is added to Google Drive and downloads it for processing. This begins the podcast workflow by pulling in the raw audio that will later be transcribed and converted into content."
},
"typeVersion": 1
},
{
"id": "3467527e-23aa-4bbf-a79f-774d088d10fc",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1216,
-160
],
"parameters": {
"color": 7,
"width": 512,
"height": 336,
"content": "## Episode Metadata Generation\nUses the cleaned transcript to generate high-quality metadata \u2014 title, description, show notes, tags, and publish date. Then parses the AI response into clean fields for use in Airtable, Buzzsprout, and social media generation."
},
"typeVersion": 1
},
{
"id": "edfa1e0c-3fbd-492e-80e0-56cc32f0ad4f",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1840,
-160
],
"parameters": {
"color": 7,
"width": 496,
"height": 336,
"content": "## Blog Article Creation\nTransforms the show notes into a polished blog post draft in Markdown format. This creates long-form written content that can be published on blogs, websites, or newsletters."
},
"typeVersion": 1
},
{
"id": "b8af3d27-d58f-400b-b6ff-daf148b0c650",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2400,
-160
],
"parameters": {
"color": 7,
"width": 432,
"height": 336,
"content": "## Store Initial Episode Data in Airtable\nStores the transcript, title, initial notes, tags, and other metadata into Airtable. This creates the first version of the episode record before thumbnails, social posts, and Buzzsprout links are added."
},
"typeVersion": 1
},
{
"id": "b05ac981-0028-4307-a2bf-34ca19d87205",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2928,
-160
],
"parameters": {
"color": 7,
"width": 672,
"height": 336,
"content": "## Social Content Generation\nCreates LinkedIn, Twitter thread, Instagram caption, and TikTok script. Merges the content with previous data and updates the Airtable record with all social-ready text."
},
"typeVersion": 1
},
{
"id": "6b42754f-545d-4f65-a222-445ce8d403e6",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
3664,
-160
],
"parameters": {
"color": 7,
"width": 432,
"height": 336,
"content": "## Thumbnail Generation\nGenerates a custom thumbnail for the episode using AI. Saves the image URL into Airtable so it\u2019s available for marketing and Buzzsprout descriptions."
},
"typeVersion": 1
},
{
"id": "b34b94ee-78fe-461b-8292-666462752e69",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
4176,
-144
],
"parameters": {
"color": 7,
"width": 400,
"height": 320,
"content": "## Prepare Episode for Buzzsprout\nPrepares the final formatted text for publishing, including cleaned description and thumbnail link. Also retrieves the original audio file again to attach to Buzzsprout."
},
"typeVersion": 1
},
{
"id": "7caf00d6-72aa-4abc-b36f-db4b919c8589",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
4656,
-144
],
"parameters": {
"color": 7,
"width": 448,
"height": 320,
"content": "## Publish Episode on Buzzsprout\nUploads the episode with audio, title, and description to Buzzsprout. After Buzzsprout returns the episode URL and ID, these details are stored back in Airtable to keep the episode record complete."
},
"typeVersion": 1
},
{
"id": "ac8a0fb6-c61b-46e4-b6a6-519798ef15fe",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
5168,
-144
],
"parameters": {
"color": 7,
"width": 528,
"height": 320,
"content": "## Notify Team\nSends a structured message to your marketing team with episode title, publish link, thumbnail, and schedule details so they can begin promotion instantly."
},
"typeVersion": 1
},
{
"id": "474420fc-f7c3-443f-8ce5-4d86c0b3916e",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
-816,
-1152
],
"parameters": {
"width": 544,
"height": 1152,
"content": "# How It Works\n### This workflow automatically converts a raw audio recording into a fully published podcast episode. Once an audio file arrives, the workflow extracts the transcript, generates the episode title, description, show notes, tags, and marketing content using AI. It then creates a record in Airtable to store all episode data, generates a YouTube-style thumbnail image, and uploads the final audio to Buzzsprout. After Buzzsprout returns the episode link and publish details, the workflow stores everything back in Airtable for tracking. Finally, it notifies your team on Slack with a summary and publish link. This makes the entire production process fully automated from audio input to podcast publication.\n\n# Setup Steps\n## Prepare Airtable\nCreate an Episode table with fields for title, description, tags, thumbnail URL, Buzzsprout ID, publish date, and all AI-generated content.\n\n## Connect Accounts in n8n\nAdd credentials for OpenAI, Airtable, Slack, and Buzzsprout (API token + podcast ID).\n\n## Add Trigger\nStart with an audio file upload trigger (Webhook or Google Drive trigger).\n\n## Add Transcript & AI Generation Nodes\nUse OpenAI Whisper for transcription and GPT for episode content, show notes, and marketing posts.\n\n## Save to Airtable\nCreate or update the episode record with all generated data.\n\n## Generate Thumbnail\nUse OpenAI Image API and store the image URL in Airtable.\n\n## Upload to Buzzsprout\nSend the audio file, title, and description to Buzzsprout via HTTP Request.\n\n## Send Slack Notification\nNotify your marketing team with episode details and links."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "991123e0-6db8-441b-b9b9-e003bc60e081",
"connections": {
"Upload Episode": {
"main": [
[
{
"node": "Save Buzzsprout Episode Data",
"type": "main",
"index": 0
}
]
]
},
"AI Transcription": {
"main": [
[
{
"node": "AI Transcript Cleaning & QA",
"type": "main",
"index": 0
}
]
]
},
"Download Raw Audio": {
"main": [
[
{
"node": "AI Transcription",
"type": "main",
"index": 0
}
]
]
},
"Save Thumbnail URL": {
"main": [
[
{
"node": "Prepare Buzzsprout Episode Payload",
"type": "main",
"index": 0
}
]
]
},
"Parse Social Content": {
"main": [
[
{
"node": "Update Social Content",
"type": "main",
"index": 0
}
]
]
},
"Prepare Slack Message": {
"main": [
[
{
"node": "Notify Marketing Team",
"type": "main",
"index": 0
}
]
]
},
"Update Social Content": {
"main": [
[
{
"node": "AI Thumbnail Generator (YouTube Image)",
"type": "main",
"index": 0
}
]
]
},
"Parse Blog Article JSON": {
"main": [
[
{
"node": "Create Episode Draft Record",
"type": "main",
"index": 0
}
]
]
},
"Trigger: New Audio File": {
"main": [
[
{
"node": "Download Raw Audio",
"type": "main",
"index": 0
}
]
]
},
"AI Blog Article Generator": {
"main": [
[
{
"node": "Parse Blog Article JSON",
"type": "main",
"index": 0
}
]
]
},
"AI Transcript Cleaning & QA": {
"main": [
[
{
"node": "Parse Cleaned Transcript JSON",
"type": "main",
"index": 0
}
]
]
},
"Create Episode Draft Record": {
"main": [
[
{
"node": "AI Social Media Content Generator",
"type": "main",
"index": 0
}
]
]
},
"Parse Episode Metadata JSON": {
"main": [
[
{
"node": "AI Blog Article Generator",
"type": "main",
"index": 0
}
]
]
},
"Save Buzzsprout Episode Data": {
"main": [
[
{
"node": "Prepare Slack Message",
"type": "main",
"index": 0
}
]
]
},
"AI Episode Metadata Generator": {
"main": [
[
{
"node": "Parse Episode Metadata JSON",
"type": "main",
"index": 0
}
]
]
},
"Parse Cleaned Transcript JSON": {
"main": [
[
{
"node": "AI Episode Metadata Generator",
"type": "main",
"index": 0
}
]
]
},
"AI Social Media Content Generator": {
"main": [
[
{
"node": "Parse Social Content",
"type": "main",
"index": 0
}
]
]
},
"Prepare Buzzsprout Episode Payload": {
"main": [
[
{
"node": "Download Audio for Buzzsprout Upload",
"type": "main",
"index": 0
}
]
]
},
"Download Audio for Buzzsprout Upload": {
"main": [
[
{
"node": "Upload Episode",
"type": "main",
"index": 0
}
]
]
},
"AI Thumbnail Generator (YouTube Image)": {
"main": [
[
{
"node": "Save Thumbnail URL",
"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.
airtableTokenApigoogleDriveOAuth2ApiopenAiApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically turns any audio file uploaded to Google Drive into a complete podcast episode. It handles transcription, content generation, blog drafting, social copy creation, thumbnail generation, Airtable record updates, Buzzsprout publishing and finally notifies…
Source: https://n8n.io/workflows/12020/ — 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 template is ideal for photographers, graphic designers, and creative professionals who manage large volumes of visual assets. It is also perfect for Digital Asset Managers looking for a customiza
Some use cases: Sales follow-ups, auto-qualifying leads based on budget, monetizing low-budget leads, and automatic data entry. Ingestion: When a call recording is uploaded to a specific Google Drive
This workflow monitors a Google Drive folder for newly uploaded APK files, automatically downloads them, triggers a MobSF static analysis scan, processes the output to detect unused or risky libraries
This template is designed for content creators, marketing teams, educators, or media managers who want to repurpose video content into written blog posts with visuals. It's ideal for anyone looking to
The Problem That it Solves