I’ve wanted to play with the Twilio client for a while. They have this great quick start but it’s written in PHP. Now I don’t mind PHP, but I prefer Ruby. If I’m going to write anything using the client, it’s going to be in Ruby, so I don’t see the point in learning it on PHP.
So, here is the meat of the quickstart done up as a Rails 3.1 application.
First, generate the application.
$ rails new twilio
create
create README
create Rakefile
create config.ru
create .gitignore
create Gemfile
create app
...
This creates a new Rails 3.1 app in the current directory called twilio. Change to this directory, and add a line to your Gemfile:
gem 'twilio-ruby'
Run bundle install to add the official Twilio gem to your bundle.
Next, head on over to your Twilio account and get your SID and auth token. Those can go in an initializer, config/initializers/twilio.rb:
TwilioAccountSID="AC........"
TwilioAuthToken="......."
Those are the magic tokens that let you authenticate yourself to the Twilio API, and more importantly for them, let them bill you.
Next, head on over to app/helpers/application_helper.rb:
module ApplicationHelper
def twilio_javascript_include_tag
javascript_include_tag "http://static.twilio.com/libs/twiliojs/1.0/twilio.min.js"
end
end
Then in app/views/layouts/application.html.erb add that helper in the head:
Yea, you could have put the code right in the layout, but I like sparse layout files.
Next up, create a controller:
$ rails generate controller client index
create app/controllers/client_controller.rb
route get "client/index"
invoke erb
create app/views/client
create app/views/client/index.html.erb
invoke test_unit
create test/functional/client_controller_test.rb
invoke helper
create app/helpers/client_helper.rb
invoke test_unit
create test/unit/helpers/client_helper_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/client.js.coffee
invoke scss
create app/assets/stylesheets/client.css.scss
Then add root :to => ‘client#index’ to config/routes.rb so that your new view is displayed in the root url.
Run rails server or whatever you do to start your dev instance and browse to it. You should get the usual “find me in app/views/client/index.html.erb” message. Check the headers to make sure the library is being installed. The rest of the examples then deal with app/views/client/index.html.erb and app/helpers/client_helper.rb.
For the first example you want:
Helper:
module ClientHelper
def twilio_token
capability = Twilio::Util::Capability.new TwilioAccountSID, TwilioAuthToken
capability.allow_client_outgoing "APabe7650f654fc34655fc81ae71caa3ff"
capability.generate
end
end
View:
function call() {
Twilio.Device.connect();
}
function hangup() {
Twilio.Device.disconnectAll();
}
$(function() {
Twilio.Device.setup("");
Twilio.Device.ready(function (device) {
$("#log").text("Ready");
});
Twilio.Device.error(function (error) {
$("#log").text("Error: " + error.message);
});
Twilio.Device.connect(function (conn) {
$("#log").text("Successfully established call");
});
});
<button class="call" onclick="call();">
Call
</button>
For the second example, you just change the view.
function call() {
Twilio.Device.connect();
}
function hangup() {
Twilio.Device.disconnectAll();
}
$(function() {
Twilio.Device.setup("");
Twilio.Device.ready(function (device) {
$("#log").text("Ready");
});
Twilio.Device.error(function (error) {
$("#log").text("Error: " + error.message);
});
Twilio.Device.disconnect(function (conn) {
$("#log").text("Call ended");
});
Twilio.Device.connect(function (conn) {
$("#log").text("Successfully established call");
});
});
<button class="call" onclick="call();">
Call
</button>
<button class="hangup" onclick="hangup();">
Hangup
</button>
<div id="log">Loading pigeons...</div>
For the third example we’ll have to change the helper and the view accordingly:
app/helpers/client_helper.rb (note I’m using my own sandbox id. You get your own inside the Twilio account page!)
module ClientHelper
def twilio_token
capability = Twilio::Util::Capability.new TwilioAccountSID, TwilioAuthToken
capability.allow_client_outgoing "AP..."
capability.allow_client_incoming 'jenny'
capability.generate
end
end
app/views/client/index.html.erb
%= javascript_tag do %>
function call() {
Twilio.Device.connect();
}
function hangup() {
Twilio.Device.disconnectAll();
}
$(function() {
Twilio.Device.setup("");
Twilio.Device.ready(function (device) {
$("#log").text("Ready");
});
Twilio.Device.error(function (error) {
$("#log").text("Error: " + error.message);
});
Twilio.Device.disconnect(function (conn) {
$("#log").text("Call ended");
});
Twilio.Device.connect(function (conn) {
$("#log").text("Successfully established call");
});
Twilio.Device.incoming(function (conn) {
$("#log").text("Incoming connection from " + conn.parameters.From);
// accept the incoming connection and start two-way audio
conn.accept();
});
});
<button class="call" onclick="call();">
Call
</button>
<button class="hangup" onclick="hangup();">
Hangup
</button>
<div id="log">Loading pigeons...</div>
Now, hook up a new action in the client controller to redirect the call from Twilio to the app inside app/controllers/client_controller.rb
def incoming
response = Twilio::TwiML::Response.new do |r|
r.Dial do |d|
d.Client 'jenny'
end
end
render :text => response.text
end
Don’t forget to add post “client/incoming” to config/routes.rb. Then point your sandbox URL to your dev box, such as http://yourhome.com:3000/client/incoming.xml.
As a bonus, here’s a rake task to log in to a remote host and set up an ssh tunnel on remote port 3000 to local port 3000:
namespace :tunnel do
desc "Start a ssh tunnel"
task :start => :environment do
public_host_username = "sean"
public_host = "home.ertw.com"
public_port = 3000
local_port = 3000
puts "Starting tunnel #{public_host}:#{public_port} \
to 127.0.0.1:#{local_port}"
exec "ssh -nNT -g -R *:#{public_port}:127.0.0.1:#{local_port} \
#{public_host_username}@#{public_host}"
end
end
There are two more examples in the quickstart, but as they are more of the same, I’ll leave them for another post. I’d also like to try rewriting the Javascript in Coffeescript.
Update – Code is at https://github.com/swalberg/twilio-client-ruby
a