-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathapp.rb
214 lines (183 loc) · 10.8 KB
/
app.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
require 'rubygems'
require 'bundler'
require 'open-uri'
Bundler.require
# Load configuration file with Sintra::Contrib helper (http://www.sinatrarb.com/contrib/)
config_file 'config.yml'
# Load some helper methods from helpers.rb
require './helpers.rb'
# To manage the web session coookies
use Rack::Session::Pool
# Setup Gabba, a server-side Google Analytics gem
G = Gabba::Gabba.new(ENV["GOOGLE_ANALYTICS_ID"], ENV["GOOGLE_ANALYTICS_DOMAIN"]) unless ENV["GOOGLE_ANALYTICS_DOMAIN"].nil?
# Setup Ohanakapa, the Ruby wrapper for the Ohana API
Ohanakapa.configure do |c|
c.api_token = ENV["OHANA_API_KEY"]
end
before do
G.page_view(request.path.to_s,request.path.to_s) if defined?(G)
end
# Resource called by the Tropo WebAPI URL setting
post '/index.json' do
# Fetches the HTTP Body (the session) of the POST and parse it into a native Ruby Hash object
v = Tropo::Generator.parse request.env["rack.input"].read
# Fetching certain variables from the resulting Ruby Hash of the session details
# into Sinatra/HTTP sessions; this can then be used in the subsequent calls to the
# Sinatra application
session[:network] = v[:session][:to][:network].upcase
session[:channel] = v[:session][:to][:channel].upcase
if defined?(G)
G.set_custom_var(1, 'caller', v[:session][:from].values.join("|").to_s, Gabba::Gabba::VISITOR)
G.set_custom_var(2, 'called', v[:session][:to].values.join("|").to_s, Gabba::Gabba::VISITOR)
G.set_custom_var(3, 'session_id', v[:session][:session_id], Gabba::Gabba::VISITOR)
G.set_custom_var(4, 'network', session[:network].to_s, Gabba::Gabba::VISITOR)
G.set_custom_var(5, 'channel', session[:channel].to_s, Gabba::Gabba::VISITOR)
end
# Create a Tropo::Generator object which is used to build the resulting JSON response
t = Tropo::Generator.new
t.voice = settings.tropo_tts["voice"]
# If there is Initial Text available, we know this is an IM/SMS/Twitter session and not voice
if v[:session][:initial_text]
# Set a session variable with the zip the user sent when they sent the IM/SMS/Twitter request
session[:zip] = v[:session][:initial_text]
t.ask :name => '0', :say => {:value => ""}, :choices => {:value => "[ANY]"}
else
# If this is a voice session, then add a voice-oriented ask to the JSON response with the appropriate options
t.ask :name => 'zip', :bargein => true, :timeout => settings.tropo_tts["timeout_for_#{session[:channel]}"], :interdigitTimeout => settings.tropo_tts["interdigitTimeout_for_#{session[:channel]}"],
:attempts => 3,
:say => [{:event => "timeout", :value => say_str("Sorry, I did not hear anything.")},
{:event => "nomatch:1 nomatch:2 nomatch:3", :value => say_str("Oops, that wasn't a five-digit zip code.")},
{:value => say_str("To search for Ohana resources in your area, please enter or say your 5 digit zip code.")}],
:choices => { :value => "[5 DIGITS]"}
end
# Add a 'hangup' to the JSON response and set which resource to go to if a Hangup event occurs on Tropo
t.on :event => 'hangup', :next => '/hangup.json'
# Add an 'on' to the JSON response and set which resource to go when the 'ask' is done executing
t.on :event => 'continue', :next => '/process_zip.json'
# Return the JSON response via HTTP to Tropo
t.response
end
# The next step in the session is posted to this resource when the 'ask' is completed in 'index.json'
post '/process_zip.json' do
# Fetch the HTTP Body (the session) of the POST and parse it into a native Ruby Hash object
v = Tropo::Generator.parse request.env["rack.input"].read
# Create a Tropo::Generator object which is used to build the resulting JSON response
t = Tropo::Generator.new
t.voice = settings.tropo_tts["voice"]
# If no intial text was captured, use the zip in response to the ask in the previous route
unless session[:zip]
if v[:result][:actions][:zip]
session[:zip] = v[:result][:actions][:zip][:value].gsub(" ","")
else
end
end
# debug
# t.say say_str("You entered #{session[:zip]}")
session[:kind] = "food" # hard coded for now, will abstract later
session[:data] = Ohanakapa.search("search", :keyword => session[:kind], :location => session[:zip])
G.event("Location", "#{session[:kind]}LookupByZip", session[:zip].to_s) if defined?(G)
if session[:data].size > 0
session[:data] = session[:data][0..8] if session[:data].size > 9 # limit to first 9 results
t.say say_str("Here are #{session[:data].size} resources in your area. Press or key in the resource number you want more information about.")
# Add an 'ask' to the JSON response and list the resources to the user in the form of a question. The selected opportunity will be handled in the next route.
t.ask :name => 'selection', :bargein => true, :timeout => settings.tropo_tts["timeout_for_#{session[:channel]}"], :interdigitTimeout => settings.tropo_tts["interdigitTimeout_for_#{session[:channel]}"],
:attempts => 3,
:say => [{:event => "nomatch:1", :value => say_str("That wasn't a one-digit resource number. Here are your choices: ")},
{:value => say_str(construct_list_of_items,"-10%")}], :choices => { :value => "[1 DIGITS]"}
else
# Add a 'say' to the JSON response and hangip the call
t.say say_str("Sorry, but we did not find any resources found in that zip code.")
t.hangup
end
t.on :event => 'continue', :next => '/process_selection.json'
t.on :event => 'hangup', :next => '/hangup.json'
t.response
end
# The next step in the session is posted to this resource when the 'ask' is completed in 'process_zip.json'
post '/process_selection.json' do
v = Tropo::Generator.parse request.env["rack.input"].read
t = Tropo::Generator.new
t.voice = settings.tropo_tts["voice"]
# If we have a valid response from the last ask, do this section
if v[:result][:actions][:selection][:value]
G.event("LocationDetails", "ItemDetails", "ItemNumber", v[:result][:actions][:selection][:value].to_s, true) if defined?(G)
item = session[:data][v[:result][:actions][:selection][:value].to_i-1]
session[:chosen_item_say_string_VOICE] = construct_details_of_item(item,"VOICE")
session[:chosen_item_say_string_TEXT] = construct_details_of_item(item,"TEXT")
if session[:channel] == "VOICE"
t.say say_str(session[:chosen_item_say_string_VOICE], "-10%")
else
t.say session[:chosen_item_say_string_TEXT]
end
# If the user is using voice, ask them if they would like an SMS sent to them
if session[:channel] == "VOICE"
t.ask :name => 'send_sms', :bargein => true, :timeout => settings.tropo_tts["timeout_for_#{session[:channel]}"], :interdigitTimeout => settings.tropo_tts["interdigitTimeout_for_#{session[:channel]}"],
:attempts => 3,
:say => [{:event => "nomatch:1 nomatch:2 nomatch:3", :value => say_str("That wasn't a valid answer.")},
{:value => say_str("Would you like to have a text message sent to you with this information? Press 1 or say 'yes' to receive a text message; press 2 or say 'no' to conclude this session.")}],
:choices => { :value => "true(1,yes), false(2,no)"}
next_url = '/send_text_message.json'
end
else
t.say say_str("Sorry, but I could not find a resource with that value. Please try again.")
t.hangup
end
next_url = '/goodbye.json' if next_url.nil?
t.on :event => 'continue', :next => next_url
t.on :event => 'hangup', :next => '/hangup.json'
t.response
end
# The next step in the session is posted to this resource when the 'ask' is completed in 'process_selection.json'
post '/send_text_message.json' do
# Fetch the HTTP Body (the session) of the POST and parse it into a native Ruby Hash object
v = Tropo::Generator.parse request.env["rack.input"].read
# Create a Tropo::Generator object which is used to build the resulting JSON response
t = Tropo::Generator.new
t.voice = settings.tropo_tts["voice"]
if v[:result][:actions][:number_to_text] # The caller provided a phone # to text message
t.message({
:to => v[:result][:actions][:number_to_text][:value],
:network => "SMS",
:say => {:value => session[:say_string_TEXT]
}})
t.say say_str("Your text message is on its way.")
else # We dont have a number, so either ask for it if they selected to send a text message, or send to goodbye.json
if v[:result][:actions][:send_sms][:value] == "true"
t.ask :name => 'number_to_text', :bargein => true, :timeout => settings.tropo_tts["timeout_for_#{session[:channel]}"], :interdigitTimeout => settings.tropo_tts["interdigitTimeout_for_#{session[:channel]}"],
:required => false, :attempts => 3,
:say => [{:event => "timeout", :value => say_str("Sorry, I did not hear anything.")},
{:event => "nomatch:1 nomatch:2 nomatch:3", :value => say_str("Oops, that wasn't a 10-digit number.")},
{:value => say_str("What 10-digit phone number would you like to send the information to?")}],
:choices => { :value => "[10 DIGITS]"}
next_url = '/send_text_message.json'
end # No need for an else, send them off to /goodbye.json
end
next_url = '/goodbye.json' if next_url.nil?
t.on :event => 'continue', :next => next_url
t.on :event => 'hangup', :next => '/hangup.json'
# Return the JSON response via HTTP to Tropo
t.response
end
# The next step in the session is posted to this resource when the 'ask' is completed in 'send_text_message.json'
post '/goodbye.json' do
# Fetch the HTTP Body (the session) of the POST and parse it into a native Ruby Hash object
v = Tropo::Generator.parse request.env["rack.input"].read
# Create a Tropo::Generator object which is used to build the resulting JSON response
t = Tropo::Generator.new
t.voice = settings.tropo_tts["voice"]
if session[:channel] == "VOICE"
t.say say_str("That's all. This service provided by social health insights dot com, data by ohana a p i dot org. Have a nice day. Goodbye.")
else # For text users, we can give them a URL (most clients will make the links clickable)
t.say "That's all. This service by http://SocialHealthInsights.com; data by http://ohanaapi.org"
end
t.hangup
# Add a 'hangup' to the JSON response and set which resource to go to if a Hangup event occurs on Tropo
t.on :event => 'hangup', :next => '/hangup.json'
t.response
end
# The next step in the session is posted to this resource when any of the resources do a hangup
post '/hangup.json' do
v = Tropo::Generator.parse request.env["rack.input"].read
G.event("OhanaSMS", "Hangup", "Duration", v[:result][:session_duration].to_s) if defined?(G)
puts " Call complete (CDR received). Call duration: #{v[:result][:session_duration]} second(s)"
end