Host a Podcast with Airtable and Serverless Framework

Zachary Wenner
Apr 7 · 6 min read

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.

Image for post
Image for post

Background

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.

Image for post
Image for post

Airtable Setup

For quick setup, copy this base as your template: https://airtable.com/shrzl0jEHPL0VUUfj

There are 4 tables: Podcast, Episodes, iTunes Categories, and iTunes Subcategories. Let’s walk through it.

Image for post
Image for post

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.

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!

Serverless Setup

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 theserverlesscommand to start a new project in Node.js.

Image for post
Image for post
Serverless project settings

You will also need to set up your AWS credentials by following this guide:
https://serverless.com/framework/docs/providers/aws/guide/credentials/

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.

Let’s write a function to grab the tables: Podcast , Episodes , 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.

Image for post
Image for post
Example ID

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 handler.js .

First, grab the Airtable Base with your API key and Base ID.

Then, we get the Podcast records, Episode records, 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.

Now that we have all of the records, we can format them into XML. Let’s start with the podcast record.

We need to get each field from the podcast record and put it into the XML body. For example: <title>${podcast.fields['<title>']}</title>

Then, return 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.

Run 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:

https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/feed.xml

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 &amp; Culture">
<itunes:category text="Documentary" />
</itunes:category>

So we set up a function that formats the category and subcategory into XML.

TheiTunes Categories and iTunes Subcategories tables are set up in Airtable with relationships to each other like this:

Image for post
Image for post

Use the map() function to format the categories and subcategories as XML. Airtable references relationships by ID, you will need to get the subcategory by its ID to get its name.

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.

Then use 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!

Validate

We can use a validator to make sure our feed is working correctly. Apple Podcasts recommends https://podba.se/validate/ and https://castfeedvalidator.com/

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:
https://serverless.com/blog/serverless-api-gateway-domain/

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

https://podcast.throughtheword.org/feed.xml

Bonus 2: Podcast Platforms Links

Here are links where you can submit your feed on the largest Podcast platforms.

Apple Podcasts

Spotify

Google Podcasts

Flatsmith

Flatsmith Blog

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store