webficient-twilio 2.0.0 → 2.1.0
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/VERSION.yml +1 -1
- data/lib/twilio/verb.rb +151 -14
- data/test/fixtures/yml/verb_responses.yml +29 -5
- data/test/twilio/verb_test.rb +77 -7
- metadata +2 -2
data/VERSION.yml
CHANGED
data/lib/twilio/verb.rb
CHANGED
@@ -1,13 +1,31 @@
|
|
1
1
|
module Twilio
|
2
2
|
# Twilio Verbs enable your application to respond to Twilio requests (to your app) with XML responses.
|
3
3
|
# There are 5 primary verbs (say, play, gather, record, dial) and 3 secondary (hangup, pause, redirect).
|
4
|
+
# Verbs can be chained and, in some cases, nested.
|
5
|
+
#
|
6
|
+
# If your response consists of a single verb, you can use the inline form of a new verb instance:
|
7
|
+
#
|
8
|
+
# Twilio::Verb.new.say('The time is 9:35 PM.')
|
9
|
+
#
|
10
|
+
# But if you need to chain several verbs together, just wrap them in a block and call the 'response' attribute:
|
11
|
+
#
|
12
|
+
# verb = Twilio::Verb.new { |v|
|
13
|
+
# v.dial('415-123-4567')
|
14
|
+
# v.redirect('http://www.foo.com/nextInstructions')
|
15
|
+
# }
|
16
|
+
# verb.response
|
4
17
|
class Verb
|
18
|
+
|
19
|
+
attr_reader :response
|
5
20
|
|
6
21
|
def initialize(&block)
|
7
22
|
@xml = Builder::XmlMarkup.new
|
8
23
|
@xml.instruct!
|
9
24
|
|
10
|
-
|
25
|
+
if block_given?
|
26
|
+
@chain = true
|
27
|
+
@response = @xml.Response { block.call(self) }
|
28
|
+
end
|
11
29
|
end
|
12
30
|
|
13
31
|
# The Say verb converts text to speech that is read back to the caller.
|
@@ -23,7 +41,8 @@ module Twilio
|
|
23
41
|
# Twilio::Verb.new.say('Your PIN is 1234', :loop => 4)
|
24
42
|
# Twilio::Verb.new.say('Your PIN is 1 2 3 4', :loop => 4)
|
25
43
|
#
|
26
|
-
# If you need a longer pause between each loop,
|
44
|
+
# If you need a longer pause between each loop, instead of explicitly calling the Pause
|
45
|
+
# verb within a block, you can set the convenient pause option:
|
27
46
|
#
|
28
47
|
# Twilio::Verb.new.say('Your PIN is 1 2 3 4', :loop => 4, :pause => true)
|
29
48
|
#
|
@@ -31,7 +50,7 @@ module Twilio
|
|
31
50
|
#
|
32
51
|
# Twilio::Verb.new.say('The time is 9:35 PM.', :voice => 'woman')
|
33
52
|
# Twilio::Verb.new.say('The time is 9:35 PM.', {:voice => 'woman', :language => 'es'})
|
34
|
-
def say(*args
|
53
|
+
def say(*args)
|
35
54
|
options = {:voice => 'man', :language => 'en', :loop => 1}
|
36
55
|
args.each do |arg|
|
37
56
|
case arg
|
@@ -44,7 +63,7 @@ module Twilio
|
|
44
63
|
end
|
45
64
|
end
|
46
65
|
|
47
|
-
|
66
|
+
output {
|
48
67
|
if options[:pause]
|
49
68
|
loop_with_pause(options[:loop], @xml) do
|
50
69
|
@xml.Say(options[:text_to_speak], :voice => options[:voice], :language => options[:language])
|
@@ -60,13 +79,14 @@ module Twilio
|
|
60
79
|
# Twilio::Verb.new.play('http://foo.com/cowbell.mp3')
|
61
80
|
# Twilio::Verb.new.play('http://foo.com/cowbell.mp3', :loop => 3)
|
62
81
|
#
|
63
|
-
# If you need a longer pause between each loop,
|
82
|
+
# If you need a longer pause between each loop, instead of explicitly calling the Pause
|
83
|
+
# verb within a block, you can set the convenient pause option:
|
64
84
|
#
|
65
85
|
# Twilio::Verb.new.play('http://foo.com/cowbell.mp3', :loop => 3, :pause => true)
|
66
86
|
#
|
67
87
|
# Options (see http://www.twilio.com/docs/api_reference/TwiML/play) are passed in as a hash,
|
68
88
|
# but only 'loop' is currently supported.
|
69
|
-
def play(*args
|
89
|
+
def play(*args)
|
70
90
|
options = {:loop => 1}
|
71
91
|
args.each do |arg|
|
72
92
|
case arg
|
@@ -79,7 +99,7 @@ module Twilio
|
|
79
99
|
end
|
80
100
|
end
|
81
101
|
|
82
|
-
|
102
|
+
output {
|
83
103
|
if options[:pause]
|
84
104
|
loop_with_pause(options[:loop], @xml) do
|
85
105
|
@xml.Play(options[:audio_url])
|
@@ -101,11 +121,29 @@ module Twilio
|
|
101
121
|
# Twilio::Verb.new.gather(:action => 'http://foobar.com')
|
102
122
|
# Twilio::Verb.new.gather(:finishOnKey => '*')
|
103
123
|
# Twilio::Verb.new.gather(:action => 'http://foobar.com', :finishOnKey => '*')
|
124
|
+
#
|
125
|
+
# Gather also lets you nest the Play, Say, and Pause verbs:
|
126
|
+
#
|
127
|
+
# verb = Twilio::Verb.new { |v|
|
128
|
+
# v.gather(:action => '/process_gather', :method => 'GET) {
|
129
|
+
# v.say('Please enter your account number followed by the pound sign')
|
130
|
+
# }
|
131
|
+
# v.say("We didn't receive any input. Goodbye!")
|
132
|
+
# }
|
133
|
+
# verb.response # represents the final xml output
|
104
134
|
def gather(*args, &block)
|
105
|
-
options = args.shift
|
106
|
-
|
135
|
+
options = args.shift || {}
|
136
|
+
output {
|
137
|
+
if block_given?
|
138
|
+
@xml.Gather(options) { block.call }
|
139
|
+
else
|
140
|
+
@xml.Gather(options)
|
141
|
+
end
|
142
|
+
}
|
107
143
|
end
|
108
144
|
|
145
|
+
#play, say, pause
|
146
|
+
|
109
147
|
# The Record verb records the caller's voice and returns a URL that links to a file
|
110
148
|
# containing the audio recording.
|
111
149
|
#
|
@@ -116,9 +154,9 @@ module Twilio
|
|
116
154
|
# Twilio::Verb.new.record(:action => 'http://foobar.com')
|
117
155
|
# Twilio::Verb.new.record(:finishOnKey => '*')
|
118
156
|
# Twilio::Verb.new.record(:transcribe => true, :transcribeCallback => '/handle_transcribe')
|
119
|
-
def record(*args
|
157
|
+
def record(*args)
|
120
158
|
options = args.shift
|
121
|
-
|
159
|
+
output { @xml.Record(options) }
|
122
160
|
end
|
123
161
|
|
124
162
|
# The Dial verb connects the current caller to an another phone. If the called party picks up,
|
@@ -137,6 +175,17 @@ module Twilio
|
|
137
175
|
# Twilio::Verb.new.dial('415-123-4567')
|
138
176
|
# Twilio::Verb.new.dial('415-123-4567', :action => 'http://foobar.com')
|
139
177
|
# Twilio::Verb.new.dial('415-123-4567', {:timeout => 10, :callerId => '858-987-6543'})
|
178
|
+
#
|
179
|
+
# Twilio also supports an alternate form in which a Number object is nested inside Dial:
|
180
|
+
#
|
181
|
+
# verb = Twilio::Verb.new { |v|
|
182
|
+
# v.dial {
|
183
|
+
# v.number('415-123-4567')
|
184
|
+
# v.number('415-123-4568')
|
185
|
+
# v.number('415-123-4569')
|
186
|
+
# }
|
187
|
+
# }
|
188
|
+
# verb.response # represents the final xml output
|
140
189
|
def dial(*args, &block)
|
141
190
|
number_to_dial = ''
|
142
191
|
options = {}
|
@@ -151,13 +200,101 @@ module Twilio
|
|
151
200
|
end
|
152
201
|
end
|
153
202
|
|
154
|
-
|
203
|
+
output {
|
204
|
+
if block_given?
|
205
|
+
@xml.Dial(options) { block.call }
|
206
|
+
else
|
207
|
+
@xml.Dial(number_to_dial, options)
|
208
|
+
end
|
209
|
+
}
|
210
|
+
end
|
211
|
+
|
212
|
+
# The Pause (secondary) verb waits silently for a number of seconds.
|
213
|
+
# It is normally chained with other verbs.
|
214
|
+
#
|
215
|
+
# Options (see http://www.twilio.com/docs/api_reference/TwiML/pause) are passed in as a hash
|
216
|
+
#
|
217
|
+
# Examples:
|
218
|
+
# verb = Twilio::Verb.new { |v|
|
219
|
+
# v.say('greetings')
|
220
|
+
# v.pause(:length => 2)
|
221
|
+
# v.say('have a nice day')
|
222
|
+
# }
|
223
|
+
# verb.response
|
224
|
+
def pause(*args)
|
225
|
+
options = args.shift
|
226
|
+
output { @xml.Pause(options) }
|
227
|
+
end
|
228
|
+
|
229
|
+
# The Redirect (secondary) verb transfers control to a different URL.
|
230
|
+
# It is normally chained with other verbs.
|
231
|
+
#
|
232
|
+
# Options (see http://www.twilio.com/docs/api_reference/TwiML/redirect) are passed in as a hash
|
233
|
+
#
|
234
|
+
# Examples:
|
235
|
+
# verb = Twilio::Verb.new { |v|
|
236
|
+
# v.dial('415-123-4567')
|
237
|
+
# v.redirect('http://www.foo.com/nextInstructions')
|
238
|
+
# }
|
239
|
+
# verb.response
|
240
|
+
def redirect(*args)
|
241
|
+
redirect_to_url = ''
|
242
|
+
options = {}
|
243
|
+
args.each do |arg|
|
244
|
+
case arg
|
245
|
+
when String
|
246
|
+
redirect_to_url = arg
|
247
|
+
when Hash
|
248
|
+
options.merge!(arg)
|
249
|
+
else
|
250
|
+
raise ArgumentError, 'dial expects String or Hash argument'
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
output { @xml.Redirect(redirect_to_url, options) }
|
255
|
+
end
|
256
|
+
|
257
|
+
# The Hangup (secondary) verb ends the call.
|
258
|
+
#
|
259
|
+
# Examples:
|
260
|
+
# If your response is only a hangup:
|
261
|
+
#
|
262
|
+
# Twilio::Verb.new.hangup
|
263
|
+
#
|
264
|
+
# If your response is chained:
|
265
|
+
#
|
266
|
+
# verb = Twilio::Verb.new { |v|
|
267
|
+
# v.say("The time is #{Time.now}")
|
268
|
+
# v.hangup
|
269
|
+
# }
|
270
|
+
# verb.response
|
271
|
+
def hangup
|
272
|
+
output { @xml.Hangup }
|
273
|
+
end
|
274
|
+
|
275
|
+
# The Number element specifies a phone number. The number element has two optional attributes: sendDigits and url.
|
276
|
+
# Number elements can only be nested in Dial verbs
|
277
|
+
def number(*args)
|
278
|
+
number_to_dial = ''
|
279
|
+
options = {}
|
280
|
+
args.each do |arg|
|
281
|
+
case arg
|
282
|
+
when String
|
283
|
+
number_to_dial = arg
|
284
|
+
when Hash
|
285
|
+
options.merge!(arg)
|
286
|
+
else
|
287
|
+
raise ArgumentError, 'dial expects String or Hash argument'
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
output { @xml.Number(number_to_dial, options) }
|
155
292
|
end
|
156
293
|
|
157
294
|
private
|
158
295
|
|
159
|
-
def
|
160
|
-
@xml.Response { yield }
|
296
|
+
def output
|
297
|
+
@chain ? yield : @xml.Response { yield }
|
161
298
|
end
|
162
299
|
|
163
300
|
def loop_with_pause(loop_count, xml, &verb_action)
|
@@ -17,8 +17,14 @@ say_hi_with_pause:
|
|
17
17
|
response: <?xml version="1.0" encoding="UTF-8"?><Response><Say loop="1" language="en" voice="man">hi</Say><Pause/></Response>
|
18
18
|
|
19
19
|
say_hi_with_pause_and_say_bye:
|
20
|
-
response: <?xml version="1.0" encoding="UTF-8"?><Response><Say loop="1" language="en" voice="man">hi</Say><Pause
|
21
|
-
|
20
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Say loop="1" language="en" voice="man">hi</Say><Pause></Pause><Say loop="1" language="en" voice="man">bye</Say></Response>
|
21
|
+
|
22
|
+
say_hi_with_2_second_pause_and_say_bye:
|
23
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Say loop="1" language="en" voice="man">hi</Say><Pause length="2"/><Say loop="1" language="en" voice="man">bye</Say></Response>
|
24
|
+
|
25
|
+
say_hi_and_hangup:
|
26
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Say loop="1" language="en" voice="man">hi</Say><Hangup/></Response>
|
27
|
+
|
22
28
|
play_mp3:
|
23
29
|
response: <?xml version="1.0" encoding="UTF-8"?><Response><Play loop="1">http://foo.com/cowbell.mp3</Play></Response>
|
24
30
|
|
@@ -29,7 +35,7 @@ play_mp3_two_times_with_pause:
|
|
29
35
|
response: <?xml version="1.0" encoding="UTF-8"?><Response><Play>http://foo.com/cowbell.mp3</Play><Pause/><Play>http://foo.com/cowbell.mp3</Play></Response>
|
30
36
|
|
31
37
|
gather:
|
32
|
-
response: <?xml version="1.0" encoding="UTF-8"?><Response><Gather
|
38
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Gather/></Response>
|
33
39
|
|
34
40
|
gather_with_action:
|
35
41
|
response: <?xml version="1.0" encoding="UTF-8"?><Response><Gather action="http://foobar.com"/></Response>
|
@@ -47,8 +53,14 @@ gather_with_num_digits:
|
|
47
53
|
response: <?xml version="1.0" encoding="UTF-8"?><Response><Gather numDigits="5"/></Response>
|
48
54
|
|
49
55
|
gather_with_all_options_set:
|
50
|
-
response: <?xml version="1.0" encoding="UTF-8"?><Response><Gather
|
56
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Gather action="http://foobar.com" numDigits="5" method="GET" timeout="10" finishOnKey="*"/></Response>
|
57
|
+
|
58
|
+
gather_and_say_instructions:
|
59
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Gather><Say loop="1" language="en" voice="man">Please enter your account number followed by the pound sign</Say></Gather><Say loop="1" language="en" voice="man">We didn't receive any input. Goodbye!</Say></Response>
|
51
60
|
|
61
|
+
gather_with_timeout_and_say_instructions:
|
62
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Gather timeout="10"><Say loop="1" language="en" voice="man">Please enter your account number followed by the pound sign</Say></Gather><Say loop="1" language="en" voice="man">We didn't receive any input. Goodbye!</Say></Response>
|
63
|
+
|
52
64
|
record:
|
53
65
|
response: <?xml version="1.0" encoding="UTF-8"?><Response><Record></Record></Response>
|
54
66
|
|
@@ -92,4 +104,16 @@ dial_with_caller_id:
|
|
92
104
|
response: <?xml version="1.0" encoding="UTF-8"?><Response><Dial callerId="858-987-6543">415-123-4567</Dial></Response>
|
93
105
|
|
94
106
|
dial_with_timeout_and_caller_id:
|
95
|
-
response: <?xml version="1.0" encoding="UTF-8"?><Response><Dial callerId="858-987-6543"
|
107
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Dial timeout="10" callerId="858-987-6543">415-123-4567</Dial></Response>
|
108
|
+
|
109
|
+
dial_with_redirect:
|
110
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Dial>415-123-4567</Dial><Redirect>http://www.foo.com/nextInstructions</Redirect></Response>
|
111
|
+
|
112
|
+
dial_with_number_and_send_digits:
|
113
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Dial><Number sendDigits="wwww1928">415-123-4567</Number></Dial></Response>
|
114
|
+
|
115
|
+
dial_multiple_numbers:
|
116
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Dial><Number>415-123-4567</Number><Number>415-123-4568</Number><Number>415-123-4569</Number></Dial></Response>
|
117
|
+
|
118
|
+
hangup:
|
119
|
+
response: <?xml version="1.0" encoding="UTF-8"?><Response><Hangup/></Response>
|
data/test/twilio/verb_test.rb
CHANGED
@@ -22,13 +22,23 @@ class VerbTest < Test::Unit::TestCase #:nodoc: all
|
|
22
22
|
assert_equal verb_response(:say_hi_three_times_with_pause), Twilio::Verb.new.say('hi', :loop => 3, :pause => true)
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
should "say 'hi' with pause and say 'bye'" do
|
26
|
+
verb = Twilio::Verb.new { |v|
|
27
|
+
v.say('hi', :loop => 1)
|
28
|
+
v.pause
|
29
|
+
v.say('bye')
|
30
|
+
}
|
31
|
+
assert_equal verb_response(:say_hi_with_pause_and_say_bye), verb.response
|
32
|
+
end
|
33
|
+
|
34
|
+
should "say 'hi' with 2 second pause and say 'bye'" do
|
35
|
+
verb = Twilio::Verb.new { |v|
|
36
|
+
v.say('hi')
|
37
|
+
v.pause(:length => 2)
|
38
|
+
v.say('bye')
|
39
|
+
}
|
40
|
+
assert_equal verb_response(:say_hi_with_2_second_pause_and_say_bye), verb.response
|
41
|
+
end
|
32
42
|
|
33
43
|
should "play mp3 response" do
|
34
44
|
assert_equal verb_response(:play_mp3), Twilio::Verb.new.play('http://foo.com/cowbell.mp3')
|
@@ -70,6 +80,26 @@ class VerbTest < Test::Unit::TestCase #:nodoc: all
|
|
70
80
|
assert_equal verb_response(:gather_with_all_options_set), Twilio::Verb.new.gather(:action => 'http://foobar.com', :method => 'GET', :timeout => 10, :finishOnKey => '*', :numDigits => 5)
|
71
81
|
end
|
72
82
|
|
83
|
+
should "gather and say instructions" do
|
84
|
+
verb = Twilio::Verb.new { |v|
|
85
|
+
v.gather {
|
86
|
+
v.say('Please enter your account number followed by the pound sign')
|
87
|
+
}
|
88
|
+
v.say("We didn't receive any input. Goodbye!")
|
89
|
+
}
|
90
|
+
assert_equal verb_response(:gather_and_say_instructions), verb.response
|
91
|
+
end
|
92
|
+
|
93
|
+
should "gather with timeout and say instructions" do
|
94
|
+
verb = Twilio::Verb.new { |v|
|
95
|
+
v.gather(:timeout => 10) {
|
96
|
+
v.say('Please enter your account number followed by the pound sign')
|
97
|
+
}
|
98
|
+
v.say("We didn't receive any input. Goodbye!")
|
99
|
+
}
|
100
|
+
assert_equal verb_response(:gather_with_timeout_and_say_instructions), verb.response
|
101
|
+
end
|
102
|
+
|
73
103
|
should "record" do
|
74
104
|
assert_equal verb_response(:record), Twilio::Verb.new.record
|
75
105
|
end
|
@@ -129,6 +159,46 @@ class VerbTest < Test::Unit::TestCase #:nodoc: all
|
|
129
159
|
should "dial with timeout and caller id" do
|
130
160
|
assert_equal verb_response(:dial_with_timeout_and_caller_id), Twilio::Verb.new.dial('415-123-4567', {:timeout => 10, :callerId => '858-987-6543'})
|
131
161
|
end
|
162
|
+
|
163
|
+
should "dial with redirect" do
|
164
|
+
verb = Twilio::Verb.new { |v|
|
165
|
+
v.dial('415-123-4567')
|
166
|
+
v.redirect('http://www.foo.com/nextInstructions')
|
167
|
+
}
|
168
|
+
assert_equal verb_response(:dial_with_redirect), verb.response
|
169
|
+
end
|
170
|
+
|
171
|
+
should "dial with number and send digits" do
|
172
|
+
verb = Twilio::Verb.new { |v|
|
173
|
+
v.dial {
|
174
|
+
v.number('415-123-4567', :sendDigits => 'wwww1928')
|
175
|
+
}
|
176
|
+
}
|
177
|
+
assert_equal verb_response(:dial_with_number_and_send_digits), verb.response
|
178
|
+
end
|
179
|
+
|
180
|
+
should "dial multiple numbers" do
|
181
|
+
verb = Twilio::Verb.new { |v|
|
182
|
+
v.dial {
|
183
|
+
v.number('415-123-4567')
|
184
|
+
v.number('415-123-4568')
|
185
|
+
v.number('415-123-4569')
|
186
|
+
}
|
187
|
+
}
|
188
|
+
assert_equal verb_response(:dial_multiple_numbers), verb.response
|
189
|
+
end
|
190
|
+
|
191
|
+
should "hangup" do
|
192
|
+
assert_equal verb_response(:hangup), Twilio::Verb.new.hangup
|
193
|
+
end
|
194
|
+
|
195
|
+
should "say hi and hangup" do
|
196
|
+
verb = Twilio::Verb.new { |v|
|
197
|
+
v.say('hi')
|
198
|
+
v.hangup
|
199
|
+
}
|
200
|
+
assert_equal verb_response(:say_hi_and_hangup), verb.response
|
201
|
+
end
|
132
202
|
end
|
133
203
|
|
134
204
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webficient-twilio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phil Misiowiec
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-06-
|
12
|
+
date: 2009-06-22 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|