Podcasts are more popular than ever. Host your own using Airtable, Serverless Framework, and AWS: Airtable for your data, AWS S3 for your files, and a Serverless function to generate your RSS feed.
I consult on technology for Through the Word. We currently have an audio-based mobile app and wanted to launch this content as a podcast. Since we already enjoy Airtable as a CMS for our mobile app, we wanted to use it for the podcast too. That way our content managers could easily update everything in one place. Here’s how you can do it too! Let’s get started.
For quick setup, copy this base as your template: https://airtable.com/shrzl0jEHPL0VUUfj
There are 4 tables:
iTunes Categories, and
iTunes Subcategories. Let’s walk through it.
Podcast holds the information for the show: title, description, link, etc.
Episodes holds all episode information: title, description, audio, etc.
iTunes Categories and
iTunes Subcategories get fancy using linked records and contain the Apple Podcasts categories.
Now you can name the fields more descriptive, but I made them reference the XML tags for now just so we can see how they match up.
Audio and Image Files
We will host podcast audio and image files on AWS S3 so we don’t run into file limits on the Airtable. While I won’t cover S3 in detail in this tutorial, here’s the gist.
First, create an AWS S3 bucket. Then, upload all your audio and image files into S3. Finally, copy the file links from S3 and paste it into the field on Airtable. You can see how the S3 links are structured in the Airtable template on
<enclosure url> (podcast audio) and
<itunes:image> (podcast image).
One hangup to be aware of is the S3 file permissions. You will need to set permissions on your bucket to be public for the podcast files. Just be careful because any files that are public can be requested by anyone and will count toward your AWS S3 costs!
For quick setup, get the code on Github. Let’s walk through it.
First, download Serverless and follow the quick start instructions for AWS: https://serverless.com/framework/docs/providers/aws/guide/quick-start/.
Just as a summary, we will download Serverless, then run the
serverlesscommand to start a new project in Node.js.
You will also need to set up your AWS credentials by following this guide:
Write our Serverless Function
Now that we have a Serverless project up and running, we will create a lambda function that will generate the podcast feed. We want this function to grab the podcast data from Airtable, format it as XML, and then return an RSS feed.
To start, let’s rename the starting
hello function to
feed and add the endpoint.
Fetch Airtable data
Let’s write a function to grab the tables:
iTunes Categories ,
iTunes Subcategories . You will also need to add the Airtable JS client and authenticate it with an API key.
First, get your API key by following the instructions on Airtable. Next, you will need to get your base ID. Go to https://airtable.com/api after you have duplicated the example Airtable base. Select that base and the ID will be right on the introduction page.
Now, add these as environment variables. For this tutorial, we are going to add them to
serverless.yml but make sure to not make your code public or your credentials will be compromised.
Now, let’s write the function. Add the Airtable client and the
fetchAirtableRecords function to the top of
First, grab the Airtable Base with your API key and Base ID.
Then, we get the
iTunes Categories records and
iTunes Subcategories records and return them. For more explanation on this, you can look at the API documentation generated specifically for your base. Thanks, Airtable!
One fancy thing the
Episodes fetch has is the
filterByFormula property to get only the episodes that are past-dated. This means you can set the
<pubDate> on an episode to be a future date and it will be “scheduled” for that date to post.
Finally, let’s add the
fetchAirtableRecords() function to the top of the
feed function and destructure the result back into the records we need.
Format the records into XML
Now that we have all of the records, we can format them into XML. Let’s start with the
We need to get each field from the
podcast record and put it into the XML body. For example:
body in the response.
At this point you should be able to test your function locally and deploy it on AWS and see your feed.
sls invoke local --function feed to run the function locally. Make sure there are no errors and then you run
sls deploy to deploy your function and API endpoint. After successfully deploying, it will give you an endpoint that looks like this:
Great! Now that we know the feed is working, we need to add categories and subcategories. According to Apple Podcasts documentation, categories are formatted like this.
<itunes:category text="Society & Culture">
<itunes:category text="Documentary" />
So we set up a function that formats the category and subcategory into XML.
iTunes Categories and
iTunes Subcategories tables are set up in Airtable with relationships to each other like this:
Then add the categories to the XML body. Use
join() to break the array of categories out into a string and separate each item by a new line.
We will set up the episodes in a similar way. Create the
episodeXML() function to format an episode into XML.
map() to format all episodes into XML.
Finally, add the episode XML to the body using
join() , just like the categories.
Phew! Now you should have a working podcast feed with all your podcast data, category data, and episode data. Run
sls deploy again to see your podcast feed in all its glory!
The Apple Podcasts documentation is a great reference for the XML formatting if you run into any trouble.
Bonus: Set up your feed on a custom domain
If you want to assign your feed to a custom domain, you can follow this tutorial:
Using the serverless-domain-manager plugin, you can add a domain that is registered on AWS Route 53 to be the custom domain for your feed. In Through the Word’s case, we assigned our domain to
Bonus 2: Podcast Platforms Links
Here are links where you can submit your feed on the largest Podcast platforms.