SMS and MMS Notifications with Ruby and Sinatra

Today we'll use Ruby and the Sinatra framework to demonstrate how to send SMS alerts to a list of system administrators when something goes wrong with your server.  We'll cover all the key details in depth so you can easily incorporate this important feature into your own application.

Clone our sample application from Github, then head to the application's README.md to see how to run the application locally.

See how EMC uses Twilio SMS to send IT alerts to 68,000 employees.

Let's get started!

Click the button below to begin the tutorial.

Configuring the Twilio REST Client

To send messages we'll need to create a Twilio REST client which requires reading a TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN from environment variables.

The values for your account SID and Auth Token will come from the Twilio console:

Twilio Account Summary section of the console

Click the eyeball icon to expose your Auth Token in a form you can copy and paste.

Loading Code Samples...
Language
require 'yaml'
require 'twilio-ruby'

module Notifier
  def self.send_sms_notifications(e)
    alert_message = "[This is a test] ALERT!"\
      "It appears the server is having issues."\
      "Exception: #{e}."\
      "Go to: http://newrelic.com for more details."
    image_url = "http://howtodocs.s3.amazonaws.com/new-relic-monitor.png"
    client = Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN']

    admin_list = YAML.load_file('config/administrators.yml')
    admin_list.each do |admin|
      phone_number = admin['phone_number']
      send_sms(client, phone_number, alert_message, image_url)
    end
  end

  def self.send_sms(client, phone_number, alert_message, image_url)
    twilio_number = ENV['TWILIO_NUMBER']
    message = client.account.messages.create(
      from: twilio_number,
      to: phone_number,
      body: alert_message,
      media_url: image_url
    )
    puts "An SMS notifying the last application error was "\
         "sent to #{message.to[0...-4] + "****"}"
  end

  private_class_method :send_sms
end
lib/notifier.rb
Read Twilio credentials from environment variables

lib/notifier.rb

Our Twilio REST Client is now ready. Let's take a closer look at that administrator list, shall we?

A List of Server Admins - And Anyone Else Who Should be Hailed

Here we create a yaml list of people who should be notified if a server error occurs.

The only essential piece of data we need is a phone_number for each administrator.

Loading Code Samples...
Language
-
  name: Doraj
  phone_number: '+15555679097'
-
  name: Nivek
  phone_number: '+15555679098'
config/administrators.yml
YAML Administrator list

config/administrators.yml

Next, let's look at how we're going to piggyback on application exceptions.

Handling Application Exceptions

We use Sinatra Errors Handlers and send out the notifications when an exception occurs.

Loading Code Samples...
Language
require 'sinatra/base'
require_relative './lib/notifier'

ENV['RACK_ENV'] ||= 'development'

require 'bundler'
Bundler.require :default, ENV['RACK_ENV'].to_sym

module ServerNotifications
  class App < Sinatra::Base
    set :show_exceptions, false
    set :raise_errors, false
    set :root, File.dirname(__FILE__)

    get '/' do
      raise "Kaboom! Something went wrong!"
    end

    error do |exception|
      Notifier.send_sms_notifications(exception)
      'An error has ocurred'
    end
  end
end
app.rb
Expose the GET route to trigger an exception and notifications

app.rb

Next up: sending a message to each administrator.

Trigger Notifications for Each Entry in the Administrator List

In our Notifier module, we read the administrators from our YAML file and send alert messages to each one of them with the method send_sms.

Loading Code Samples...
Language
require 'yaml'
require 'twilio-ruby'

module Notifier
  def self.send_sms_notifications(e)
    alert_message = "[This is a test] ALERT!"\
      "It appears the server is having issues."\
      "Exception: #{e}."\
      "Go to: http://newrelic.com for more details."
    image_url = "http://howtodocs.s3.amazonaws.com/new-relic-monitor.png"
    client = Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN']

    admin_list = YAML.load_file('config/administrators.yml')
    admin_list.each do |admin|
      phone_number = admin['phone_number']
      send_sms(client, phone_number, alert_message, image_url)
    end
  end

  def self.send_sms(client, phone_number, alert_message, image_url)
    twilio_number = ENV['TWILIO_NUMBER']
    message = client.account.messages.create(
      from: twilio_number,
      to: phone_number,
      body: alert_message,
      media_url: image_url
    )
    puts "An SMS notifying the last application error was "\
         "sent to #{message.to[0...-4] + "****"}"
  end

  private_class_method :send_sms
end
lib/notifier.rb
Read the YAML Administrator list

lib/notifier.rb

Next up, we will see how to send a text message.

Sending a Text Message

There are three parameters needed to send an SMS using the Twilio REST API: from, to, and body.

US and Canadian phone numbers can also send an image with the message.  Other countries will have an automatically shortened URL added to the message body.

Loading Code Samples...
Language
require 'yaml'
require 'twilio-ruby'

module Notifier
  def self.send_sms_notifications(e)
    alert_message = "[This is a test] ALERT!"\
      "It appears the server is having issues."\
      "Exception: #{e}."\
      "Go to: http://newrelic.com for more details."
    image_url = "http://howtodocs.s3.amazonaws.com/new-relic-monitor.png"
    client = Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN']

    admin_list = YAML.load_file('config/administrators.yml')
    admin_list.each do |admin|
      phone_number = admin['phone_number']
      send_sms(client, phone_number, alert_message, image_url)
    end
  end

  def self.send_sms(client, phone_number, alert_message, image_url)
    twilio_number = ENV['TWILIO_NUMBER']
    message = client.account.messages.create(
      from: twilio_number,
      to: phone_number,
      body: alert_message,
      media_url: image_url
    )
    puts "An SMS notifying the last application error was "\
         "sent to #{message.to[0...-4] + "****"}"
  end

  private_class_method :send_sms
end
lib/notifier.rb
Send an MMS or SMS

lib/notifier.rb

It's as simple as that! 

We've just implemented an automated server notification system that can push out alerts if anything goes wrong.

Next, let's look at what other features the Twilio Ruby SDK makes simple to integrate.

Where to Next?

We've got a lot of other excellent Ruby code we'd love to share with you... but we'll keep our links to just two:

Two-Factor Authentication

Increase the security of your login system by verifying a user's mobile phone in addition to their password.

SMS and MMS marketing notifications

SMS and MMS messages are a personal way to engage with users, offering a much higher open rate than e-mail and more impact than a tweet.

Did this Help?

Thanks for checking out this tutorial! Tweet @twilio with what you thought, what you're thinking, and most importantly... what you're going to build.

Jarod Reyes
Paul Kamp
Andrew Baker
Agustin Camino
Jose Oliveros

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd browsing the Twilio tag on Stack Overflow.

1 / 1
Loading Code Samples...
require 'yaml'
require 'twilio-ruby'

module Notifier
  def self.send_sms_notifications(e)
    alert_message = "[This is a test] ALERT!"\
      "It appears the server is having issues."\
      "Exception: #{e}."\
      "Go to: http://newrelic.com for more details."
    image_url = "http://howtodocs.s3.amazonaws.com/new-relic-monitor.png"
    client = Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN']

    admin_list = YAML.load_file('config/administrators.yml')
    admin_list.each do |admin|
      phone_number = admin['phone_number']
      send_sms(client, phone_number, alert_message, image_url)
    end
  end

  def self.send_sms(client, phone_number, alert_message, image_url)
    twilio_number = ENV['TWILIO_NUMBER']
    message = client.account.messages.create(
      from: twilio_number,
      to: phone_number,
      body: alert_message,
      media_url: image_url
    )
    puts "An SMS notifying the last application error was "\
         "sent to #{message.to[0...-4] + "****"}"
  end

  private_class_method :send_sms
end
-
  name: Doraj
  phone_number: '+15555679097'
-
  name: Nivek
  phone_number: '+15555679098'
require 'sinatra/base'
require_relative './lib/notifier'

ENV['RACK_ENV'] ||= 'development'

require 'bundler'
Bundler.require :default, ENV['RACK_ENV'].to_sym

module ServerNotifications
  class App < Sinatra::Base
    set :show_exceptions, false
    set :raise_errors, false
    set :root, File.dirname(__FILE__)

    get '/' do
      raise "Kaboom! Something went wrong!"
    end

    error do |exception|
      Notifier.send_sms_notifications(exception)
      'An error has ocurred'
    end
  end
end
require 'yaml'
require 'twilio-ruby'

module Notifier
  def self.send_sms_notifications(e)
    alert_message = "[This is a test] ALERT!"\
      "It appears the server is having issues."\
      "Exception: #{e}."\
      "Go to: http://newrelic.com for more details."
    image_url = "http://howtodocs.s3.amazonaws.com/new-relic-monitor.png"
    client = Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN']

    admin_list = YAML.load_file('config/administrators.yml')
    admin_list.each do |admin|
      phone_number = admin['phone_number']
      send_sms(client, phone_number, alert_message, image_url)
    end
  end

  def self.send_sms(client, phone_number, alert_message, image_url)
    twilio_number = ENV['TWILIO_NUMBER']
    message = client.account.messages.create(
      from: twilio_number,
      to: phone_number,
      body: alert_message,
      media_url: image_url
    )
    puts "An SMS notifying the last application error was "\
         "sent to #{message.to[0...-4] + "****"}"
  end

  private_class_method :send_sms
end
require 'yaml'
require 'twilio-ruby'

module Notifier
  def self.send_sms_notifications(e)
    alert_message = "[This is a test] ALERT!"\
      "It appears the server is having issues."\
      "Exception: #{e}."\
      "Go to: http://newrelic.com for more details."
    image_url = "http://howtodocs.s3.amazonaws.com/new-relic-monitor.png"
    client = Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN']

    admin_list = YAML.load_file('config/administrators.yml')
    admin_list.each do |admin|
      phone_number = admin['phone_number']
      send_sms(client, phone_number, alert_message, image_url)
    end
  end

  def self.send_sms(client, phone_number, alert_message, image_url)
    twilio_number = ENV['TWILIO_NUMBER']
    message = client.account.messages.create(
      from: twilio_number,
      to: phone_number,
      body: alert_message,
      media_url: image_url
    )
    puts "An SMS notifying the last application error was "\
         "sent to #{message.to[0...-4] + "****"}"
  end

  private_class_method :send_sms
end