How I Built PandoRdio
February 19, 2013
PandoRdio is a Google Chrome Extension that adds a song to your Rdio collection after you “thumbs up” a song in Pandora.
Easy, Right?
While the extension is actually a very simple Chrome Extension, there were a few things I had to put in place to get it to work. There were a couple roadblocks:
- Pandora offers no API
- The Rdio API has a same origin policy
No Pandora API
Pandora doesn’t offer an API. All I needed to know was when
someone “thumbs ups” a song, and what the artist and track are.
Because there’s no API, I decided to just use a Google Chrome
content script and listen to the click
event on the various
“thumbs up” buttons scattered across www.pandora.com.
Rdio’s Same Origin Policy
Rdio’s API (http://api.rdio.com/1/) has a same origin policy. So I created a proxy in Node.js. This “proxy” does a little more than merely proxy requests to the Rdio API, though.
I have it hosted on Heroku, where it’s also serving as the public landing page for PandoRdio. You authorize PandoRdio’s access to your Rdio account through here, and a cookie is set to handle the OAuth requests to the Rdio API.
Rdio JavaScript Library
Now that I had a working proxy up, I just needed a small JavaScript library that used it and provided the handful of API methods I needed to use. It’s available on GitHub and provides the following API methods:
- search
- addToCollection
- setAvailableOffline
- getPlaylists
- createPlaylist
- addToPlaylist
All Together Now
Here’s all the apps involved:
- pandordio-node - the Node.js proxy
-
PandoRdio - a project containing Rake tasks to build the rdio-api and copy it into pandordio-chrome
- pandordio-chrome - the Google Chrome Extension
- rdio-api - the Rdio JavaScript Library
Credits
Almost all of the Node.js code is based off monsur’s rdio-node.
The Google Chrome Extension
So, now I had all the ingredients necessary to write the extension that would add a song to my Rdio collection when I “thumbs up”ed a song in Pandora. The result is the PandoRdio extension available in the Google Chrome Webstore.