Twilio and Rails 3: Tracking SMS Conversations

Alex Meyer is a developer and a DOer. While building a Twilio Powered app on Rails 3, he ran into a problem but quickly developed the solution. Below is a detailed post by Alex on tracking SMS conversations built with Twilio on Rails 3.

 He is the founder of stealth startup Ordext, an SMS restaurant ordering service, that is built on Ruby on Rails and powered by Twilio. Follow Alex on Twitter at @Meyer_On_Fire and @Ordext.

Twilio and Rails 3

I have been working on a web app that integrates Twilio and could not find the Rails documentation needed to solve an issue I ran into. Below should be a helper to any developer using Twilio with Rails 3 for both Twilio SMS and Twilio Voice API.

Problem

While trying to integrate Twilio into my Rails app I came across the issue of how to keep track of a SMS conversation.  Following along with the Twilio documentation on tracking SMS conversations as found here, I came up with the following code:

This code is part of a separate controller that I created in my Rails app to handle Twilio SMS. It allows me to redirect the conversation if it has already been started, or start a conversation from the beginning.  The code also uses the session variables provided by Rails, which stores a cookie on the client-side so that you can remember certain states in the application.

Having written this code I figured I was all set and ready to go.  I placed this code on the server and tried sending a couple test texts.  The start of the conversation worked perfectly, I was able to receive the correct responses.  However, when I would respond to this text message and expect the conversation to be passed to the next action in my controller, I was getting the same responses I got at the start of the conversation.

This was a problem. I knew that it had to be the session variable that wasn’t being saved but I had no idea why.

Searching for a Solution

At first I thought it was because of the way Rails saves session data in cookies. I knew Twilio handled SMS conversations using cookies, but perhaps the cookies were incompatible and I would need to change the storing of the session data in the cookie to the server instead of client.  This however, did not help at all as the session variable was still not being saved. Another way to get around the cookie problem would be to create my own and save everything in a created database table. This is feasible but very time consuming and not practical.

Searching online for answers, I stumbled across Cross Site Reference Forgery and Rails. The Rails guide on this can be found here. In Rails, to protect against CSRF, there is a line of code found in the application controller:

This line of code protects the entire application against CSRF. The way it defends the application from this kind of attack is to delete any session variables that exist. This is obviously a problem when trying to use session variables.

Going back to my server logs, I found that this was in fact the reason for my session variables not working.  This line would appear after the post request to my application:

Because of this, all the session variables that I had created and tried to save were being deleted each time a new text message was sent from Twilio to my Rails app.

The Solution

I learned there are two ways to solve this problem, both simple and straight forward.  The first is changing the POST requests to GET requests. This can easily be done by visiting your Twilio account page and changing the dropdown menu next to your SMS URL from POST to GET.  Rails does not protect GET requests from CSRF and therefore doing this will solve the problem.

If you want to keep POST requests then you need to make sure Rails doesn’t protect against CSRF in the controller you are using to accept requests from Twilio. Doing this requires just one line of code:

Adding this line of code to the controller you use to handle the Twilio requests will disable the CSRF protection for only this controller.

Once I did this within my own controller, everything worked flawlessly and just they way I expected. Session variables saved the way they were supposed to.

I hope this article helps any users who are looking to incorporate Twilio into their Rails apps!