slayer-twilio 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.gitignore +8 -0
  2. data/CHANGELOG.rdoc +31 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +20 -0
  5. data/README.rdoc +63 -0
  6. data/Rakefile +9 -0
  7. data/lib/twilio.rb +53 -0
  8. data/lib/twilio/account.rb +12 -0
  9. data/lib/twilio/available_phone_numbers.rb +56 -0
  10. data/lib/twilio/call.rb +37 -0
  11. data/lib/twilio/conference.rb +35 -0
  12. data/lib/twilio/incoming_phone_number.rb +30 -0
  13. data/lib/twilio/notification.rb +20 -0
  14. data/lib/twilio/outgoing_caller_id.rb +33 -0
  15. data/lib/twilio/recording.rb +24 -0
  16. data/lib/twilio/sms.rb +22 -0
  17. data/lib/twilio/twilio_object.rb +19 -0
  18. data/lib/twilio/verb.rb +387 -0
  19. data/lib/twilio/version.rb +3 -0
  20. data/spec/fixtures/xml/account.xml +23 -0
  21. data/spec/fixtures/xml/account_renamed.xml +11 -0
  22. data/spec/fixtures/xml/available_phone_numbers_local.xml +26 -0
  23. data/spec/fixtures/xml/available_phone_numbers_local_search.xml +15 -0
  24. data/spec/fixtures/xml/available_phone_numbers_toll_free.xml +14 -0
  25. data/spec/fixtures/xml/available_phone_numbers_toll_free_search.xml +10 -0
  26. data/spec/fixtures/xml/call.xml +18 -0
  27. data/spec/fixtures/xml/call_new.xml +14 -0
  28. data/spec/fixtures/xml/call_redirected.xml +15 -0
  29. data/spec/fixtures/xml/calls.xml +36 -0
  30. data/spec/fixtures/xml/conference.xml +10 -0
  31. data/spec/fixtures/xml/conference_participant.xml +12 -0
  32. data/spec/fixtures/xml/conference_participant_muted.xml +12 -0
  33. data/spec/fixtures/xml/conference_participants.xml +24 -0
  34. data/spec/fixtures/xml/conferences.xml +12 -0
  35. data/spec/fixtures/xml/incoming_phone_number.xml +12 -0
  36. data/spec/fixtures/xml/incoming_phone_numbers.xml +24 -0
  37. data/spec/fixtures/xml/notification.xml +19 -0
  38. data/spec/fixtures/xml/notifications.xml +32 -0
  39. data/spec/fixtures/xml/outgoing_caller_id.xml +10 -0
  40. data/spec/fixtures/xml/outgoing_caller_id_new.xml +7 -0
  41. data/spec/fixtures/xml/outgoing_caller_ids.xml +20 -0
  42. data/spec/fixtures/xml/recording.xml +10 -0
  43. data/spec/fixtures/xml/recordings.xml +20 -0
  44. data/spec/fixtures/xml/sms.xml +14 -0
  45. data/spec/fixtures/xml/sms_messages.xml +29 -0
  46. data/spec/fixtures/xml/sms_new.xml +14 -0
  47. data/spec/fixtures/xml/sms_new_with_callback.xml +15 -0
  48. data/spec/fixtures/xml/transcription.xml +13 -0
  49. data/spec/fixtures/xml/transcriptions.xml +26 -0
  50. data/spec/fixtures/yml/verb_responses.yml +86 -0
  51. data/spec/spec_helper.rb +17 -0
  52. data/spec/support/twilio_helpers.rb +52 -0
  53. data/spec/twilio/account_spec.rb +21 -0
  54. data/spec/twilio/available_phone_numbers_spec.rb +53 -0
  55. data/spec/twilio/call_spec.rb +64 -0
  56. data/spec/twilio/conference_spec.rb +58 -0
  57. data/spec/twilio/incoming_phone_number_spec.rb +42 -0
  58. data/spec/twilio/live_connection_spec.rb +21 -0
  59. data/spec/twilio/notification_spec.rb +29 -0
  60. data/spec/twilio/outgoing_caller_id_spec.rb +43 -0
  61. data/spec/twilio/recording_spec.rb +44 -0
  62. data/spec/twilio/sms_spec.rb +36 -0
  63. data/spec/twilio/verb_spec.rb +253 -0
  64. data/twilio.gemspec +30 -0
  65. metadata +258 -0
data/lib/twilio/sms.rb ADDED
@@ -0,0 +1,22 @@
1
+ module Twilio
2
+ # An SMS message resource represents an Inbound or Outbound SMS message. When someone sends a text message from
3
+ # or to your application, either via the REST API, or during a call via the verb, an SMS message resource is created.
4
+ class Sms < TwilioObject
5
+ # Example:
6
+ # Twilio.connect('my_twilio_sid', 'my_auth_token')
7
+ # Twilio::Sms.message(CALLER_ID, user_number, 'This is my simple SMS message', 'http://example.com/sms_callback')
8
+ def message(from, to, body, callback_url=nil)
9
+ callback = callback_url ? {:StatusCallback => callback_url} : {}
10
+ Twilio.post("/SMS/Messages", :body => {:From => from, :To => to, :Body => body}.merge(callback))
11
+ end
12
+
13
+ def list(opts = {})
14
+ Twilio.get("/SMS/Messages", :query => (opts.empty? ? nil : opts))
15
+ end
16
+
17
+ def get(sms_message_sid)
18
+ Twilio.get("/SMS/Messages/#{sms_message_sid}")
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ module Twilio
2
+ class TwilioObject #:nodoc: all
3
+ def initialize
4
+ end
5
+
6
+ class << self
7
+ def method_missing(method_id, *args) #:nodoc:
8
+ o = self.new
9
+ o.send(method_id, *args)
10
+ rescue HTTParty::UnsupportedURIScheme
11
+ raise "You must set Twilio.connect before calling #{self.inspect}##{method_id}"
12
+ end
13
+ end
14
+
15
+ def connected?
16
+ self.class.base_uri
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,387 @@
1
+ module Twilio
2
+ # Twilio Verbs enable your application to respond to Twilio requests (to your app) with XML responses.
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 call a Verb class method:
7
+ #
8
+ # Twilio::Verb.say 'The time is 9:35 PM.'
9
+ #
10
+ # But if you need to chain several verbs together, just wrap them in an instance 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
17
+ class Verb
18
+
19
+ attr_reader :response
20
+
21
+ class << self
22
+ def method_missing(method_id, *args) #:nodoc:
23
+ v = Verb.new
24
+ v.send(method_id, *args)
25
+ end
26
+ end
27
+
28
+ def initialize(&block)
29
+ @xml = Builder::XmlMarkup.new
30
+ @xml.instruct!
31
+
32
+ if block_given?
33
+ @chain = true
34
+ @response = @xml.Response { block.call(self) }
35
+ end
36
+ end
37
+
38
+ # The Say verb converts text to speech that is read back to the caller.
39
+ # Say is useful for dynamic text that is difficult to prerecord.
40
+ #
41
+ # Examples:
42
+ # Twilio::Verb.say 'The time is 9:35 PM.'
43
+ # Twilio::Verb.say 'The time is 9:35 PM.', :loop => 3
44
+ #
45
+ # With numbers, 12345 will be spoken as "twelve thousand three hundred forty five" while
46
+ # 1 2 3 4 5 will be spoken as "one two three four five."
47
+ #
48
+ # Twilio::Verb.say 'Your PIN is 1234', :loop => 4
49
+ # Twilio::Verb.say 'Your PIN is 1 2 3 4', :loop => 4
50
+ #
51
+ # If you need a longer pause between each loop, instead of explicitly calling the Pause
52
+ # verb within a block, you can set the convenient pause option:
53
+ #
54
+ # Twilio::Verb.say 'Your PIN is 1 2 3 4', :loop => 4, :pause => true
55
+ #
56
+ # Options (see http://www.twilio.com/docs/api_reference/TwiML/say) are passed in as a hash:
57
+ #
58
+ # Twilio::Verb.say 'The time is 9:35 PM.', :voice => 'woman'
59
+ # Twilio::Verb.say 'The time is 9:35 PM.', :voice => 'woman', :language => 'es'
60
+ def say(*args)
61
+ options = {:voice => 'man', :language => 'en', :loop => 1}
62
+ args.each do |arg|
63
+ case arg
64
+ when String
65
+ options[:text_to_speak] = arg
66
+ when Hash
67
+ options.merge!(arg)
68
+ else
69
+ raise ArgumentError, 'say expects String or Hash argument'
70
+ end
71
+ end
72
+
73
+ output {
74
+ if options[:pause]
75
+ loop_with_pause(options[:loop], @xml) do
76
+ @xml.Say(options[:text_to_speak], :voice => options[:voice], :language => options[:language])
77
+ end
78
+ else
79
+ @xml.Say(options[:text_to_speak], :voice => options[:voice], :language => options[:language], :loop => options[:loop])
80
+ end
81
+ }
82
+ end
83
+
84
+ # The Play verb plays an audio URL back to the caller.
85
+ # Examples:
86
+ # Twilio::Verb.play 'http://foo.com/cowbell.mp3'
87
+ # Twilio::Verb.play 'http://foo.com/cowbell.mp3', :loop => 3
88
+ #
89
+ # If you need a longer pause between each loop, instead of explicitly calling the Pause
90
+ # verb within a block, you can set the convenient pause option:
91
+ #
92
+ # Twilio::Verb.play 'http://foo.com/cowbell.mp3', :loop => 3, :pause => true
93
+ #
94
+ # Options (see http://www.twilio.com/docs/api_reference/TwiML/play) are passed in as a hash,
95
+ # but only 'loop' is currently supported.
96
+ def play(*args)
97
+ options = {:loop => 1}
98
+ args.each do |arg|
99
+ case arg
100
+ when String
101
+ options[:audio_url] = arg
102
+ when Hash
103
+ options.merge!(arg)
104
+ else
105
+ raise ArgumentError, 'play expects String or Hash argument'
106
+ end
107
+ end
108
+
109
+ output {
110
+ if options[:pause]
111
+ loop_with_pause(options[:loop], @xml) do
112
+ @xml.Play(options[:audio_url])
113
+ end
114
+ else
115
+ @xml.Play(options[:audio_url], :loop => options[:loop])
116
+ end
117
+ }
118
+ end
119
+
120
+ # The Gather verb collects digits entered by a caller into their telephone keypad.
121
+ # When the caller is done entering data, Twilio submits that data to a provided URL,
122
+ # as either a HTTP GET or POST request, just like a web browser submits data from an HTML form.
123
+ #
124
+ # Options (see http://www.twilio.com/docs/api_reference/TwiML/gather) are passed in as a hash
125
+ #
126
+ # Examples:
127
+ # Twilio::Verb.gather
128
+ # Twilio::Verb.gather :action => 'http://foobar.com'
129
+ # Twilio::Verb.gather :finishOnKey => '*'
130
+ # Twilio::Verb.gather :action => 'http://foobar.com', :finishOnKey => '*'
131
+ #
132
+ # Gather also lets you nest the Play, Say, and Pause verbs:
133
+ #
134
+ # verb = Twilio::Verb.new { |v|
135
+ # v.gather(:action => '/process_gather', :method => 'GET) {
136
+ # v.say 'Please enter your account number followed by the pound sign'
137
+ # }
138
+ # v.say "We didn't receive any input. Goodbye!"
139
+ # }
140
+ # verb.response # represents the final xml output
141
+ def gather(*args, &block)
142
+ options = args.shift || {}
143
+ output {
144
+ if block_given?
145
+ @xml.Gather(options) { block.call}
146
+ else
147
+ @xml.Gather(options)
148
+ end
149
+ }
150
+ end
151
+
152
+ #play, say, pause
153
+
154
+ # The Record verb records the caller's voice and returns a URL that links to a file
155
+ # containing the audio recording.
156
+ #
157
+ # Options (see http://www.twilio.com/docs/api_reference/TwiML/record) are passed in as a hash
158
+ #
159
+ # Examples:
160
+ # Twilio::Verb.record
161
+ # Twilio::Verb.record :action => 'http://foobar.com'
162
+ # Twilio::Verb.record :finishOnKey => '*'
163
+ # Twilio::Verb.record :transcribe => true, :transcribeCallback => '/handle_transcribe'
164
+ def record(*args)
165
+ options = args.shift
166
+ output { @xml.Record(options) }
167
+ end
168
+
169
+ # The Dial verb connects the current caller to an another phone. If the called party picks up,
170
+ # the two parties are connected and can communicate until one hangs up. If the called party does
171
+ # not pick up, if a busy signal is received, or the number doesn't exist, the dial verb will finish.
172
+ #
173
+ # If an action verb is provided, Twilio will submit the outcome of the call attempt to the action URL.
174
+ # If no action is provided, Dial will fall through to the next verb in the document.
175
+ #
176
+ # Note: this is different than the behavior of Record and Gather. Dial does not submit back to the
177
+ # current document URL if no action is provided.
178
+ #
179
+ # Options (see http://www.twilio.com/docs/api_reference/TwiML/dial) are passed in as a hash
180
+ #
181
+ # Examples:
182
+ # Twilio::Verb.dial '415-123-4567'
183
+ # Twilio::Verb.dial '415-123-4567', :action => 'http://foobar.com'
184
+ # Twilio::Verb.dial '415-123-4567', :timeout => 10, :callerId => '858-987-6543'
185
+ #
186
+ # Twilio also supports an alternate form in which a Number object is nested inside Dial:
187
+ #
188
+ # verb = Twilio::Verb.new { |v|
189
+ # v.dial { |v|
190
+ # v.number '415-123-4567'
191
+ # v.number '415-123-4568'
192
+ # v.number '415-123-4569'
193
+ # }
194
+ # }
195
+ # verb.response # represents the final xml output
196
+ def dial(*args, &block)
197
+ number_to_dial = ''
198
+ options = {}
199
+ args.each do |arg|
200
+ case arg
201
+ when String
202
+ number_to_dial = arg
203
+ when Hash
204
+ options.merge!(arg)
205
+ else
206
+ raise ArgumentError, 'dial expects String or Hash argument'
207
+ end
208
+ end
209
+
210
+ output {
211
+ if block_given?
212
+ @xml.Dial(options) { block.call }
213
+ else
214
+ @xml.Dial(number_to_dial, options)
215
+ end
216
+ }
217
+ end
218
+
219
+ # The <Dial> verb's <Conference> noun allows you to connect to a conference room.
220
+ # Much like how the <Number> noun allows you to connect to another phone number,
221
+ # the <Conference> noun allows you to connect to a named conference room and talk
222
+ # with the other callers who have also connected to that room.
223
+ #
224
+ # Options (see http://www.twilio.com/docs/api_reference/TwiML/conference) are passed in as a hash
225
+ #
226
+ # Examples:
227
+ # verb = Twilio::Verb.new { |v|
228
+ # v.dial {
229
+ # v.conference 'MyRoom', :muted => true
230
+ # }
231
+ # }
232
+ # verb.response
233
+ def conference(*args)
234
+ conference_name = ''
235
+ options = {}
236
+ args.each do |arg|
237
+ case arg
238
+ when String
239
+ conference_name = arg
240
+ when Hash
241
+ options.merge!(arg)
242
+ else
243
+ raise ArgumentError, 'conference expects String or Hash argument'
244
+ end
245
+ end
246
+
247
+ output { @xml.Conference(conference_name, options)}
248
+ end
249
+
250
+ # The Pause (secondary) verb waits silently for a number of seconds.
251
+ # It is normally chained with other verbs.
252
+ #
253
+ # Options (see http://www.twilio.com/docs/api_reference/TwiML/pause) are passed in as a hash
254
+ #
255
+ # Examples:
256
+ # verb = Twilio::Verb.new { |v|
257
+ # v.say 'greetings'
258
+ # v.pause :length => 2
259
+ # v.say 'have a nice day'
260
+ # }
261
+ # verb.response
262
+ def pause(*args)
263
+ options = args.shift
264
+ output { @xml.Pause(options) }
265
+ end
266
+
267
+ # The Redirect (secondary) verb transfers control to a different URL.
268
+ # It is normally chained with other verbs.
269
+ #
270
+ # Options (see http://www.twilio.com/docs/api_reference/TwiML/redirect) are passed in as a hash
271
+ #
272
+ # Examples:
273
+ # verb = Twilio::Verb.new { |v|
274
+ # v.dial '415-123-4567'
275
+ # v.redirect 'http://www.foo.com/nextInstructions'
276
+ # }
277
+ # verb.response
278
+ def redirect(*args)
279
+ redirect_to_url = ''
280
+ options = {}
281
+ args.each do |arg|
282
+ case arg
283
+ when String
284
+ redirect_to_url = arg
285
+ when Hash
286
+ options.merge!(arg)
287
+ else
288
+ raise ArgumentError, 'dial expects String or Hash argument'
289
+ end
290
+ end
291
+
292
+ output { @xml.Redirect(redirect_to_url, options) }
293
+ end
294
+
295
+ # The <Sms> verb sends a SMS message to a phone number.
296
+ #
297
+ # Options (see http://www.twilio.com/docs/api/2008-08-01/twiml/sms/sms) ars passed in as a hash
298
+ #
299
+ # Examples:
300
+ # verb = Twilio::Verb.new { |v|
301
+ # v.sms 'Meet at South Street'
302
+ # }
303
+ #
304
+ def sms(*args)
305
+ message = ''
306
+ options = {}
307
+ args.each do |arg|
308
+ case arg
309
+ when String
310
+ message = arg
311
+ when Hash
312
+ options.merge!(arg)
313
+ else
314
+ raise ArgumentError, 'sms expects STring or Hash argument'
315
+ end
316
+ end
317
+
318
+ output { @xml.Sms(message, options) }
319
+ end
320
+
321
+ # The Hangup (secondary) verb ends the call.
322
+ #
323
+ # Examples:
324
+ # If your response is only a hangup:
325
+ #
326
+ # Twilio::Verb.hangup
327
+ #
328
+ # If your response is chained:
329
+ #
330
+ # verb = Twilio::Verb.new { |v|
331
+ # v.say "The time is #{Time.now}"
332
+ # v.hangup
333
+ # }
334
+ # verb.response
335
+ def hangup
336
+ output { @xml.Hangup }
337
+ end
338
+
339
+ # The Number element specifies a phone number. The number element has two optional attributes: sendDigits and url.
340
+ # Number elements can only be nested in Dial verbs
341
+ def number(*args)
342
+ number_to_dial = ''
343
+ options = {}
344
+ args.each do |arg|
345
+ case arg
346
+ when String
347
+ number_to_dial = arg
348
+ when Hash
349
+ options.merge!(arg)
350
+ else
351
+ raise ArgumentError, 'dial expects String or Hash argument'
352
+ end
353
+ end
354
+
355
+ output { @xml.Number(number_to_dial, options) }
356
+ end
357
+
358
+
359
+ # The Reject verb refuse the call
360
+ # (see http://www.twilio.com/docs/api/twiml/reject)
361
+ # Examples:
362
+ #
363
+ # Twilio::Verb.reject
364
+ #
365
+ # If reject called with argument:
366
+ #
367
+ # Twilio::Verb.reject :reason => "busy"
368
+ #
369
+ def reject options = {}
370
+ output { @xml.Reject(options) }
371
+ end
372
+
373
+ private
374
+
375
+ def output
376
+ @chain ? yield : @xml.Response { yield }
377
+ end
378
+
379
+ def loop_with_pause(loop_count, xml, &verb_action)
380
+ last_iteration = loop_count-1
381
+ loop_count.times do |i|
382
+ yield verb_action
383
+ xml.Pause unless i == last_iteration
384
+ end
385
+ end
386
+ end
387
+ end
@@ -0,0 +1,3 @@
1
+ module Twilio
2
+ VERSION = "3.0.1"
3
+ end
@@ -0,0 +1,23 @@
1
+ <TwilioResponse>
2
+ <Account>
3
+ <Sid>mysid</Sid>
4
+ <FriendlyName>Do you like my friendly name?</FriendlyName>
5
+ <Status>active</Status>
6
+ <DateCreated>Wed, 04 Aug 2010 21:37:41 +0000</DateCreated>
7
+ <DateUpdated>Fri, 06 Aug 2010 01:15:02 +0000</DateUpdated>
8
+ <AuthToken>mytoken</AuthToken>
9
+ <Uri>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d</Uri>
10
+ <SubresourceUris>
11
+ <AvailablePhoneNumbers>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/AvailablePhoneNumbers</AvailablePhoneNumbers>
12
+ <Calls>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Calls</Calls>
13
+ <Conferences>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Conferences</Conferences>
14
+ <IncomingPhoneNumbers>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/IncomingPhoneNumbers</IncomingPhoneNumbers>
15
+ <Notifications>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Notifications</Notifications>
16
+ <OutgoingCallerIds>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/OutgoingCallerIds</OutgoingCallerIds>
17
+ <Recordings>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Recordings</Recordings>
18
+ <Sandbox>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Sandbox</Sandbox>
19
+ <SMSMessages>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/SMS/Messages</SMSMessages>
20
+ <Transcriptions>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Transcriptions</Transcriptions>
21
+ </SubresourceUris>
22
+ </Account>
23
+ </TwilioResponse>