Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark S committed Jan 27, 2010
1 parent a415612 commit bf9d141
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 0 deletions.
Binary file added call_flow.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions goodies.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require 'time'

# Helper to take out http[s]:// so Tropo TTS doesn't try to stream the URL as if it were an audio file.
# => Method by @Skram
def reformat_uris(text)
text.gsub(/https?:\/\//, "link to ")
end

# Helper to convert number to ordinal.
# Such as: 1 = "first", 2 = "second", 3 = "third", ... 99 = "ninety-ninth", and so on.
# => Method by @Skram
def say_as_ordinal(number)
"<?xml version='1.0' encoding='UTF-8'?><speak><say-as interpret-as='ordinal'>#{number}</say-as></speak>"
end


### Borrowed from 2nd answer on http://stackoverflow.com/questions/195740/how-do-you-do-relative-time-in-rails
### => Thanks MattW! - http://stackoverflow.com/users/4494/mattw
module PrettyDate
def to_pretty
a = (Time.now-self).to_i
case a
when 0 then return 'just now'
when 1 then return 'a second ago'
when 2..59 then return a.to_s+' seconds ago'
when 60..119 then return 'a minute ago' #120 = 2 minutes
when 120..3540 then return (a/60).to_i.to_s+' minutes ago'
when 3541..7100 then return 'an hour ago' # 3600 = 1 hour
when 7101..82800 then return ((a+99)/3600).to_i.to_s+' hours ago'
when 82801..172000 then return 'a day ago' # 86400 = 1 day
when 172001..518400 then return ((a+800)/(60*60*24)).to_i.to_s+' days ago'
when 518400..1036800 then return 'a week ago'
end
return ((a+180000)/(60*60*24*7)).to_i.to_s+' weeks ago'
end
end
Time.send :include, PrettyDate
84 changes: 84 additions & 0 deletions twitter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
%w(rubygems sinatra tropo-webapi-ruby/lib/tropo-webapi-ruby.rb pp open-uri rexml/document goodies.rb).each{|lib| require lib}
enable :sessions

post '/start.json' do
v = Tropo::Generator.parse request.env["rack.input"].read
session[:id] = v[:session][:id]
session[:caller] = v[:session][:from]
session[:user] = "voxeo"
session[:page] = 1 # This shouldn't be tinkered with unless you don't want the most recent tweets to be heard.
t = Tropo::Generator.new
t.on :event => 'continue', :next => '/process.json'
t.on :event => 'error', :next => '/error.json' # For fatal programming errors. Log some details so we can fix it
t.on :event => 'hangup', :next => '/hangup.json' # When a user hangs or call is done. We will want to log some details.
t.on :event => 'incomplete', :next => '/incomplete.json'
t.say "You have reached @#{session[:user]}'s tweets-by-phone."

t.ask :name => 'count', :bargein => true, :timeout => 7, :required => true, :attempts => 4,
:say => [{:event => "timeout", :value => "Sorry, I did not hear anything."},
{:event => "nomatch:1 nomatch:2 nomatch:3", :value => "That wasn't a one digit number."},
{:value => "How many tweets do you want to listen to at once? Enter or say a one digit number."},
{:event => "nomatch:3", :value => "This is your last attempt. Watch it."}],
:choices => { :value => "[1 DIGITS]"}
t.response
end

# NOTE, This incomplete event is not necessary.
# To be more user friendly, you can simply not define an incomplete action and
# validate input with Ruby logic inside the 'continue' event's document.
post '/incomplete.json' do
v = Tropo::Generator.parse request.env["rack.input"].read
t = Tropo::Generator.new
t.on :event => 'error', :next => '/error.json' # For fatal programming errors. Log some details so we can fix it
t.on :event => 'hangup', :next => '/hangup.json' # When a user hangs or call is done. We will want to log some details.
t.say "You failed to enter a valid number #{v[:result][:actions][:attempts]} times."
t.say "Please call back and try again or contact us for help."
t.hangup
t.response
end

post '/process.json' do
v = Tropo::Generator.parse request.env["rack.input"].read
t = Tropo::Generator.new
t.on :event => 'error', :next => '/error.json' # For fatal programming errors. Log some details so we can fix it
t.on :event => 'hangup', :next => '/hangup.json' # When a user hangs or call is done. We will want to log some details.
t.on :event => 'continue', :next => '/say_page_of_tweets.json'
session[:count] = v[:result][:actions][:count][:value]
# t.say "@#{session[:user]} tweets coming right up!"
t.response
end

post '/say_page_of_tweets.json' do
t = Tropo::Generator.new
t.on :event => 'error', :next => '/error.json' # For fatal programming errors. Log some details so we can fix it
t.on :event => 'hangup', :next => '/hangup.json' # When a user hangs or call is done. We will want to log some details.
t.on :event => 'continue', :next => '/say_page_of_tweets.json'
t.say "I'm about to read you the"
t.say say_as_ordinal(session[:page])
t.say " #{session[:count]} tweets by #{session[:user]}."
source = "http://twitter.com/statuses/user_timeline/#{session[:user]}.rss?count=#{session[:count]}&page=#{session[:page]}"
rss = REXML::Document.new(open(source).read).root
rss.root.elements.each("channel/item") { |element|
t.say "Tweet from about #{Time.parse(element.get_text('pubDate').to_s).to_pretty}"
t.say reformat_uris(element.get_text('title').to_s) + "," # comma for extra pause between tweets.
}
session[:page] += 1
t.response
end

post '/hangup.json' do
v = Tropo::Generator.parse request.env["rack.input"].read
if v[:result][:complete]
puts "Call complete. Call duration: #{v[:result][:call_duration]} second(s)"
else
puts "/!\\ Caller hung up. Call duration: #{v[:result][:call_duration]} second(s)."
end
puts " Caller info: ID=#{session[:caller][:id]}, Name=#{session[:caller][:name]}"
puts " Call logged in CDR. Tropo session ID: #{session[:id]}"
end

post '/error.json' do
v = Tropo::Generator.parse request.env["rack.input"].read
puts "!"*10 + "ERROR (see rack.input below); call ended"
pp v # Print the JSON to our Sinatra console/log so we can find the error
end

0 comments on commit bf9d141

Please sign in to comment.