Send Mass SMS Broadcasts in Ruby
Time to read: 7 minutes
Sometime in the next four weeks, my wife is going to go into labor. We’ll wait at home for as long as possible, then hop in the car and head to the hospital. At that point begins one of my comparatively few responsibilities over the next couple days: updating close friends and family of what’s going on.
Text messaging seems tailor made for times like these. Unfortunately, texting gets messy when it involves a group of people. To solve my message “delivery” problems, I’m building a group messaging app using Twilio SMS to broadcast one-to-many messages when I make an announcement, and receive one-to-one text-message when my friends text back. And now that Twilio supports MMS, I can send and receive pictures too.
Now, I’m building this app to make my life easier on baby day, but SMS broadcasting has tons more uses than this such as emergency management, teachers communicating with students, or talking trash with your fantasy football league to name a few.
In this tutorial, we’ll build an app to broadcast text messages using Sinatra, Google Docs, and Twilio. This app will:
- Retrieve contact names and numbers from a Google Spreadsheet
- Forward a message from your phone to all your contacts
- Forward a message from one of your contacts to your phone
Here’s what you’ll need to get started:
- A free Twilio account
- An MMS enabled Twilio number
- A Gmail account
- Ruby
The rest of this post will walk you through how to write this code line by line. If you’d like to jump to the finished product, check out my Text Message Broadcast GitHub repo. Also, at the bottom of this post you’ll find a Deploy to Heroku button that will get your own broadcast app live in minutes.
Retrieve contacts from a Google Spreadsheet
You could hard code your friends and family’s phone numbers, but that means re-deploying every time you want to add an aunt to the list. Who has time for that when there’s a baby on the way?
A while back I was inspired by this tweet by Patrick McKenzie, a longtime friend of Twilio who recently welcomed his own daughter into the world (Congrats Patrick!):
Perfect!
Open Google Drive and create a new spreadsheet with two columns named ‘number’ and ‘name’ (it’s important that you give your columns these names and in this order — you’ll see why soon). Punch in a couple numbers to play with — when I was building my app, I used my cell phone and my wife’s cell phone. No point in spamming my friends during development.
Click File -> Publish to Web and you’ll see a link to a publicly accessible version of your document. Unfortunately the document at the other end of this link is not in JSON, but I found this article on How to Use Google Spreadsheet as a JSON backend that tells us how to fix that that.
In the middle of that link (and in the url in the navbar of your browser) is an ID for your spreadsheet:
Open broadcast.rb and:
- require the libraries needed to open a uri and parse json
- define a constant for your spreadsheet ID
- create a method to return the url of the spreadsheet data in JSON format
Twilio expects ten digit phone numbers sans punctuation and spaces, prefixed with with a valid country code ( “+1” for the US). Let’s create a method that will add the country code and strip out non-digits. We’ll also strip off any leading ‘1’ so that we don’t end up with the country code on there twice.
Add this to the bottom of your code:
Next, create two methods to:
- open the spreadsheet and parse the JSON data
- iterate through each spreadsheet entry
- extract the values for each number and name
- return the pairs as a hash
When run, contacts_from_spreadsheets returns a hash in the format of:
For the sake of verbosity, create two simple methods to:
- return an array of all of our contacts’ phone numbers
- look up a contact’s name given their phone number
And that’s it for Google! If you want to give this a go, load this file in irb and try running each of the methods:
You’ve got an easy-to-maintain phonebook in the form of a Google Spreadsheet. Now let’s do something with those numbers.
Broadcast text messages using Sinatra and Twilio
One thing that’s surprised me since starting at Twilio is how useful Sinatra can be for building Twilio apps. I’ve always been more of a Rails guy, but it turns out that with Sinatra + Twilio you can build some pretty powerful apps in a single file.
To get started, create a Gemfile. It’s a simple app, so you won’t need much:
Then install your gems from a terminal:
Add two more requires to your broadcast.rb, then add a new constant for your cellphone number:
When your Twilio number receives a text, Twilio makes an HTTP request to your server. In the parameters of that request you can find details about the message in the same way that you would find data from from a form submission. Just as a web browser makes an HTTP request and expects an HTTP response in the form of HTML, Twilio expects a response in a form of Twilio-flavored XML that we call TwiML. For example, the generic TwiML to send a single message looks like this:
If you want to send multiple messages then you simply add more message blocks inside the response tag. If there’s no picture, you omit the tag.
With that roadmap in mind, create a method that will:
- handle Twilio’s POST request
- extract the message details
- call yet-to-be-defined methods to generate instructions on where to forward the messages
- return those instructions to Twilio as an XML response
Now let’s create your send_to_contacts method which will:
- accept a message body and (optional) media_url as arguments
- iterate through your contacts’ numbers and…
- … send a message to each number with the appropriate message body and media_url (unless it’s nil)
- return the text of the generated TwiML response
Thanks to the Twilio Ruby gem, you won’t have to write TwiML by hand.
Onto the second use case: a friend texts your Twilio number and you want to forward that message to your cell phone and your cell phone only. Now, when that message shows up on your phone it’s going to be from your Twilio number, so you’ll want to prepend the message body with the sender’s info.
And that’s it for the Ruby code! Open a terminal and fire up your Sinatra server:
Make it Live
There are only two more steps needed to make your broadcast system operational from your development machine:
- make your Sinatra server accessible to the public Internet
- tell Twilio where to find it
There are a number of ways to do the former, but my favorite is to use ngrok. If you haven’t used ngrok before, this article from Kevin Whinnery will show you how to set it up in less than five minutes. I highly recommend registering for a free ngrok account so that you can take advantage of the subdomain flag which will prevent you from needing to update your webhook settings in Twilio everytime you restart ngrok. Once you’ve installed ngrok, start it up and point it at Sinatra’s default port, 4567:
Finally, tell Twilio where to find your webserver when it gets an incoming text:
- Go to the numbers list in your Twilio dashboard
- click on your preferred Twilio number
- replace the Messaging Resource URL with http://example.ngrok.com/message
That’s it! Save your settings and send a text to your Twilio number. The numbers you defined in your spreadsheet should get a copy of the message. Reply from a number that’s not MY_NUMBER and you should get that message only on your cellphone. Now try it with a picture.
Deploy to Heroku
In order for this app to be useful when your computer’s offline, you’re going to have to get it off of your development machine and into the cloud. The easiest way to deploy the stock version of this app (found at my GitHub repo) is to click this button:
(Props to Heroku for that little piece of magic.)
Once you’ve done that, you’ll need set environment variables for MY_NUMBER and SPREADSHEET_ID:
- go to the dashboard for your Heroku app
- click Settings at the top right of the page
- click Reveal Config Vars
- click Edit
- Add MY_NUMBER and your cellphone in the format of: +1XXXYYYZZZZ
- Add SPREADSHEET_ID
Then, in your Twilio dashbaord, point the messaging URL for your Twilio number to http://yourherokuapp.herokuapp.com/message.
Onward
Congrats! You now can blast out text and picture messages to friends and family while maintaining your contacts as easily as updating a spreadsheet. I hope it’s as useful for you as I imagine it will be for me in a few weeks.
If you run into any problems along the way, have a cool story to share about how you’ve used this app or if you have any tips on how to survive the first few weeks of parenthood, hit me up at gb@twilio.com or @greggyb. Fair warning though, I may be a bit preoccupied starting around mid-November.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.