Skip to content
This repository has been archived by the owner on Feb 28, 2018. It is now read-only.

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelansel committed Jul 13, 2009
0 parents commit 2bdb8ed
Show file tree
Hide file tree
Showing 12 changed files with 1,724 additions and 0 deletions.
19 changes: 19 additions & 0 deletions config.ru
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
22 changes: 22 additions & 0 deletions config/database.yml
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
154 changes: 154 additions & 0 deletions demos/call_simulator.rb
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
179 changes: 179 additions & 0 deletions demos/call_simulator/main.css
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 ***/
Loading

0 comments on commit 2bdb8ed

Please sign in to comment.