tropo-webapi-ruby 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|