Alexa Flash Briefing and Anchor.fm RSS Feed

[Tutorial Tuesday]

Today we are going to solve a problem that I came across recently when I turned my Anchor.fm podcast into a feed for an Amazon Alexa Flash Briefing. As with many podcasts, you can share the podcast to play with Alexa through an RSS feed.

It turns out that the RSS feed from Anchor FM shows a number (maybe the most recent 10+) podcasts. This is fantastic for when I want to have the top 10 items available on my website [https://www.fortyfour-three.com/daily-minute-podcast/]. But it isn’t great when you want to have Alexa only play the most recent podcast, not the last 5. I am not the only one with this issue [https://forums.developer.amazon.com/questions/172076/flash-brief.html], so I’ve created a short Python script that will help me solve the problem.

In our script today we are going to:

  1. Get the full RSS XML from my Anchor RSS [https://anchor.fm/s/94eb7c8/podcast/rss]
  2. Read the XML, and then take out each of the nodes except the first one. The elements are the elements that give Alexa information about the podcast to play.
  3. Save the whole XML structure to a file.
  4. Set up my Daily Briefing to look at the RSS file I created, not the Anchor.fm RSS. [This part was a fun and glorious failure, but a problem that you can easily avoid – you’ll see why.)

The one constraint I wanted to apply is that I wouldn’t install any package that wasn’t included with the core installation of Python. This way anyone can implement this code. I’m using Python 3.6, but you could probably use Python 2.7 to do the same thing.

Let’s get started.

Pulling RSS XML from Anchor RSS feed

First, we import a couple of libraries: one to read other websites, and one to read XML files. We can easily access the RSS feed and have python read it as the XML file that it is. When we load the RSS text from another website, we are loading it as a string into our XML object. This means that it is treated as an element, not the whole element tree. This will matter later.

# Import the xml library. We'll name it ET for ease.
import xml.etree.ElementTree as ET

# Import the web-page reading library
import urllib.request

## RSS URL
url = 'https://anchor.fm/s/94eb7c8/podcast/rss'

## Open the URL and read the page.
uf = urllib.request.urlopen(url)
tree_text = uf.read()

## Turns the RSS into an element.
root = ET.fromstring(tree_text)

Read the XML File And Eliminate Each node

Once we have the RSS data in an XML element format, we only need to find each ‘item.’ Using the following code, we save the first item and Remove all other items.

## If the counter is 0, then it doesn't remove the item
## If the counter is 1 (after the first element. Then the item is removed.
counter = 0
for item in root[0].findall('item'):
	if counter == 0: 
		counter = counter + 1
	else:
		root[0].remove(item)

Save The Whole XML Structure To a File

This is where reading the XML from a string into an element can get a little confusing. To save the XML, it must be an ElementTree object. In order to make this work you must:

  1. Create an empty element tree object
  2. Add your XML element (the one that you have filtered out all of the items except for 1.)
  3. Save the element tree after defining parameters like ‘utf-8’, the XML declaration, and filename.

Our code looks like this:

## Create an empty element tree.
tree = ET.ElementTree()

## Set the root of the element tree with the XML that we have been 
## 	working with.
tree._setroot(root)

## Write it to a file.
tree.write('podcast_rss.xml', encoding="utf-8", xml_declaration=True)

Set up my Daily Briefing to look at the RSS file I created

This step is where it all ground to a halt. In a perfect world I would take my code, throw it on the web-server, and have the server generate the updated single-item RSS feed daily. In the real world, my service provider only executes Python 2.5 scripts. This means that I am entirely out of luck for running this on a web-server. In turn, I haven’t been able to point Alexa to my single-entry RSS feed. (The truth is that I might have to recode this all in PHP to make it work.)

If you have a server that will execute Python 3, or even 2.7 you could run this code with a cron job every day. This would update the RSS feed that Alexa can look at. If you triggered that even each day by a cron job, you would save some of your sanity.

Happy coding, podcasting, and Alexa Skilling!

The full code is below:

## FortyFour-Three Query Script
## Single RSS feed item from Anchor.fm
## Verson 1.0 - 2019-03-19

# Import the xml library. We'll name it ET for ease.
import xml.etree.ElementTree as ET

# Import the web-page reading library
import urllib.request

## RSS URL
url = 'https://anchor.fm/s/94eb7c8/podcast/rss'

## Open the URL and read the page.
uf = urllib.request.urlopen(url)
tree_text = uf.read()

## Turns the RSS into an element.
root = ET.fromstring(tree_text)

## If the counter is 0, then it doesn't remove the item
## If the counter is 1 (after the first element. Then the item is removed.
counter = 0
for item in root[0].findall('item'):
	if counter == 0: 
		counter = counter + 1
	else:
		root[0].remove(item)

## Create an empty element tree.
tree = ET.ElementTree()

## Set the root of the element tree with the XML that we have been 
## 	working with.
tree._setroot(root)

## Write it to a file.
tree.write('podcast_rss.xml', encoding="utf-8", xml_declaration=True)