Feed FM: Making Hold Music Less Boring With Twilio

April 14, 2014
Written by

feed-small
Left: CTO Eric Lambrecht Right: CEO Jeff Yasuda
Left: CTO Eric Lambrecht Right: CEO Jeff Yasuda

When you’re on hold, it might seem like time drags on forever. Your customers feel the same way when they’re on hold– because hold music is terrible.

Feed.FM is on a mission to provide a legal and easy way to add popular music (anything from Arcade Fire to Zeppelin) to your app, website, or game. They take care of all of the reporting, billing and licensing so you can focus on building your app and keeping your customers engaged.

Feed.fm’s API makes hold music better so you can keep your customers on the line, keep them happy, and improve conversions. It’s part of their philosophy of Music as a Service: using music to build a better customer experience on anything from hold music, ad campaigns, to in-game soundtracks.

After switching up Fuzz Blackjack’s in-game they boosted the average session playing time from 11 minutes to 51 minutes, the rate of return visit from 15% to 41%, and dropped the bounce rate from 52% to 2%. Now, Feed.FM is trying to bring the same results to your customer service line using Twilio.

Below is a demo of how to integrate Feed.fm’s easily searchable music database into your Twilio app using the Twilio API and Feed.fm API.

Make sure to sign up for the API at feed.fm/twilio and enter the promo code “twiliorocks” to get some free music and try out the service.  You can also check out their post about the integration on the Feed.fm blog.

Integrating Feed FM and Twilio

Twilio has a special markup language called TwiML that you use to create documents that tell it how to respond to voice calls. For example, you can associate a phone number with a URL that generates the following document:

Feed eff em and Twilio are keen!

When that phone number is called, Twilio will tell the caller about two cool services, then hang up. The commands in the document are called verbs. The Say verb instructs Twilio to read text to the caller. TwiML has a verb called Enqueue that places the caller in a hold queue. Normally while in the hold queue, your poor caller is subject to the default Twilio hold music. Let’s use Feed.fm to give the caller something better!

Getting Started

Next, let’s get an account on Feed.fm. Head over to the sign up page and create a new account. When asked, tell Feed.fm that you are adding music to an app and mark the platform as Other. You’ll then be asked what music you want for your app – search for a station called ‘Spaghetti Westerns’ for our experiment (you can always change this later). Feed.fm will ask you if you want to purchase more minutes, but you can do that after we’ve finished testing things out. Once Feed.fm tells you you’re ready to integrate, click on Home, click on the app we just created, and then click on the Embed Codes and IDs tab to get the credentials that you’ll need to put in your code to access the API.

Strategery

The key ingredient for using Feed.fm to power your hold queue music is the waitUrl attribute on the Enqueue tag, as in this document:

support

– See more at: http://feed.fm/twilio-enhanced-with-feed-fm/?__feed#sthash.1luG2dap.dpuf

If provided, Twilio will repeatedly retrieve the waitUrl to get instructions on how to entertain the caller.

We will build a script that requests music from Feed.fm and generates a TwiML document to tell Twilio to play the requested music. Our node script will generate a document that looks like this:

http://some.audio/file.mp3

– See more at: http://feed.fm/twilio-enhanced-with-feed-fm/?__feed#sthash.1luG2dap.dpuf

Twilio will play that song, then on completion it will call the script again to get another song to play.

Feed.fm API

Feed.fm’s REST API has an endpoint called ‘/play’ that will give us a new song to play. Before we hand the song over to Twilio, we also need to call the ‘/play/:id/start’ endpoint to let Feed.fm know that song playback has started.

Aside from authentication credentials, all we need to supply to the ‘/play’ endpoint is a client id. The client id is used to uniquely identify a listener so that DMCA music playback rules can be enforced, and can be created with a post to the ‘/client’ endpoint. Normally we’d cookie the listener with the id, but we can’t cookie a phone client. This script will need to keep a server side cache that maps the caller’s phone number (provided by Twilio) to a client id.

Implementation

Our node script uses the ‘express’, ‘superagent’, and ‘memory-cache’ modules, so make sure to install them with

npm install express superagent memory-cache

The simplest app we can make that responds with a TwiML document looks like the following:

var express = require('express'),
    http = require('http'),
    agent = require('superagent');

var app = express();

app.use(express.bodyParser());

app.post('/', function(req, res, next) {
  res.type('text/xml');
  res.send('Feed eff em and Twilio for the win!');
});

http.createServer(app).listen(8080);

That script will listen on port 8080 for incoming requests. If you point your Twilio phone number to that host and port 8080, you’ll hear the message spoken to you.

To talk to the Feed.fm servers, we need to include some authentication with all our requests. This is easily done by base64-encoding your authentication credentials and placing them in the header with each request like so:

var agent = require('superagent'),
    feedToken = 'beefdecadebeefdecadebeefdecadebeefdecade',
    feedSecret = 'beefdecadebeefdecadebeefdecadebeefdecade',
    userPass = new Buffer(token + ':' + secret).toString('base64'),

agent
  .post('https://feed.fm/api/v2/client')
  .set('Authorization', 'Basic ' + userPass)
  .end(function(err, res) {
    console.log('good stuff in the body of the response:', res.body);
  });

One caveat for our script is that we can only deliver music to people within the United States due to licensing restrictions. This is easily handled by looking at the ‘FromCountry’ parameter passed to our script from Twilio. When it is equal to ‘US’ we’re good to use Feed.fm music, otherwise we need to serve something else to the caller.

The final implementation of our app sticks together all the pieces above and looks like the following (available on github here):

var express = require('express'),
    http = require('http'),
    agent = require('superagent'),
    cache = require('memory-cache');

var feedToken = 'beefdecadebeefdecadebeefdecadebeefdecade',
    feedSecret = 'beefdecadebeefdecadebeefdecadebeefdecade',
    userPass = new Buffer(feedToken + ':' + feedSecret).toString('base64'),
    host = 'http://54.186.190.255:8080'; // replace this with your host address

var app = express();

app.use(express.bodyParser());

app.post('/', function(req, res, next) {
  res.type('text/xml');

  res.send('' +
           ' Hello there, please hold!' +
           ' support' +
           '');
});
app.post('/hold', function(req, res, next) {
  var from = req.body.From || 'unknown';

  if (req.body.FromCountry != 'US') {
    return res.send('We\'ll be with you momentarily!');
  }

  getClientId(from, function(clientId) {
    agent
      .post('https://feed.fm/api/v2/play')
      .send({ client_id: clientId })
      .set('Authorization', 'Basic ' + userPass)
      .end(function(err, r) {

        agent
          .post('https://feed.fm/api/v2/play/' + r.body.play.id + '/start')
          .set('Authorization', 'Basic ' + userPass)
          .end(function(err) {

            console.log('playing ' + r.body.play.audio_file.url + ' for ' + from);

            res.type('text/xml');
            res.send('' + r.body.play.audio_file.url + '');
          });
      });
  });

});

http.createServer(app).listen(8080);

/* Map an incoming caller to a Feed.fm client id */
function getClientId(from, next) {
  var clientId = cache.get(from);

  if (clientId) {
    return next(clientId);

  } else {
    agent
      .post('https://feed.fm/api/v2/client')
      .set('Authorization', 'Basic ' + userPass)
      .end(function(err, res) {
        cache.put(from, res.body.client_id, 1000 * 60 * 60 * 24);
        return next(res.body.client_id);
      });
  }
}

If you map your Twilio phone number to this script, you’ll be greeted and then placed in a hold queue that will play our ‘Spaghetti Westerns’ music!

While this is up and running you can log into your Feed.fm account and use our music management interface to change up the music all you want without having to change any code.

Happy hacking!

Learn more about Feed.fm by visiting their site here