29 August 2007
Sending SMS messages from your Rails application
Something I’ve seen come up on the Ruby/Rails mailing lists/google groups from time to time is how to send SMS messages from your Rails app. In this article, I’ll introduce you to my Ruby Clickatell library and how to use it to send SMS messages from your Rails application in no time.
When it comes to sending an SMS using Ruby there are two approaches you can take. The first – and more complicated – is to use your own hardware and something like the ruby-sms library to communicate with the hardware. This set-up is time consuming, a pain to maintain and probably not very scalable.
The second option is to take the much easier route and use an existing SMS gateway service. There are many SMS gateways out there that offer APIs (ranging from HTTP/FTP based to email and COM-based); one such provider is Clickatell who are one of the bigger providers out there with a range of services whose customers include Barclays Bank, the BBC and CNN.
Getting started with the Ruby Clickatell gem
Before you can start sending SMS messages from your Rails app, you’ll need a Clickatell account. You can sign up for an account (Clickatell Central API) on their website. Once you have signed up you can log into your account centre and add an HTTP service to your account – this will give you an API key that you will need to use in your code.
Once you’ve signed up, you need to install the Ruby Clickatell gem. I’ve just released version 0.4 and its fast approaching being stable for production use – all it needs is some users to test it out a bit more extensively. So install it and give it a go:
$ sudo gem install clickatell
The gem also comes with a handy command-line utility, “sms”, which can be used to send SMS messages directly from the command line. For more information, simply run:
$ sms --help
More information can be found on the website.
Integrating with Rails
For our basic example application, which will use REST-ful conventions, we will expose a single resource – sms – which we can POST to to send an SMS to a specified recipient. First of all, lets create a simple wrapper around the Clickatell API which will act as our “resource” that takes a hash containing our username/password/api-key and has an ActiveRecord-style create method.
require 'clickatell'
class SMS
def initialize(config)
@config = config
end
def create(recipient, message_text)
api.send_message(recipient, message_text)
end
private
def api
@api ||= Clickatell::API.authenticate(
@config[:api_key],
@config[:username],
@config[:password]
)
end
end
The above wrapper isn’t strictly necessary but it helps to keep our controller as skinny as possible.
For convenience, we’ll want to keep our Clickatell credentials in a YAML file in the config folder of our Rails app:
# config/clickatell.yml
api_key: abcdefghi123
username: joebloggs
password: secret
We’ll also want to access this config within our Rails app easily:
# config/environments/production.rb
CLICKATELL_CONFIG = YAML.load(File.open(File.join(RAILS_ROOT, 'config', 'clickatell.yml')))
Bringing it altogether
Now we’ll want to configure our routing to expose our SMS resource:
ActionController::Routing::Routes.draw do |map|
map.resource :sms
end
Next, we’ll create our form under app/views/sms/new.rhtml:
<% form_tag '/sms', :method => :post do -%>
<label>Enter the recipients mobile number:</label>
<%= text_field_tag "recipient" %>
<label>Enter your message:</label>
<%= text_area_tag "message_text" %>
<%= submit_tag "Send SMS" %>
<% end %>
Finally, all we have to do is create our controller’s create method to handle the form submission.
class SmsController < ApplicationController
def create
sms = SMS.new(CLICKATELL_CONFIG)
sms.create(params[:recipient], params[:message_text])
flash[:notice] = "Message sent succesfully!"
redirect_to :back
rescue Clickatell::API::Error => e
flash[:error] = "Clickatell API error: #{e.message}"
redirect_to :back
end
end
And thats all there is to it. Of course, in a real application you might want to think about things such as validation of required attributes and message length. I’ll leave that as an exercise to the reader.
For more information:
- Ruby Clickatell API Website
- Ruby Clickatell Documentation
- Rubyforge project page
- Clickatell Gateway information
Return to home page | Check out my tumblelog
15 Comments on this article
Return to home page | Check out my tumblelog
Commenting on this article is now closed
1. Comment by Pratik on 29 Aug 2007 at 15:08
This is wonderful stuff ! It’s so good to have you back :-)
2. Comment by Dylan on 29 Aug 2007 at 21:08
Thanks, this is indeed a great help, Luke. Was just about to go the ruby-sms route and stumbled across this and set it up in ten minutes. Awesome.
3. Comment by Mason on 30 Aug 2007 at 01:08
Not only have you provided an excellent resource, but also a service to go with! I had never heard of them until I read your post… was worrying over which gateway to go through. Kudos to you!
4. Comment by Sven on 30 Aug 2007 at 13:08
How to send unicode messages?
5. Comment by Benjamin Stein on 30 Aug 2007 at 13:08
Sven, you can’t really send unicode messages, at least here in the States. That is to say, most of the gateways don’t like them and most of the handsets can’t read them. Most can’t even support extended ASCII characters! At my company, we spend a lot of time filtering & transforming characters to make sure messages always get to the handset.
6. Comment by Piyush gupta on 11 Sep 2007 at 14:09
hi can anyone tell me some more links where i can get advanced knowledge abt the sms thing on rails some links or some pllication where they have used iit whats the pros and cons thank you mba.piyushgupta@gmail.com
7. Comment by Alex Egg on 18 Sep 2007 at 09:09
Why are you using this API? Why not just send the emails to the devices?
8. Comment by Luke Redpath on 18 Sep 2007 at 11:09
Alex, I don’t really understand what you’re asking? Are you suggesting sending email instead of an SMS? What does that have to do with anything?
9. Comment by Philippe Creytens on 18 Sep 2007 at 15:09
Hi Like your gem but when I use the $sms command with the ~/.clickatell file on Mac, there seems to be an issue. It returns an error ‘the API key cannot be parsed’. When I use $sms with all the arguments -u, -p, -k it seems to work.
I had a quick peek at the code in the gem and it seems that there is some confusing reading the .clickatell file related to the key being named ‘api_key’ while the code states ‘api_id’. Something to look into and update the gem?
—PC
10. Comment by Luke Redpath on 18 Sep 2007 at 15:09
Thanks for the comments – the key in the .clickatell file should definitely be api_key – certainly a documentation issue to look at, thanks.
11. Comment by ernest T on 24 Sep 2007 at 18:09
hi everyone, i’m new to ruby on rails. but my current project need to have sms feature. i found this website is great.
but i have a doubt, that is ” First of all, lets create a simple wrapper around the Clickatell API which will act as our “resource” ….. “
where exactly i should create this “wrapper” ? i’m kind of confused. can anyone guide me in details?
your help is much appreciated.
12. Comment by Luke Redpath on 24 Sep 2007 at 21:09
Hi ernest, you should create this in your app/models directory.
13. Comment by ernest T on 25 Sep 2007 at 13:09
thanks for it, Luke. it helps a lot.. by the way, i got another problem now. after i press the send button, i didn’t received the message and my account’s credit stay same… but i have double checked my api_key, username and password. nothing is wrong… do you know what is the error?
thanks in advance
14. Comment by Matthew on 27 Sep 2007 at 10:09
Awesome post! I was also wondering which SMS gateway to go for with my side project app
15. Comment by Matthew on 27 Sep 2007 at 10:09
I have been looking at the api, any chance of seeing support for the Two-Way SMS Messaging service from them too? Receiving SMS would be cool.