This repository has been archived by the owner on Feb 28, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2bdb8ed
Showing
12 changed files
with
1,724 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# vim:set ft=ruby: # | ||
|
||
# Applications | ||
#require 'demos/hello_world' | ||
require 'demos/call_simulator' | ||
|
||
# Middleware | ||
require 'demos/twilio_auth' | ||
|
||
Twilio::AccountSid = TWILIO_ACCOUNT_SID = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' | ||
Twilio::AuthToken = TWILIO_AUTH_TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' | ||
DEFAULT_URL = 'http://demo.twilio.com/welcome' | ||
|
||
|
||
|
||
use Rack::TwilioAuth | ||
use Rack::Session::Cookie | ||
|
||
run Sinatra::Application |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# SQLite version 3.x | ||
# gem install sqlite3-ruby (not necessary on OS X Leopard) | ||
development: | ||
adapter: sqlite3 | ||
database: db/development.sqlite3 | ||
pool: 5 | ||
timeout: 5000 | ||
|
||
# Warning: The database defined as "test" will be erased and | ||
# re-generated from your development database when you run "rake". | ||
# Do not set this db to the same as development or production. | ||
test: | ||
adapter: sqlite3 | ||
database: db/test.sqlite3 | ||
pool: 5 | ||
timeout: 5000 | ||
|
||
production: | ||
adapter: sqlite3 | ||
database: production.sqlite3 | ||
pool: 10 | ||
timeout: 10000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
require 'sinatra' unless defined? Sinatra | ||
require 'twilio/call_handler' | ||
require 'twilio/verb' | ||
require 'builder' | ||
|
||
set :public, Proc.new { File.join(root, "call_simulator") } | ||
set :clean_trace, true | ||
set :lock, true | ||
|
||
def ns_get(matcher,&block) | ||
get(Regexp.new('^/call-sim/?'+matcher.to_s+'(\?.*)?$'), &block) | ||
end | ||
def ns_post(matcher,&block) | ||
post(Regexp.new('^/call-sim/?'+matcher.to_s+'(\?.*)?$'), &block) | ||
end | ||
|
||
ns_get "" do | ||
if not session[:call_handler] or session[:call_handler].phone.call_status == :completed | ||
session[:call_handler] = Twilio::CallHandler.new | ||
else | ||
puts "Triggering a hangup on page reload" | ||
session[:call_handler].hangup | ||
end | ||
|
||
ch = session[:call_handler] | ||
phone = ch.phone | ||
|
||
if params[:call_url] | ||
ch.call_url(params[:call_url]) | ||
else | ||
ch.call_url(DEFAULT_URL) | ||
end | ||
|
||
output = "" | ||
xml = Builder::XmlMarkup.new(:indent => 2, :target => output) | ||
xml.instruct! | ||
xml.declare!(:DOCTYPE, :html, :PUBLIC, "-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd") | ||
|
||
xml.html(:xmlns=>'http://www.w3.org/1999/xhtml', "xml:lang" => "en") do |xml| | ||
xml.head do |xml| | ||
xml.script(:type => "text/javascript", :src => "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js") {} | ||
xml.script(:type => "text/javascript", :src => "/main.js") {} | ||
xml.link(:type => "text/css", :rel => "stylesheet", :href => "/main.css") | ||
end | ||
xml.body do |xml| | ||
xml.div(:id => "left-sidebar", :class => "sidebar") do |xml| | ||
xml.form(:id => "call_url", :onsubmit => "ajax_call('call_url'); return false;") do |xml| | ||
xml.input(:id => 'url', :name => "call_url", :value => "Callback URL"); | ||
xml.button("Call", :type => "submit")#, :onclick => "ajax_call('call_url')") | ||
end | ||
xml.div(:id => 'quick_call_links') do |xml| | ||
[ ["Twilio Welcome", "http://demo.twilio.com/welcome" ], | ||
["Naglio Status", "http://naglio.datadrop.biz/phone_calls/status" ], | ||
["DukeNow", "http://dukenow-test.heroku.com/twilio/" ], | ||
["TalkingTexts Inbox", "http://talkingtexts.datadrop.biz/text_messages/inbox/1.xml" ], | ||
["Earth911 Search", "http://search.earth911.com/voice/what/?failures=0" ], | ||
["Pause Test", "http://dreamhost.anselcomputers.com/pause_test.xml" ], | ||
["Twilio Hello World", "http://demo.twilio.com/helloworld/index.xml" ], | ||
["Monkey Demo", "http://dreamhost.anselcomputers.com/hello-monkey.php" ] | ||
].each do |name,url| | ||
xml.a(name, :href => '#quick_call', :onclick => "$('form#call_url')[0].url.value = #{url.inspect}; ajax_call('call_url'); return false;") | ||
xml.br | ||
end | ||
end | ||
end | ||
xml.div(:id => "right-sidebar", :class => "sidebar") do |xml| | ||
xml.button("Hangup", :id => "hangup", :onclick => "ajax_call('hangup'); return false;"); | ||
|
||
xml.div(:id => "countdown", :style => "display:none") {} | ||
xml.div(:id => "gather_box", :style => "display:none") do |xml| | ||
xml.button("Timeout", :id => "gather_timeout", :onclick => "ajax_call('gather_timeout'); return false;") | ||
xml.div(:id => "gather_keypad") do |xml| | ||
[[1,2,3],[4,5,6],[7,8,9],%w{* 0 #}].each do |row| | ||
xml.div(:class => "gather_key_row") do |xml| | ||
row.each do |key| | ||
xml.a(key, :class => "gather_key", :href => "#press_digit=#{key}", :onclick => "ajax_call('press_digit', {digit: #{key}}); return false;") | ||
end | ||
end | ||
end | ||
end | ||
end | ||
xml.div(:id => "record_box", :style => "display:none") do |xml| | ||
xml.button("Timeout", :id => "record_timeout", :onclick => "ajax_call('record_timeout'); return false;") | ||
end | ||
end | ||
xml.button("Toggle Auto-Refresh", :id => "auto_refresh_button", :onclick => "toggle_auto_update_call_flow()") | ||
xml.div(:id => "call_flow") do |xml| | ||
xml.div("Call Flow", :class => "call_flow_header") | ||
end | ||
end | ||
end | ||
|
||
output | ||
end | ||
|
||
ns_get "/ajax" do | ||
if session[:call_handler].nil? | ||
# Reset/Reload page to generate a new session | ||
return [{:status => false, :method => :reload_page, :params => true}].to_json | ||
return "<script type='text/javascript'> | ||
//<![CDATA[ | ||
window.location = window.location; | ||
//]]> </script>" | ||
end | ||
|
||
|
||
ch = session[:call_handler] | ||
phone = ch.phone | ||
|
||
case params[:action].downcase | ||
when 'next' | ||
#puts "Processing CallHandler queue all the way through" | ||
true until ch.process_queue.nil? | ||
#puts "Processing Phone queue all the way through" | ||
reply = []; h = {:status => true} | ||
until( h[:noop] or not h[:status] ) do | ||
h = phone.listen | ||
s = h[:status] | ||
m = (h.keys - [:status])[0] | ||
reply << { :status => s, :method => m, :params => h[m]} | ||
reply.delete_if{|a| a[:method] == :noop } | ||
end | ||
puts "Replying with:\n#{reply.to_yaml}" unless reply == [] | ||
return reply.to_json | ||
when 'call_url' | ||
puts "Triggering a hangup so we can make another call" | ||
ch.hangup | ||
ch = session[:call_handler] = Twilio::CallHandler.new | ||
ch.call_url(params[:url]) | ||
return [{:status => true, :method => :notify, :params => "Resetting any previous calls"}, | ||
{:status => false, :method => :call_completed, :params => true}, | ||
{:status => true, :method => :toggle_auto_update_call_flow, :params => true}].to_json | ||
when 'press_digit' | ||
accepted = ch.press_digit(params[:digit]) ? "Key press accepted" : "Key press REJECTED!" | ||
reply = [{:status => true, :method => :notify, :params => accepted}] | ||
puts "Replying with:\n#{reply.to_yaml}" unless reply == [] | ||
return reply.to_json | ||
when 'gather_timeout' | ||
ch.gather_timeout | ||
when 'record_timeout' | ||
ch.record_timeout | ||
when 'hangup' | ||
session[:call_handler] = Twilio::CallHandler.new | ||
puts "Triggering a hangup due to AJAX request" | ||
ch.hangup | ||
return [{:status => false, :method => :call_completed, :params => true}].to_json | ||
return "<script type='text/javascript'> | ||
//<![CDATA[ | ||
call_completed(); | ||
//]]> </script>" | ||
end | ||
|
||
"" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
/*** Control Panel ***/ | ||
.sidebar { | ||
position: fixed; | ||
display:block; | ||
top:0; width: 250px; | ||
margin-top: 10px; | ||
} | ||
.sidebar a,button { | ||
outline: 0; | ||
} | ||
#left-sidebar { left:0; margin-left: 10px; } | ||
#right-sidebar { right:0; margin-right: 10px; } | ||
|
||
.sidebar button { | ||
width: 100%; | ||
font-size: 2.5em; | ||
} | ||
|
||
/** Left Sidebar **/ | ||
#call_url #url { | ||
font-size: 1.5em; | ||
width: 500px; | ||
z-index: 1; | ||
} | ||
#quick_call_links > br { display: none; } | ||
#quick_call_links > a { | ||
display: block; | ||
font-size: 1.5em; | ||
line-height: 1.75em; | ||
|
||
margin-top: 10px; | ||
|
||
padding: 5px; | ||
padding-left: 10px; | ||
padding-right: 10px; | ||
white-space: nowrap; | ||
overflow: hidden; | ||
|
||
|
||
border: 1px solid black; | ||
-moz-border-radius: 5px; | ||
-webkit-border-radius: 5px; | ||
|
||
color: black; | ||
text-decoration: none; | ||
} | ||
#quick_call_links > a:hover { | ||
background-color: #E0E0E0; | ||
} | ||
/** End Left Sidebar **/ | ||
|
||
|
||
/** Right Sidebar **/ | ||
#hangup { | ||
} | ||
#countdown { | ||
line-height:2em; | ||
margin:auto 0; | ||
min-height:2em; | ||
min-width:2em; | ||
text-align:center; | ||
font-size:5em; | ||
background-color:pink; | ||
} | ||
#gather_box { | ||
width: 100%; | ||
border: 1px solid black; | ||
} | ||
#gather_timeout { | ||
width: 100%; | ||
padding: 5px 0; | ||
} | ||
#gather_keypad { | ||
width: 100%; | ||
display: table; | ||
table-layout: fixed; | ||
} | ||
.gather_key_row { | ||
display: table-row; | ||
} | ||
.gather_key { | ||
display: table-cell; | ||
font-size: 3.0em; | ||
text-align: center; | ||
text-decoration: none; | ||
color: black; | ||
} | ||
.gather_key:hover { | ||
background-color: #E0E0E0; | ||
} | ||
/** End Right Sidebar **/ | ||
|
||
/*** End Control Panel ***/ | ||
|
||
body { | ||
margin: 0; | ||
padding: 2.0em 10px 10px 10px; | ||
} | ||
|
||
|
||
/*** Call Flow Elements ***/ | ||
#call_flow { | ||
position: relative; | ||
margin: 0 auto; | ||
width: 940px; | ||
-moz-border-radius-topleft: 40px; | ||
-moz-border-radius-topright: 40px; | ||
-webkit-border-top-left-radius: 40px; | ||
-webkit-border-top-right-radius: 40px; | ||
background-color: #E0E0E0; | ||
padding: 20px; | ||
} | ||
button#auto_refresh_button { | ||
position: fixed; | ||
left: 0; right: 0; top: 0; | ||
width: 500px; | ||
margin: 0 auto; | ||
z-index: 1; | ||
font-size: 2.0em; | ||
|
||
} | ||
.call_flow_header { | ||
font-weight: bold; | ||
font-size: 2.0em; | ||
text-align: center; | ||
} | ||
|
||
#call_flow > div { | ||
margin-top: 10px; | ||
} | ||
.say { | ||
width: 50%; | ||
margin-left: auto; | ||
padding: 10px; | ||
|
||
-moz-border-radius: 10px; | ||
-webkit-border-radius: 10px; | ||
background-color: #D7F5FF; | ||
|
||
font-size: 1.5em; | ||
} | ||
.say span { | ||
display: block; | ||
margin-left: 1em; | ||
text-indent: -1em; | ||
} | ||
.gather, .pause { | ||
padding: 10px; | ||
|
||
-moz-border-radius: 10px; | ||
-webkit-border-radius: 10px; | ||
background-color: #FF855C; | ||
|
||
font-size: 1.3em; | ||
} | ||
.notify { | ||
display: inline-block; | ||
padding: 10px; | ||
margin-right: 25%; | ||
|
||
-moz-border-radius: 10px; | ||
-webkit-border-radius: 10px; | ||
background-color: #90FF6B; | ||
} | ||
.twiml { | ||
display: block; | ||
white-space: pre; | ||
font-family: monospace; | ||
padding: 20px; | ||
-moz-border-radius: 10px; | ||
-webkit-border-radius: 10px; | ||
background-color:#FFFD7F; | ||
} | ||
.call-divider { | ||
width:100%; height:10px; | ||
margin: 5px 0; | ||
background-color:gray; | ||
} | ||
/*** End Call Flow Elements ***/ |
Oops, something went wrong.