Get Sentimental About SMS with Twilio, Bluemix and AlchemyAPI

November 11, 2015
Written by
Phil Nash
Twilion

IBM’s Bluemix platform is home to an ever growing number of cognitive computing services that, as developers, we can use in our applications to learn more about our data. Earlier this year Ricky showed us how combining Watson’s question and answer API, Twilio and Node.js could get us answers to health questions. Also living under the Watson banner, AlchemyAPI is a set of services for understanding content and context within text and images.

This is where my lame headline joke kicks in. I’m not talking about getting nostalgic about sending abbreviated SMS messages from your Nokia 3310. Today we’re going to look into analysing the sentiment of text messages using one of the AlchemyAPI services hosted on Bluemix. We’ll build up an application that receives SMS messages and deals with them differently based on the sentiment in the message.

If you’d rather watch a video of this tutorial you’re in luck as earlier this year I live coded the application as part of an IBM Bluemix webinar.

If you’d like to see what the app does right now you can send a text to my customer support line on 07903596047, if you’re in the UK like me, or (415) 214-9793 in the US. Feel free to praise or complain about the service and see how it responds.

Sending messages with different sentiments to the service results in different replies

Tools for today

Before we start you’re going to need to set up some bits and pieces. You’ll need:

And then to run the app you’ll need:

  • A Twilio number that can send and receive SMS messages
  • Ruby and Bundler installed
  • The Cloud Foundry CLI (this is the way to interact with Bluemix from our command line)

Let’s get started

When Ricky built his Watson based app, he started on the command line. I’m going to take the opposite approach for this application and start in Bluemix as they have some starter projects that are ready to go. Log in to Bluemix and create a Cloud Foundry app. Create a Web App and then use one of the provided boilerplate applications by clicking on “Browse Boilerplates” then choosing the Ruby Sinatra package. Enter a name for your app and click “Create”.

Your application is now starting up on Bluemix. And we haven’t even written a line of code yet. Exciting! Once the application has started you will be able to visit it. For example, my application just started up at http://sentiment-analysis.eu-gb.mybluemix.net/.

The default landing page for a Sinatra application on Bluemix. It says 'Hi there!'

It doesn’t do much just yet though. To get any further, we will need to write some code, so let’s download that starter project from Bluemix.

Go back to the application starting page and follow the instructions to download the project and connect Cloud Foundry

This is the best time to hook up the project we’ve downloaded with Bluemix using the Cloud Foundry command line tool. The steps are laid out further down on the page pictured above. Follow them and everything should be set up nicely. If everything worked as planned you should be able to push your local copy of the application to the server and see the application running from your terminal:

The terminal will show that the state of the application is running.

If you open up the example project you’ll see the code for the boilerplate application. It’s time for us to get to work on our application code now.

Receiving text messages on Bluemix

Crack open the project in your text editor. If you open up the file helloWorld.rb you’ll see we have a Sinatra application. This is what is running in Bluemix right now. For the purposes of our application, we have no need to change the root path that is showing the holding page. Instead, let’s build something that can receive SMS messages and respond to them.

We’ll need an endpoint in our application at which we can point our Twilio number’s webhook. The endpoint will need to return TwiML, a set of instructions in XML that tell Twilio what to do with a message or phone call. In this case, we just need to return a simple response that tells Twilio to reply with a message. Add this code below the requires at the top of helloWorld.rb:

# helloWorld.rb
post "/messages" do
  content_type "text/xml"
  "
  <Response>
    <Message>Thanks for texting my Bluemix application!</Message>
  </Response>
  "
end

Great, that’s all we’re going to need for now. Save the file and push it up to Bluemix again.

$ cf push your_app_name

Now head to the Twilio dashboard. You should have a phone number you can use to send and receive messages, if you don’t, buy one now! When you’ve got it, edit the number and find the request URL field. Fill that field in with http://your_app_name.eu-gb.mybluemix.net/messages and save.

Fill in the Messaging Request URL field with your application URL

Now, send a message from your phone to your Twilio number and wait from the response from Bluemix.

Sending any SMS message to your Twilio number and your application will reply with 'Thanks for texting my Bluemix application!

Now that sending messages is working, let’s get onto the second part: making the responses smart with sentiment analysis from AlchemyAPI.

Getting sentimental

Head back to the Bluemix dashboard and add the AlchemyAPI service to our application. From your app overview page, click on “Add a service or API”, find the AlchemyAPI service and click “Create”.

You’ll see that the AlchemyAPI service comes with an API key to use. You can view the credentials under the Environment Variables section of your app.

Back in the code we need to add one new gem to the project to make it nice and easy to work with AlchemyAPI. Open your Gemfile and add this line at the bottom:

# Gemfile
gem 'alchemy-api-rb', :require => 'alchemy_api'

Open up helloWorld.rb again and require the gem at the top of the file:

# helloWorld.rb
require 'alchemy_api'

Now we need to get hold of our API key from the environment that Bluemix provides. Environment variables, including our AlchemyAPI key in Bluemix are stored in JSON under the variable VCAP_SERVICES. We’re going to add a quick helper function that will give us access to this JSON.

# helloWorld.rb
def vcap_services
  JSON.parse(ENV['VCAP_SERVICES'])
end

Then we can use that helper function to set our API key for the AlchemyAPI library:

# helloWorld.rb
AlchemyAPI.key = vcap_services["alchemy_api"].first["credentials"]["apikey"]

We’ll call the AlchemyAPI sentiment analysis API now by passing it some text to analyse. Here’s an example:

> AlchemyAPI.search(:sentiment_analysis, text: "I love sending text messages")
=> {"score"=>"0.685872", "type"=>"positive"}

As you can see, the result is a score and a type. Saying something negative will return a negative score and type:

> AlchemyAPI.search(:sentiment_analysis, text: "I miss my old phone")
=> {"score"=>"-0.899126", "type"=>"negative"}

Sometimes AlchemyAPI doesn’t quite understand and the gem will give back nil as a response, so we should be ready to handle that scenario.

> AlchemyAPI.search(:sentiment_analysis, text: "I miss my Nokia 3310")
=> nil

We can now hook this analysis code up with our code that receives SMS messages in order to respond based on the sentiment. We’ll need to get the incoming body of the message. In Sinatra, that message body is exposed on the params object as params["Body"]. We can feed the text to AlchemyAPI and get the sentiment.

Imagine if we were building an SMS feedback channel, we could do something like:

# helloWorld.rb
post "/messages" do
  content_type "text/xml"

  sentiment = AlchemyAPI.search(:sentiment_analysis, text: params["Body"])

  if sentiment
    case sentiment["type"]
    when "positive"
      # Set a reply for a positive message
      message = "Glad you're having a good day! Is there anything I can help with?"
    when "negative"
      # Set a reply for a negative message
      message = "Sorry things aren't going so well, how can I help?"
    end
  end

  # Set a reply if we haven't set one yet
  message ||= "What can I help with?"

  # Respond with the reply.
  "
  <Response>
    <Message>#{message}</Message>
  </Response>
  "
end

Replace the old body of the messages endpoint with the above code. Feel free to pick your own responses. Once you’re happy, push the code up to Bluemix using the Cloud Foundry tool again.

$ cf push your_app_name

Wait for the deploy process to complete. Then start sending your Twilio number messages with different sentiments and watch the different responses you get back.

If you can’t do this for yourself right now, you can try some different messages with my SMS support line on 07903596047 in the UK or (415) 214-9793 in the US. You can also check out the final application code on GitHub.

{ “type” => “positive”, “score” => “1.0” }

Now that you’ve seen how you can get started with Bluemix, AlchemyAPI and Twilio there’s loads more you can do.

You could try to drive an entire SMS based conversation based on sentiment, reacting differently as the user responds. Or you could check out some of the other AlchemyAPIs like Entity Extraction or Concept Tagging to really dig into the language processing power. If you want to get away from text, you can check out the Image Tagging or Face Detection/Recognition API.

I’m genuinely excited about APIs like AlchemyAPI and Watson and would love to hear if you have built anything or build anything with them in the future. Please let me know if you do in the comments, on email or on Twitter.