It’s been a while since our Ruby gem was first released. Today we’re going to take a closer look at it by studying a practical example: ofmtweet. It’s a simple application that displays the last few tweeted tracks along with official.fm players. Besides being a great way to keep up with what’s being listened to on the Twitterverse, it’s actually a good example to get to know our Ruby bindings better!

Since it’s a small application, we are going to use the Sinatra web framework, with the DataMapper ORM, REXML to manipulate XML blocks, and of course the Twitter and Official.fm gems. We’re going to need a database to cache our results, since the combined requests to Twitter + Official.fm APIs make loading from scratch very costly. An in-memory SQLite instance will be more than enough.
Getting started
Here’s our Gemfile, run bundle install and you’re all set!
Your first step as an Official.fm application developer is to register your application in the developers zone. Don’t forget to give your application a meaningful name and description, along with a pretty logo — you don’t want to be unprepared when we pick your application to be featured on this blog!
Once you have your Application key, use it to complete this skeleton Sinatra app we’re going to flesh out:
To make sure we’re on the right path, run ruby app.rb and visit http://localhost:4567/ (or whatever port Sinatra is running on) to see the result.
Fetching tweets
This is not a Twitter API tutorial, but thankfully, the twitter gem is really easy to use. Good job, @jnunemaker! We’re going to be searching for tweets containing the string official.fm/tracks/. Since searching with the Twitter API is serious business, we need to create a Search object, specify that we want recent results (well duh), and say how many results we want. This is roughly what we’re looking at:
For a more complete example, see this gist which displays a pretty ugly list of tweets, but hey, it works.
Creating players
It’s easy to create an Official.FM player once we know the ID of the track we want to play. We use regular expressions to validate the track URLs and extract the track ID. We also ignore retweets, since they’re annoying, and we check for the presence of official.fm/tracks/, because the Twitter API searches in expanded short-urls, thus we’re going to end up with bit.ly, fb.me, jmp.
So what’s going on here? First, we create an OfficialFM::Client with our Application key. Then we retrieve information about a track, by ID, including embed codes, and we use the small embed codes in our list of tweets. The result is pretty neat, although at this point it’s obvious it needs a designer’s touch. See this gist for an example of players in the timeline.
The best way to see what’s happening behind the scenes it to play with our API Console. Here’s an example request made by our application. We could display a lot more infos such as the downloads count, creation date, genres, and a download link for some tracks.
Improving performance
If you’ve gotten this far, you might’ve noticed the application is running slow as fuck. Now the reason we have a database in the first place is because we want to cache those results. Instead of just caching the Twitter API results, we’re going to go one step further and cache the XHTML nodes we use to display the tweets in our application. This severely improves load times when the data is still fresh (<600s old, for the example). Since this is not a DataMapper tutorial, let me refer you to the ofmtweet repository, which contains the full database logic presented in this paragraph.
Another suboptimal detail in our implementation (besides the fact that Twitter’s public keyless API seems to take pleasure in waiting 3 secs before answering) is that one request per track is done in order to create a player. Not only is it wasteful and slow, it’s also unnecessary! Our upcoming JavaScript player API allows you to create Official.fm players on-the-fly, allowing a full dynamic experience. I’ve been dreaming of a minimalist HTML5+CSS3+JS unofficial front-end to Official.fm for ages now. Can you pull it off? I’d love to feature such an app on this blog.
See you next time for another language binding announcement!