tropo-webapi-ruby 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +24 -0
- data/.yardoc +0 -0
- data/HISTORY.rdoc +5 -0
- data/LICENSE +21 -0
- data/README.rdoc +192 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/examples/sinatra_server.rb +193 -0
- data/lib/tropo-webapi-ruby.rb +6 -0
- data/lib/tropo-webapi-ruby/tropo-webapi-ruby-helpers.rb +228 -0
- data/lib/tropo-webapi-ruby/tropo-webapi-ruby.rb +438 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/tropo-webapi-ruby_spec.rb +444 -0
- data/tropo-webapi-ruby.gemspec +64 -0
- metadata +92 -0
@@ -0,0 +1,228 @@
|
|
1
|
+
module Tropo
|
2
|
+
module Helpers
|
3
|
+
private
|
4
|
+
|
5
|
+
##
|
6
|
+
# Method checks for presence of required elements and then builds the action
|
7
|
+
#
|
8
|
+
# @param [String] the name of the action to build
|
9
|
+
# @param [Hash] the elements to be used to build the action
|
10
|
+
# @return [Hash] provides the properply built hash for the action
|
11
|
+
def build_action(action, params)
|
12
|
+
raise ArgumentError, 'Action requires parameters' if params.nil?
|
13
|
+
|
14
|
+
case action
|
15
|
+
when 'ask'
|
16
|
+
has_params?(params, 'ask', 'name')
|
17
|
+
when 'choices'
|
18
|
+
if params[:mode]
|
19
|
+
if params[:mode] != 'dtmf' && params[:mode] != 'speech'
|
20
|
+
raise ArgumentError, "If mode is provided, only 'dtmf', 'speech' or 'any' is supported"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
when 'conference'
|
24
|
+
has_params?(params, 'conference', ['name', 'id'])
|
25
|
+
when 'on'
|
26
|
+
has_params?(params, 'on', 'event')
|
27
|
+
when 'record'
|
28
|
+
has_params?(params, 'record', ['name', 'url'])
|
29
|
+
when 'start_recording'
|
30
|
+
has_params?(params, 'start_recording', ['name', 'url'])
|
31
|
+
|
32
|
+
# Camelcase this one to be Java friendly
|
33
|
+
action = 'startRecording'
|
34
|
+
when 'redirect'
|
35
|
+
has_params?(params, 'redirect', 'to')
|
36
|
+
raise ArgumentError, "Redirect should only be used alone and before the session is answered, use transfer instead" if @nested_hash
|
37
|
+
when 'say'
|
38
|
+
has_params?(params, 'say', 'value')
|
39
|
+
return build_elements(params)
|
40
|
+
when 'transfer'
|
41
|
+
has_params?(params, 'transfer', 'to')
|
42
|
+
end
|
43
|
+
|
44
|
+
if action == 'on'
|
45
|
+
build_elements(params)
|
46
|
+
else
|
47
|
+
{ action.to_sym => build_elements(params) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Checks to see if certain parameters are present, and if not raises an error
|
53
|
+
#
|
54
|
+
# @overload has_params?(params, action, names)
|
55
|
+
# @param [Hash] the parameter hash to be checked for the presence of a parameter
|
56
|
+
# @param [String] the action being checked
|
57
|
+
# @param [String] the name of the key in the params that must be present
|
58
|
+
# @overload has_params?(params, action, names)
|
59
|
+
# @param [Hash] the parameter hash to be checked for the presence of a parameter
|
60
|
+
# @param [String] the action being checked
|
61
|
+
# @param [Array] a list of names of the keys in the params that must be present
|
62
|
+
def has_params?(params, action, names)
|
63
|
+
if names.kind_of? Array
|
64
|
+
names.each { |name| raise ArgumentError, "A '#{name}' must be provided to a '#{action}' action" if params[name.to_sym].nil? }
|
65
|
+
else
|
66
|
+
raise ArgumentError, "A '#{names}' must be provided to a '#{action}' action" if params[names.to_sym].nil?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Takes a Ruby underscore string and converts to a Java friendly camelized string
|
71
|
+
#
|
72
|
+
# @param [String] the string to be camelized
|
73
|
+
# @return [String] the Ruby string camelized
|
74
|
+
def camelize(ruby_string)
|
75
|
+
split_string = ruby_string.split('_')
|
76
|
+
split_string[0] + split_string[1].capitalize
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Creates a nested hash when we have block within a block
|
81
|
+
#
|
82
|
+
# @param [String] the name of the action being built
|
83
|
+
# @param [Hash] the parameters to be added to the action
|
84
|
+
# @return [nil]
|
85
|
+
def create_nested_hash(name, params)
|
86
|
+
@nested_hash = build_action(name, params)
|
87
|
+
@nested_name = name
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Creates a nested hash specfic to 'on', as an on may have an additional block
|
92
|
+
#
|
93
|
+
# @param [Hash] the parameters to be added to the instance of the 'on' action
|
94
|
+
# @return [nil]
|
95
|
+
def create_nested_on_hash(params)
|
96
|
+
@nested_on_hash ||= { :on => Array.new }
|
97
|
+
@nested_on_hash_cnt ||= 0
|
98
|
+
@nested_on_hash[:on] << params
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# Creates an on_hash for the on action
|
103
|
+
#
|
104
|
+
# @return [nil]
|
105
|
+
def create_on_hash
|
106
|
+
@on_hash ||= { :on => Array.new }
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Method builds the elements for each of the actions
|
111
|
+
#
|
112
|
+
# @param [Hash] the individual elements to be used to build the hash
|
113
|
+
# @return [Hash] returns the elements properly formatted in a hash
|
114
|
+
def build_elements(params)
|
115
|
+
if params[:url]
|
116
|
+
uri = URI.parse params[:url]
|
117
|
+
# Check to see if it is a valid http address
|
118
|
+
if uri.class != URI::HTTP
|
119
|
+
# Check to see if it is a valid email address
|
120
|
+
if params[:url].match(/^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/) == false
|
121
|
+
raise ArgumentError, "The 'url' paramater must be a valid URL"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
hash = Hash.new
|
127
|
+
params.each_pair do |k,v|
|
128
|
+
if k.to_s.include? "_"
|
129
|
+
k = camelize k.to_s
|
130
|
+
k = k.to_sym
|
131
|
+
end
|
132
|
+
hash.merge!({ k => v })
|
133
|
+
end
|
134
|
+
hash
|
135
|
+
end
|
136
|
+
|
137
|
+
##
|
138
|
+
# Takes a Java Camelized string and converts to an underscore string
|
139
|
+
#
|
140
|
+
# @param [String] the string to be de-camelized
|
141
|
+
# @return [String] the Ruby string with an underscore and no capitals
|
142
|
+
def decamelize(camel_string)
|
143
|
+
camel_string.gsub(/[A-Z]/) { |char| '_' + char.downcase }
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Formats the @response instance variable to JSON before making it available to the accessor
|
148
|
+
#
|
149
|
+
# @return [nil]`
|
150
|
+
def render_response
|
151
|
+
@response.to_json
|
152
|
+
end
|
153
|
+
|
154
|
+
##
|
155
|
+
# Returns an hash from a collapsed array, using the values of 'key' or 'name' as the collpassed hash key
|
156
|
+
#
|
157
|
+
# @param [Array] the array of values to collapse into a Hash
|
158
|
+
# @return [Hash] the collapsed Hash
|
159
|
+
def transform_array(array)
|
160
|
+
transformed_to_hash = Hash.new
|
161
|
+
|
162
|
+
array.each_with_index do |ele, i|
|
163
|
+
# Set the key to the value of the respresentative key
|
164
|
+
key = ele['key'].to_sym if ele['key']
|
165
|
+
key = ele['name'].to_sym if ele['name']
|
166
|
+
|
167
|
+
# Merge this new key into the hash
|
168
|
+
transformed_to_hash.merge!({ key => Hash.new })
|
169
|
+
|
170
|
+
# Then add the corresponding key/values to this new hash
|
171
|
+
ele.each_pair do |k, v|
|
172
|
+
if k != 'key' && k != 'name'
|
173
|
+
transformed_to_hash[key].merge!(transform_pair(k, v))
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
transformed_to_hash
|
179
|
+
end
|
180
|
+
|
181
|
+
##
|
182
|
+
# Transforms a hash into the appropriatey formatted hash with no camelcase and keys as symbols
|
183
|
+
#
|
184
|
+
# @param [Hash] Hash to be transformed
|
185
|
+
# @return [Hash] the transformed hash
|
186
|
+
def transform_hash(hash)
|
187
|
+
transformed_hash = Hash.new
|
188
|
+
hash.each_pair { |k, v| transformed_hash.merge!(transform_pair(k, v)) }
|
189
|
+
transformed_hash
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# Transforms a single keypair into a decamelized symbol with the appropriate value. Also converts
|
194
|
+
# any timestamps to a Ruby Time object
|
195
|
+
#
|
196
|
+
# @param[String] the key to be decamelized and symobolized
|
197
|
+
# @param[Hash] the newly created hash that contins the properly formatted key
|
198
|
+
def transform_pair(key, value)
|
199
|
+
hash = { decamelize(key).to_sym => value }
|
200
|
+
hash[:timestamp] = Time.parse(value) if hash[:timestamp]
|
201
|
+
if hash[:actions]
|
202
|
+
if hash[:actions][:name]
|
203
|
+
key_name = hash[:actions][:name]
|
204
|
+
hash[:actions].delete(:name)
|
205
|
+
hash[:actions] = { key_name.to_sym => hash[:actions] }
|
206
|
+
end
|
207
|
+
end
|
208
|
+
set_session_type(hash) if hash[:channel]
|
209
|
+
hash
|
210
|
+
end
|
211
|
+
|
212
|
+
##
|
213
|
+
# Sets the session type instance variables of voice_session and text_session
|
214
|
+
#
|
215
|
+
# @param[Hash] the key, value pair of the channel
|
216
|
+
# @return nil
|
217
|
+
def set_session_type(hash)
|
218
|
+
case hash[:channel]
|
219
|
+
when "VOICE"
|
220
|
+
@voice_session = true
|
221
|
+
@text_session = false
|
222
|
+
when "TEXT"
|
223
|
+
@text_session = true
|
224
|
+
@voice_session = false
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
@@ -0,0 +1,438 @@
|
|
1
|
+
# @author Jason Goecke
|
2
|
+
module Tropo
|
3
|
+
class Generator
|
4
|
+
include Tropo::Helpers
|
5
|
+
|
6
|
+
##
|
7
|
+
# Set a couple of Booleans to indicate the session type as a convenience
|
8
|
+
attr_reader :voice_session, :text_session
|
9
|
+
|
10
|
+
##
|
11
|
+
# Defines the actions on self so that we may call them individually
|
12
|
+
#
|
13
|
+
# @return [nil]
|
14
|
+
class << self
|
15
|
+
def method_missing(method_id, *args, &block)
|
16
|
+
g = Generator.new
|
17
|
+
g.send(method_id, *args, &block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Initializes the Generator class
|
23
|
+
#
|
24
|
+
# @overload initialize()
|
25
|
+
# @overload initialize(params)
|
26
|
+
# @param [Object] pass in an object that may be accessed inside the block
|
27
|
+
# @overload initialize(params, &block)
|
28
|
+
# @param [Object] pass in an object that may be accessed inside the block
|
29
|
+
# @param [Block] a block of code to execute (optional)
|
30
|
+
# @return [Object] a new Generator object
|
31
|
+
def initialize(params=nil, &block)
|
32
|
+
@response = { :tropo => Array.new }
|
33
|
+
if block_given?
|
34
|
+
# Lets us know were are in the midst of building a block, so we only rendor the JSON
|
35
|
+
# response at the end of executing the block, rather than at each action
|
36
|
+
@building = true
|
37
|
+
instance_exec(&block)
|
38
|
+
render_response
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Prompts the user (audio file or text to speech) and optionally waits for a response from the user.
|
44
|
+
# If collected, responses may be in the form of DTMF, speech recognition or text using a grammar or
|
45
|
+
# free-form text.
|
46
|
+
#
|
47
|
+
# @overload ask(params)
|
48
|
+
# @param [Hash] params the options to create an ask action request with.
|
49
|
+
# @option params [String] :name the name to assign to the result when returned to the application, default is true
|
50
|
+
# @option params [optional, Integer] :attempts (1) the number of times to prompt the user for input
|
51
|
+
# @option params [optional, Boolean] :bargein (true) allows a user to enter a key to stop the ask action
|
52
|
+
# @option params [optional, Float] :min_confidence (.5) the minimum confidence by which to accept the response expressed from 0-1, as opposed to asking again
|
53
|
+
# @option params [optional, Boolean] :required (true) if this is a field that must be completed by the user
|
54
|
+
# @option params [optional, Integer] :timeout (30) the amount of time, in seconds, to wait for a response before moving on
|
55
|
+
# @overload ask(params, &block)
|
56
|
+
# @param [Hash] params the options to create an ask action request with.
|
57
|
+
# @param [Block] takes a block so that you may trigger actions, such as a say, on a specific event
|
58
|
+
# @option params [String] :name the name to assign to the result when returned to the application
|
59
|
+
# @option params [optional, Integer] :attempts (1) the number of times to prompt the user for input
|
60
|
+
# @option params [optional, Boolean] :bargein (true) allows a user to enter a key to stop the ask action
|
61
|
+
# @option params [optional, Float] :min_confidence (.5) the minimum confidence by which to accept the response expressed from 0-1, as opposed to asking again
|
62
|
+
# @option params [optional, Boolean] :required (true) if this is a field that must be completed by the user
|
63
|
+
# @option params [optional, Integer] :timeout (30) the amount of time, in seconds, to wait for a response before moving on
|
64
|
+
# @return [String, nil] the JSON string to be passed back to Tropo or nil
|
65
|
+
# if the method has been called from inside a block
|
66
|
+
def ask(params={}, &block)
|
67
|
+
if block_given?
|
68
|
+
create_nested_hash('ask', params)
|
69
|
+
instance_exec(&block)
|
70
|
+
@response[:tropo] << @nested_hash
|
71
|
+
else
|
72
|
+
hash = build_action('ask', params)
|
73
|
+
@response[:tropo] << hash
|
74
|
+
end
|
75
|
+
render_response if @building.nil?
|
76
|
+
end
|
77
|
+
alias :prompt :ask
|
78
|
+
|
79
|
+
##
|
80
|
+
# Choices to give the user on input
|
81
|
+
#
|
82
|
+
# @param [Hash] params the options used to construct the grammar for the user
|
83
|
+
# @option params [String] :value the name to assign to the result when returned to the app
|
84
|
+
# @option params [optional, String] :mode (ANY) the mode to use when asking the user [DTMF, SPEECH or ANY]
|
85
|
+
# @option params [optional, String] :term_char the user may enter a keypad entry to stop the request
|
86
|
+
# @option params [optional, String] :type (simple/grammar) the type of grammar to use
|
87
|
+
# @option [String, nil] the JSON string to be passed back to Tropo or nil
|
88
|
+
# if the method has been called from inside a block
|
89
|
+
def choices(params={})
|
90
|
+
hash = build_action('choices', params)
|
91
|
+
|
92
|
+
if @nested_hash
|
93
|
+
@nested_hash[@nested_name.to_sym].merge!(hash)
|
94
|
+
else
|
95
|
+
@response[:tropo] << hash
|
96
|
+
render_response if @building.nil?
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# Creates a conference or pushes a user to an existing conference
|
102
|
+
#
|
103
|
+
# @overload conference(params)
|
104
|
+
# @param [Hash] params the options to create a message with.
|
105
|
+
# @option params [String] :name the name to assign to the conference room and to identify events back to the application
|
106
|
+
# @option params [Integer] :id the number to assign to the conference room
|
107
|
+
# @option params [optional, Boolean] :mute (false) whether to mute this caller in the conference
|
108
|
+
# @option params [optional, Integer] :max_time the maximum time, in seconds, to allow this user to stay in conference
|
109
|
+
# @option params [optional, Integer] :send_tones whether to send the DTMF a user may enter to the audio of the conference
|
110
|
+
# @option params [optional, String] :exit_tone whether to play a beep when this user exits a conference
|
111
|
+
# @overload conference(params, &block)
|
112
|
+
# @param [Hash] params the options to create a message with.
|
113
|
+
# @param [Block] takes a block so that you may trigger actions, such as a say, on a specific event
|
114
|
+
# @option params [String] :name the name to assign to the conference room and to identify events back to the application
|
115
|
+
# @option params [Integer] :id the number to assign to the conference room
|
116
|
+
# @option params [optional, Boolean] :mute (false) whether to mute this caller in the conference
|
117
|
+
# @option params [optional, Integer] :max_time the maximum time, in seconds, to allow this user to stay in conference
|
118
|
+
# @option params [optional, Integer] :send_tones whether to send the DTMF a user may enter to the audio of the conference
|
119
|
+
# @option params [optional, String] :exit_tone whether to play a beep when this user exits a conference
|
120
|
+
# @return [String, nil] the JSON string to be passed back to Tropo or nil
|
121
|
+
# if the method has been called from inside a block
|
122
|
+
def conference(params={}, &block)
|
123
|
+
if block_given?
|
124
|
+
create_nested_hash('conference', params)
|
125
|
+
instance_exec(&block)
|
126
|
+
@response[:tropo] << @nested_hash
|
127
|
+
else
|
128
|
+
hash = build_action('conference', params)
|
129
|
+
@response[:tropo] << hash
|
130
|
+
end
|
131
|
+
render_response if @building.nil?
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# This function instructs Tropo to "hang-up" or disconnect the current session.
|
136
|
+
#
|
137
|
+
# May trigger these events:
|
138
|
+
# - hangup
|
139
|
+
# - error
|
140
|
+
#
|
141
|
+
# @return [String, nil] returns the JSON string to hangup/stop the current session or nil
|
142
|
+
# if the method has been called from inside a block
|
143
|
+
def hangup
|
144
|
+
@response[:tropo] << { :hangup => nil }
|
145
|
+
render_response if @building.nil?
|
146
|
+
end
|
147
|
+
alias :disconnect :hangup
|
148
|
+
|
149
|
+
##
|
150
|
+
# Sets event handlers to call a REST resource when a particular event occurs
|
151
|
+
#
|
152
|
+
# @overload initialize(params)
|
153
|
+
# @param [Hash] params the options to create a message with.
|
154
|
+
# @option params [String] :event the event name that should trigger the callback
|
155
|
+
# @option params [String] :next the resource to send the callback to, such as '/error.json'
|
156
|
+
# @overload initialize(params, &block)
|
157
|
+
# @param [Hash] params the options to create a message with.
|
158
|
+
# @option params [String] :event the event name that should trigger the callback
|
159
|
+
# @option params [String] :next the resource to send the callback to, such as '/error.json'
|
160
|
+
# @param [Block] takes a block so that you may trigger actions, such as a say, on a specific event
|
161
|
+
# @option [String, nil] the JSON string to be passed back to Tropo or nil
|
162
|
+
# if the method has been called from inside a block
|
163
|
+
def on(params={}, &block)
|
164
|
+
if block_given?
|
165
|
+
create_nested_on_hash(params)
|
166
|
+
instance_exec(&block)
|
167
|
+
if @nested_hash
|
168
|
+
@nested_hash[@nested_name.to_sym].merge!(@nested_on_hash)
|
169
|
+
end
|
170
|
+
else
|
171
|
+
create_on_hash
|
172
|
+
hash = build_action('on', params)
|
173
|
+
@on_hash[:on] << hash
|
174
|
+
if @nested_hash
|
175
|
+
@nested_hash[@nested_name.to_sym].merge!(@on_hash)
|
176
|
+
else
|
177
|
+
@response[:tropo] << { :on => hash }
|
178
|
+
render_response if @building.nil?
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
##
|
184
|
+
# Parses the JSON string recieved from Tropo into a Ruby Hash
|
185
|
+
#
|
186
|
+
# @param [String] a JSON string
|
187
|
+
# @return [Hash] a Hash representing the response from Tropo
|
188
|
+
def parse(json_string)
|
189
|
+
response = JSON.parse json_string
|
190
|
+
|
191
|
+
# Check to see what type of response we are working with
|
192
|
+
if response['session']
|
193
|
+
transformed_response = { :session => { } }
|
194
|
+
|
195
|
+
response['session'].each_pair do |key, value|
|
196
|
+
value = transform_hash value if value.kind_of? Hash
|
197
|
+
transformed_response[:session].merge!(transform_pair(key, value))
|
198
|
+
end
|
199
|
+
|
200
|
+
elsif response['result']
|
201
|
+
transformed_response = { :result => { :actions => { } } }
|
202
|
+
|
203
|
+
response['result'].each_pair do |key, value|
|
204
|
+
value = transform_hash value if value.kind_of? Hash
|
205
|
+
value = transform_array value if value.kind_of? Array
|
206
|
+
transformed_response[:result].merge!(transform_pair(key, value))
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
transformed_response
|
211
|
+
end
|
212
|
+
|
213
|
+
##
|
214
|
+
# Plays a prompt (audio file or text to speech) and optionally waits for a response from the caller that is recorded.
|
215
|
+
# If collected, responses may be in the form of DTMF or speech recognition using a simple grammar format defined below.
|
216
|
+
# The record funtion is really an alias of the prompt function, but one which forces the record option to true regardless of how it is (or is not) initially set.
|
217
|
+
# At the conclusion of the recording, the audio file may be automatically sent to an external server via FTP or an HTTP POST/Multipart Form.
|
218
|
+
# If specified, the audio file may also be transcribed and the text returned to you via an email address or HTTP POST/Multipart Form.
|
219
|
+
#
|
220
|
+
# @overload record(params)
|
221
|
+
# @param [Hash] params the options to create a message with.
|
222
|
+
# @option params [String] :name the event name that should trigger the callback
|
223
|
+
# @option params [String] :url a valid URI, an HTTP, FTP or email address to POST the recording file to
|
224
|
+
# @option params [optional, String] :format (audio/wav) the audio format to record in, either a wav or mp3
|
225
|
+
# @option params [optional, String] :username if posting to FTP, the username for the FTP server
|
226
|
+
# @option params [optional, String] :password if posting to FTP, the password for the FTP server
|
227
|
+
# @overload record(params, &block)
|
228
|
+
# @param [Hash] params the options to create a message with.
|
229
|
+
# @param [Block] takes a block so that you may trigger actions, such as a say, on a specific event
|
230
|
+
# @option params [String] :name the event name that should trigger the callback
|
231
|
+
# @option params [String] :url a valid URI, an HTTP, FTP or email address to POST the recording file to
|
232
|
+
# @option params [optional, String] :format (audio/wav) the audio format to record in, either a wav or mp3
|
233
|
+
# @option params [optional, String] :username if posting to FTP, the username for the FTP server
|
234
|
+
# @option params [optional, String] :password if posting to FTP, the password for the FTP server
|
235
|
+
# @option [String, nil] the JSON string to be passed back to Tropo or nil
|
236
|
+
# if the method has been called from inside a block
|
237
|
+
def record(params={}, &block)
|
238
|
+
if block_given?
|
239
|
+
create_nested_hash('record', params)
|
240
|
+
instance_exec(&block)
|
241
|
+
@response[:tropo] << @nested_hash
|
242
|
+
else
|
243
|
+
hash = build_action('record', params)
|
244
|
+
@response[:tropo] << hash
|
245
|
+
end
|
246
|
+
render_response if @building.nil?
|
247
|
+
end
|
248
|
+
|
249
|
+
##
|
250
|
+
# The redirect function forwards an incoming call to another destination / phone number before answering it.
|
251
|
+
# The redirect function must be called before answer is called; redirect expects that a call be in the ringing or answering state.
|
252
|
+
# Use transfer when working with active answered calls.
|
253
|
+
#
|
254
|
+
# tel: classic phone number (See RFC 2896), must be proceeded by a + and the country code (ie - +14155551212 for a US #)
|
255
|
+
# sip: Session Initiation Protocol (SIP) address
|
256
|
+
#
|
257
|
+
# @param [Hash] params the options to create a message with.
|
258
|
+
# @option params [required, String] :to where to redirect the session to
|
259
|
+
# @option params [optional, String] :from set the from id for the session when redirecting
|
260
|
+
# @return [String, nil] the JSON string to redirect the current session or nil
|
261
|
+
# if the method has been called from inside a block
|
262
|
+
def redirect(params={})
|
263
|
+
hash = build_action('redirect', params)
|
264
|
+
@response[:tropo] << hash
|
265
|
+
render_response if @building.nil?
|
266
|
+
end
|
267
|
+
|
268
|
+
##
|
269
|
+
# Allows Tropo applications to reject incoming calls before they are answered.
|
270
|
+
# For example, an application could inspect the callerID variable to determine if the caller is known,
|
271
|
+
# and then use the reject call accordingly.
|
272
|
+
#
|
273
|
+
# @return [String, nil] the JSON string to reject the current session or nil
|
274
|
+
# if the method has been called from inside a block
|
275
|
+
def reject
|
276
|
+
@response[:tropo] << { :reject => nil }
|
277
|
+
render_response if @building.nil?
|
278
|
+
end
|
279
|
+
|
280
|
+
##
|
281
|
+
# Renders the JSON string to be sent to Tropo to execute a set of actions
|
282
|
+
#
|
283
|
+
# @return [String] the JSON string to be sent to the Tropo Remote API
|
284
|
+
def response
|
285
|
+
@response.to_json
|
286
|
+
end
|
287
|
+
|
288
|
+
##
|
289
|
+
# Resets the action hash if one desires to reuse the same Generator object
|
290
|
+
#
|
291
|
+
# @return [nil]
|
292
|
+
def reset
|
293
|
+
@response = { :tropo => Array.new }
|
294
|
+
@voice_session = false
|
295
|
+
@text_session = false
|
296
|
+
end
|
297
|
+
|
298
|
+
##
|
299
|
+
# Plays a prompt (audio file, text to speech or text for IM/SMS). There is no ability to wait for a response from a user.
|
300
|
+
# An audio file used for playback may be in one of the following two formats:
|
301
|
+
# Wav 8bit 8khz Ulaw
|
302
|
+
# MP3
|
303
|
+
#
|
304
|
+
# @overload say(params)
|
305
|
+
# @param [Hash] params the options to create a message with.
|
306
|
+
# @option params [String] :value the text or audio to be spoken or played back to the user
|
307
|
+
# @option params [Boolean] :event assigns a callback when a particular event occurs
|
308
|
+
# @option params [Integer] :as instructs the engine on how to handle the grammar
|
309
|
+
# @option params [Boolean] :format instructs the engine on how to handle the grammar
|
310
|
+
# @return [String, nil] the JSON string to be passed back to Tropo or nil
|
311
|
+
# if the method has been called from inside a block
|
312
|
+
# @overload say(value, params)
|
313
|
+
# @param [String] the text or audio to be spoken or played back to the user
|
314
|
+
# @param [Hash] params the options to create a message with.
|
315
|
+
# @option params [Boolean] :event assigns a callback when a particular event occurs
|
316
|
+
# @option params [Integer] :as instructs the engine on how to handle the grammar
|
317
|
+
# @option params [Boolean] :format instructs the engine on how to handle the grammar
|
318
|
+
# @return [String, nil] the JSON string to be passed back to Tropo or nil
|
319
|
+
# if the method has been called from inside a block
|
320
|
+
def say(value=nil, params={})
|
321
|
+
|
322
|
+
# This will allow a string to be passed to the say, as opposed to always having to specify a :value key/pair,
|
323
|
+
# or still allow a hash or Array to be passed as well
|
324
|
+
if value.kind_of? String
|
325
|
+
params[:value] = value
|
326
|
+
elsif value.kind_of? Hash
|
327
|
+
params = value
|
328
|
+
elsif value.kind_of? Array
|
329
|
+
params = value
|
330
|
+
else
|
331
|
+
raise ArgumentError, "An invalid paramater type #{value.class} has been passed"
|
332
|
+
end
|
333
|
+
|
334
|
+
response = { :say => Array.new }
|
335
|
+
|
336
|
+
if params.kind_of? Array
|
337
|
+
params.each do |param|
|
338
|
+
hash = build_action('say', param)
|
339
|
+
response[:say] << hash
|
340
|
+
end
|
341
|
+
else
|
342
|
+
hash = build_action('say', params)
|
343
|
+
response[:say] << hash
|
344
|
+
end
|
345
|
+
|
346
|
+
if @nested_hash && @nested_on_hash.nil?
|
347
|
+
@nested_hash[@nested_name.to_sym].merge!(response)
|
348
|
+
elsif @nested_on_hash
|
349
|
+
@nested_on_hash[:on][@nested_on_hash_cnt].merge!(response)
|
350
|
+
@nested_on_hash_cnt += 1
|
351
|
+
else
|
352
|
+
@response[:tropo] << response
|
353
|
+
render_response if @building.nil?
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
##
|
358
|
+
# Allows Tropo applications to begin recording the current session.
|
359
|
+
# The resulting recording may then be sent via FTP or an HTTP POST/Multipart Form.
|
360
|
+
#
|
361
|
+
# @param [Hash] params the options to create a message with.
|
362
|
+
# @option params [String] :url a valid URI, an HTTP, FTP or email address to POST the recording file to
|
363
|
+
# @option params [optional, String] :format (audio/wav) the audio format to record in, either a wav or mp3
|
364
|
+
# @option params [optional, String] :username if posting to FTP, the username for the FTP server
|
365
|
+
# @option params [optional, String] :password if posting to FTP, the password for the FTP server
|
366
|
+
# @return [String, nil] returns the JSON string to start the recording of a session or nil
|
367
|
+
# if the method has been called from inside a block
|
368
|
+
def start_recording(params={})
|
369
|
+
if block_given?
|
370
|
+
create_nested_hash('start_recording', params)
|
371
|
+
instance_exec(&block)
|
372
|
+
@response[:tropo] << @nested_hash
|
373
|
+
else
|
374
|
+
hash = build_action('start_recording', params)
|
375
|
+
@response[:tropo] << hash
|
376
|
+
end
|
377
|
+
render_response if @building.nil?
|
378
|
+
end
|
379
|
+
|
380
|
+
##
|
381
|
+
# Stops the recording of the current session after startCallRecording has been called
|
382
|
+
#
|
383
|
+
# @return [String, nil] returns the JSON string to stop the recording of a session or nil
|
384
|
+
# if the method has been called from inside a block
|
385
|
+
def stop_recording
|
386
|
+
@response[:tropo] << { :stopRecording => nil }
|
387
|
+
render_response if @building.nil?
|
388
|
+
end
|
389
|
+
|
390
|
+
##
|
391
|
+
# Transfers an already answered call to another destination / phone number.
|
392
|
+
# Call may be transferred to another phone number or SIP address, which is set through the "to" parameter and is in URL format.
|
393
|
+
# Supported formats include:
|
394
|
+
# tel: classic phone number (See RFC 2896), must be proceeded by a + and the country code (ie - +14155551212 for a US #)
|
395
|
+
# sip: SIP protocol address
|
396
|
+
#
|
397
|
+
# When this method is called the following occurs:
|
398
|
+
# The audio file specified in playvalue is played to the existing call. This could be "hold music", a ring-back sound, etc. The audio file is played up to playrepeat times.
|
399
|
+
# While audio is playing, a new call is initiated to the specified "to" address using the callerID specified.
|
400
|
+
# If answerOnMedia is true, the audio from the new call is connected to the existing call immediately.
|
401
|
+
# The system waits for an answer or other event from the new call up to the timeout.
|
402
|
+
# If the call successfully completes within the timeout, the existing call and new call will be connected, onSuccess will be called, and the transfer call will return a success event.
|
403
|
+
# If the call fails before the timeout, onCallFailure will be called and the method will return an onCallFailure event.
|
404
|
+
# If the call fails due to the timeout elapsing, onTimeout will be called and the method will return a timeout event
|
405
|
+
#
|
406
|
+
# @overload transfer(params)
|
407
|
+
# @param [Hash] params the options to create a transfer action request with
|
408
|
+
# @option params [String] :name the name to assign to the result when returned to the application, default is true
|
409
|
+
# @option params [optional, Boolean] :answer_on_media ???
|
410
|
+
# @option params [optional, Integer] :answer_timeout the amount of time to ring the far side before giving up and going to the next step
|
411
|
+
# @option params [optional, Boolean] :required (true) ???
|
412
|
+
# @option params [required, String] :to where to redirect the session to
|
413
|
+
# @option params [optional, String] :from set the from id for the session when redirecting
|
414
|
+
# @option params [optional, Integer] :ring_repeat ???
|
415
|
+
# @overload transfer(params, &block)
|
416
|
+
# @param [Hash] params the options to create a transfer action request with
|
417
|
+
# @option params [String] :name the name to assign to the result when returned to the application, default is true
|
418
|
+
# @option params [optional, Boolean] :answer_on_media ???
|
419
|
+
# @option params [optional, Integer] :answer_timeout the amount of time to ring the far side before giving up and going to the next step
|
420
|
+
# @option params [optional, Boolean] :required (true) ???
|
421
|
+
# @option params [required, String] :to where to redirect the session to
|
422
|
+
# @option params [optional, String] :from set the from id for the session when redirecting
|
423
|
+
# @option params [optional, Integer] :ring_repeat ???
|
424
|
+
# @return [nil, String]
|
425
|
+
def transfer(params={}, &block)
|
426
|
+
if block_given?
|
427
|
+
create_nested_hash('transfer', params)
|
428
|
+
instance_exec(&block)
|
429
|
+
@response[:tropo] << @nested_hash
|
430
|
+
else
|
431
|
+
hash = build_action('transfer', params)
|
432
|
+
@response[:tropo] << hash
|
433
|
+
end
|
434
|
+
render_response if @building.nil?
|
435
|
+
end
|
436
|
+
|
437
|
+
end
|
438
|
+
end
|