Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Sample code for Twilio IVR Blog. Demonstrates how to create a run a simple IVR System.

View Call_Handler.rb (Build)
1 2 3 4 5 6 7 8 9 10
# We can use this to setup the database,
configure do
#Finalize and store our models.
DataMapper.finalize.auto_upgrade!
 
#Create some steps...
if Step.all.count == 0
Step.create_tree
end
end
View Call_Handler.rb (Build)
1 2 3
post '/fin' do
Metric.create(cid: params[:CallSid], state: params[:CallStatus])
end
View Call_Handler.rb (Build)
1 2 3 4
get '/metric' do
@metrics = Metric.all
#erb :metric, :layout => :main_layout
end
View Call_Handler.rb (Build)
1 2 3 4 5
require 'sinatra'
require 'data_mapper'
require 'twilio-ruby'
require './step'
require './metric'
View Call_Handler.rb (Build)
1 2 3 4 5
#Simple Page to show all the steps.
get '/' do
@steps = Step.all
erb :index, :layout => :main_layout
end
View Call_Handler.rb (Build)
1 2 3 4 5
post '/step' do
step = Step.first(:root => true)
Metric.create(cid: params[:CallSid], state: params[:CallStatus], step: step)
step.to_twiml
end
View Call_Handler.rb (Build)
1 2 3 4 5 6 7 8 9 10 11 12 13
#Get and render a step...
post '/step/:id' do
step = Step.get(params[:id])
#If we are responding to a DTMF sequence, we can simply swap out the current step, and proceed as before.
if params[:Digits] != nil
#We swap the step if the user has entered a keypress.
step = step.children.find {|option| option[:gather] == params[:Digits] }.action
end
 
Metric.create(cid: params[:CallSid], state: params[:CallStatus], step: step)
content_type 'text/xml'
step.to_twiml
end
View Call_Handler.rb (Build)
1 2 3 4 5 6
#Deletes everything to give a nice clean database...
get '/tank' do
Step.all.each{|step| step.destroy}
Metric.all.each{|metric| metric.destroy}
"DONE"
end
View Call_Handler.rb (Build)
1 2 3 4 5 6 7 8 9
source 'http://rubygems.org'
ruby '1.9.3'
gem 'sinatra'
gem 'thin'
gem 'twilio-ruby'
gem 'pg'
gem 'data_mapper'
gem 'dm-postgres-adapter'
gem 'dm-timestamps'
View Call_Handler.rb (Build)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#Just in case we reuse this elsewhere.
require 'data_mapper'
require 'twilio-ruby'
 
class Step
include DataMapper::Resource
property :id, Serial
property :say, String
property :sequence, Integer
property :gather, String
property :root, Boolean, :default => false
property :goal, Boolean, :default => true
belongs_to :parent, :model => Step, :required => false
has n, :children, :model => Step, :child_key => [ :parent_id ]
belongs_to :action, :model => Step, :required => false
end
View Call_Handler.rb (Build)
1 2 3 4 5 6 7 8 9
def self.create_tree
# Create the first varaint of steps...
topStep = Step.create(say: "Thank you for calling Twil'lio Owl Sanctuary.", sequence: 0, gather: nil, root: true)
owl_count = Step.create(say: "Thank you. We have 3 Owls. Three.", sequence: 0, gather: nil, goal: true)
operator = Step.create(say: "This is a demo, we don't really have an operator.", sequence: 0, gather: nil, goal: true)
Step.create(say: "To hear how many Owls we have, press 1.", parent: topStep, sequence: 0, gather: "1", action: owl_count)
Step.create(say: "To speak to an operator, press 2.", parent: topStep, sequence: 1, gather: "2", action: operator,)
 
end
View Call_Handler.rb (Build)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
def to_twiml
#If an error occurs here, the exception will cause Twilio to read out the 'An Application Error has Occured' message.
twiml = Twilio::TwiML::Response.new do |r|
 
r.Say say, :language => "en-gb", :voice => "alice"
 
if children.count > 0
r.Gather action: "/step/#{id}" do |gather|
children.each do |options|
gather.Say options.say, :language => "en-gb", :voice => "alice"
end
end
else
r.Say "Goodbye.", :language => "en-gb", :voice => "alice"
r.Hangup
end
end
twiml.text
end
View Call_Handler.rb (Build)
1 2
require './call_handler'
run Sinatra::Application
View Call_Handler.rb (Build)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<table>
<tr>
<th>ID</th>
<th>Say</th>
<th>Parent</th>
<th>Sequence</th>
<th>Gather</th>
<th>Action</th>
</tr>
<% @steps.each do |step| %>
<tr>
<td><%= step.id %></td>
<td><%= step.say %></td>
<td><%= step.parent.say if step.parent != nil %></td>
<td><%= step.sequence %></td>
<td><%= step.gather %></td>
<td><%= step.action.say if step.action != nil%></td>
<tr>
<% end %>
</table>
View Call_Handler.rb (Build)
1 2 3 4 5 6 7 8 9
<!doctype html>
<html>
<head>
<title>Twilio Demo App</title>
</head>
<body>
<%= yield %>
</body>
</html>
View Call_Handler.rb (Build)
1 2
<p>Total Calls: <%= @metrics.uniq{|metric| metric.cid}.count %></p>
<p>Total Completed Calls: <%= @metrics.select{|metric| metric.step != nil && metric.step.goal}.uniq{|metric| metric.cid}.count %></p>
View Call_Handler.rb (Build)
1 2 3 4 5 6 7 8 9 10 11 12
#Just in case we reuse this elsewhere.
require 'data_mapper'
require './step'
 
#A model to hold the call tree.
class Metric
include DataMapper::Resource
property :id, Serial
property :cid, String
property :state, String
belongs_to :step, :required => false
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.