twilio-rb 1.0beta2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
-
2
1
  # Twilio.rb
3
2
 
4
- Interact with the Twilio API in a nice Ruby way.
3
+ Interact with the Twilio API in a nice Ruby way.
5
4
 
6
5
  Twilio.rb is the only library that encapsulates Twilio resources as Ruby objects, has 100% test coverage, and supports the whole API.
7
6
 
@@ -9,7 +8,7 @@ It offers an ActiveRecord style API, i.e. one that most Ruby developers are fami
9
8
 
10
9
  ## Installation
11
10
 
12
- The library has been packaged as a gem and is available from rubygems.org. The version that this readme pertains to is 1.0beta. To install use the `--pre` flag
11
+ The library has been packaged as a gem and is available from rubygems.org. The version that this readme pertains to is 2.0.0.
13
12
 
14
13
  <pre>gem install twilio-rb --pre</pre>
15
14
 
@@ -19,49 +18,146 @@ Please use the Github issue tracker to report any issues or bugs you uncover.
19
18
 
20
19
  Require the library in your script as
21
20
 
22
- <pre>require 'twilio'</pre>
21
+ <pre>require 'twilio-rb'</pre>
23
22
 
24
23
  or using bundler:
25
24
 
26
- <pre>gem 'twilio-rb', '1.0beta', :require => 'twilio'</pre>
25
+ <pre>gem 'twilio-rb'</pre>
27
26
 
28
27
  ## Configuration
29
28
 
30
- Configuration for this library is encapsulated within `Twilio::Config`. One needs to setup with an Account SID and an Auth Token, e.g.
29
+ Configuration for this library is achieved with `Twilio::Config.setup`. One needs to setup with an Account SID and an Auth Token, e.g.
31
30
 
32
31
  <pre># This should be in an initializer or similar
33
- Twilio::Config.setup do
34
- account_sid 'AC0000000000000000000000000000'
35
- auth_token '000000000000000000000000000000'
32
+ Twilio::Config.setup \
33
+ :account_sid => 'AC0000000000000000000000000000',
34
+ :auth_token => '000000000000000000000000000000'
36
35
  end</pre>
37
36
 
38
37
  Any method that calls the Twilio API will raise `Twilio::ConfigurationError` if either Account SID or Auth Token are not configured.
39
38
 
40
39
  # Getting started
41
40
 
41
+ ## Summary
42
+
43
+ Twilio resources are represented as Ruby objects. List resources are represnted by classes, e.g. `Twilio::SMS` and operations on list resources are performed using class methods, e.g. `Twilio::SMS.create`. Resource instances are represented by instances of those classes, and operations on those resource instances are perfomed using instance methods.
44
+
45
+ Resources that can be created via the API, using the HTTP POST verb can be done so in the library using the `.create` class method, e.g.
46
+
47
+ <pre>Twilio::Call.create :to => '+16465551234', :from => '+19175550000',
48
+ :url => "http://example.com/call_handler"</pre>
49
+
50
+ Resources that can be removed via the API, using the HTTP DELETE verb can be done so in the library using the `#destroy` instance method, e.g.
51
+
52
+ <pre>
53
+ # Delete all log entries
54
+ Twilio::Notification.all.each &:destroy
55
+ </pre>
56
+
57
+ Object representations instantiated by the library respond to all methods that match attributes on its corresponding resource. The method names are those of the parameters in snake case (underscored), i.e. as they are returned in the JSON representation.
58
+
59
+ The Twilio API documentation itself is the canonical reference for which resources have what properties, and which of those can be updated by the API. Please refer to the Twilio REST API documentation for thos information.
60
+
61
+ ## Accessing resource instances
62
+
63
+ Resource instances can be accessed ad hoc passsing the resource sid to the `.find` class method on the resource class, e.g.
64
+
65
+ <pre>call = Twilio::Call.find 'CAe1644a7eed5088b159577c5802d8be38'</pre>
66
+
67
+ This will return an instance of the resource class, in this case `Twilio::Call`, with the attributes of the resource. These attributes are accessed using dynamically defined getter methods, where the method name is the attribute name underscored, i.e. as they are returned in a JSON response from the API.
68
+
69
+ Sometimes these method name might collide with native Ruby methods, one such example is the `method` parameter colliding with `Object#method`. Native Ruby methods are never overridden by the library as they are lazily defined using `method_missing`. To access these otherwise unreachable attributes, there is another syntax for accessing resource attributes:
70
+
71
+ <pre>
72
+ call = Twilio::Call.find 'CAe1644a7eed5088b159577c5802d8be38'
73
+ call[:method] # With a symbol or
74
+ call['method'] # or with a string. Access is indifferent.
75
+ </pre>
76
+
77
+ ## Querying list resources
78
+
79
+ List resources can be accessed ad hoc by calling the `.all` class method on the resource class, e.g.
80
+
81
+ <pre>calls = Twilio::Call.all</pre>
82
+
83
+ This will return a collection of objects, each a representation of the corresponding resource.
84
+
85
+ ### Using filter parameters to refine a query
86
+
87
+ The `.all` class method will ask Twilio for all resource instances on that list resource, this can easily result in a useless response if there are numerous resource instances on a given resource. The `.all` class method accepts a hash of options for parameters to filter the response, e.g.
88
+
89
+ <pre>Twilio::Call.all :to => '+19175550000', :status => 'complete'</pre>
90
+
91
+ Twilio does some fancy stuff to implement date ranges, consider the API request:
92
+
93
+ <pre>GET /2010-04-01/Accounts/AC5ef87.../Calls?StartTime&gt;=2009-07-06&EndTime&lt;=2009-07-10</pre>
94
+
95
+ This will return all calls started after midnight July 06th 2009 and completed before July 10th 2009. Any call started and ended within that time range matches those criteria and will be returned. To make the same reqest using this library:
96
+
97
+ <pre>
98
+ require 'date'
99
+ start_date, end_date = Date.parse('2009-07-06'), Date.parse('2009-07-10')
100
+
101
+ Twilio::Call.all :started_after => start_date, :ended_before => end_date
102
+ </pre>
103
+
104
+ All option parameters pertaining to dates accept a string or any object that returns a RFC 2822 date when `#to_s` is called on it, e.g. an instance of `Date`. If a date parameter is not a rnage but absolute, one can of course use the normal option, e.g.
105
+
106
+ <pre>Twilio::Call.all :start_time => start_date</pre>
107
+
108
+ The key names for these Date filters are inconsistent across resources, in the library they are:
109
+
110
+ <pre>
111
+ Twilio::SMS.all :created_before => date, :created_after => date, :sent_before => date, :sent_after # :"created_#{when}" and :"sent_#{when}" are synonomous
112
+ Twilio::Notification.all :created_before => date, :created_after => date
113
+ Twilio::Call.all :started_before => date, :started_after => date, :ended_before => date, :ended_after => date
114
+ </pre>
115
+
116
+ ### Pagination
117
+
118
+ The Twilio API paginates API responses and by default it will return 30 objects in one response, this can be overridden to return up to a maximum of 1000 per response using the `:page_size` option, If more than 1000 resources instances exist, the `:page` option is available, e.g.
119
+
120
+ <pre>Twilio::Call.all :started_after => start_date, :ended_before => end_date, :page_size => 1000, :page => 7</pre>
121
+
122
+ To determine how many resources exist, the `.count` class method exists, which accepts the same options as `.all` in order to constrain the query e.g.
123
+
124
+ <pre>Twilio::Call.count :started_after => start_date, :ended_before => end_date</pre>
125
+
126
+ It returns an integer corresponding to how many resource instances exist with those conditions.
127
+
128
+ ## Updating resource attributes
129
+
130
+ Certain resources have attributes that can be updated with the REST API. Instances of those resources can be updated using either a setter method with a name that corresponds to the attribute, or by using the `#update_attributes`.
131
+
132
+ <pre>
133
+ call = Twilio::Call.all(:status => 'in-progress').first
134
+
135
+ call.url = 'http://example.com/in_ur_apiz_hijackin_ur_callz.xml'
136
+ call.update_attributes :url => 'http://example.com/in_ur_apiz_hijackin_ur_callz.xml'
137
+ </pre>
138
+
139
+ These are both equivalent, i.e. they immediately make an API request and update the state of the object with the API response. The first one in fact uses the second one internally and is just a shortcut. Use the second when there is more than one attribute to be updated in the same HTTP request.
140
+
42
141
  ## Making a telephone call
43
142
 
44
143
  The API used to make a telephone call is similar to interacting with an ActiveRecord model object.
45
- <pre>Twilio::Call.create :to => '+16465551234', :from => '+19175550000',
144
+ <pre>Twilio::Call.create :to => '+16465551234', :from => '+19175550000',
46
145
  :url => "http://example.com/call_handler"</pre>
47
146
 
48
147
  The parameter keys should be given as underscored symbols. They will be converted internally to camelized strings prior to an API call being made.
49
148
 
50
- Please see the Twilio REST API documentation for an up to date list of supported parameters.
149
+ Please see the Twilio REST API documentation for an up to date list of supported parameters.
51
150
 
52
151
  If the request was successful, an instance of `Twilio::Call` wil be returned
53
152
 
54
153
  ### Modifying a live telephone call
55
154
 
56
- Once a call has been been created it can be modified with the following methods:
155
+ As well as the the aforementioned setter methods, once a call has been been created it can be modified with the following convenience methods:
57
156
 
58
157
  `Twilio::Call#cancel!` will terminate the call if its state is `queued` or `ringing`
59
158
  `Twilio::Call#complete!` will terminate the call even if its state is `in-progress`
60
159
  `Twilio::Call#url=` will immediately redirect the call to a new handler URL
61
160
 
62
- `Twilio::Call#cancel!` and `Twilio::Call#complete!` will raise `Twilio::InvalidStateError` if the call has not been "saved".
63
- `Twilio::Call#url=` will updated its state with the new URL ready for when `Twilio::Call#save` is called.
64
-
65
161
  ## Finding an existing telephone call
66
162
 
67
163
  To retrieve an earlier created call, there is the `Twilio::Call.find` method, which accepts a call SID, e.g.
@@ -73,7 +169,7 @@ This returns an instance of `Twilio::Call` if a call with the given SID was foun
73
169
  ## Sending an SMS message
74
170
 
75
171
  The API used to send an SMS message is similar to interacting with an ActiveRecord model object.
76
- <pre>Twilio::SMS.create :to => '+16465551234', :from => '+19175550000',
172
+ <pre>Twilio::SMS.create :to => '+16465551234', :from => '+19175550000',
77
173
  :body => "Hey baby, how was your day? x"</pre>
78
174
 
79
175
  The parameter keys should be given as underscored symbols. They will be converted internally to camelized strings prior to an API call being made.
@@ -82,7 +178,7 @@ Please see the Twilio REST API documentation for an up to date list of supported
82
178
 
83
179
  If the request was successful, an instance of `Twilio::SMS` wil be returned
84
180
 
85
- ## Finding an existing telephone SMS message
181
+ ## Finding an existing SMS message
86
182
 
87
183
  To retrieve an earlier created SMS message, there is the `Twilio::SMS.find` method, which accepts a SMS message SID, e.g.
88
184
 
@@ -90,13 +186,95 @@ To retrieve an earlier created SMS message, there is the `Twilio::SMS.find` meth
90
186
 
91
187
  This returns an instance of `Twilio::SMS` if a SMS message with the given SID was found, otherwise nil is returned
92
188
 
189
+ # Twilio Client
190
+
191
+ To generate capability tokens for use with Twilio Client you can use `Twilio::CapabilityToken.create`
192
+
193
+ <pre>
194
+ Twilio::CapabilityToken.create \
195
+ allow_incoming: 'unique_identifier_for_this_user',
196
+ allow_outgoing: 'your_application_sid'
197
+ </pre>
198
+
199
+ You can create capability tokens on arbitrary accounts, e.g. subaccounts. Just pass in those details:
200
+
201
+ <pre>
202
+ Twilio::CapabilityToken.create \
203
+ account_sid: 'AC00000000000000000000000',
204
+ auth_token: 'XXXXXXXXXXXXXXXXXXXXXXXXX',
205
+ allow_incoming: 'unique_identifier_for_this_user',
206
+ allow_outgoing: 'your_application_sid'
207
+ </pre>
208
+
209
+ You can also pass arbitrary parameters into your outgoing privilege, these are sent from Twilio as HTTP request params when it hits your app endpoint for TwiML.
210
+
211
+ <pre>
212
+ Twilio::CapabilityToken.create allow_outgoing: ['your_application_sid', { :foo => 'bar' }]
213
+ </pre>
214
+
215
+ By default tokens expire exactly one hour from the time they are generated. You can choose your own token ttl like so:
216
+
217
+ <pre>
218
+ Twilio::CapabilityToken.create \
219
+ allow_incoming: 'unique_identifier_for_this_user',
220
+ allow_outgoing: 'your_application_sid',
221
+ expires: 10.minutes.from_now
222
+ </pre>
223
+
224
+ # Associations
225
+
226
+ Certain resources themselves have subresources, e.g. a call can have many recordings. It would be very convenient to access these via an association proxy, so instead of:
227
+
228
+ <pre>
229
+ calls = Twilio::Call.all
230
+ recordings = Twilio::Recording.all :call_sid => calls.last.sid
231
+ </pre>
232
+
233
+ You might prefer:
234
+
235
+ <pre>
236
+ calls = Twilio::Call.all
237
+ recordings = calls.recordings.all
238
+ </pre>
239
+
240
+ twilio-rb now supports these association proxies
241
+
242
+ # Subaccounts
243
+
244
+ The Twilio REST API supports subaccounts that is discrete accounts owned by a master account. twilio-rb supports this too.o
245
+
246
+ ## Subaccount creation
247
+
248
+ You can create new subaccounts by using `Twilio::Account.create`
249
+
250
+ ## Performing actions on resources belonging to subaccounts
251
+
252
+ There are three ways to perform an operation on an account other than the master account: you can pass in the subaccount sid
253
+
254
+ <pre>Twilio::SMS.create :to => '+19175551234' :from => '+16465550000',
255
+ :body => 'This will be billed to a subaccount, sucka!' :account => 'ACXXXXXXXXXXXXXXXXXXXXXXXX'</pre>
256
+
257
+ You can also pass in an object that responds to sid, i.e. an instance of Twilio::Account
258
+
259
+ <pre>Twilio::SMS.create :to => '+19175551234' :from => '+16465550000',
260
+ :body => 'This TOO will be billed to a subaccount, sucka!' :account => my_subaccount_object</pre>
261
+
262
+ By using an association proxy. By chaining the list resource methods, e.g. find, create, etc, on the association proxy, they are scoped to that account
263
+
264
+ <pre>
265
+ bobs_account = Twilio::Account.find :friendly_name => "Bob's subaccount"
266
+
267
+ # This will send a SMS message on Bob's subaccount
268
+ bobs_account.sms.create :to => '+16465551234', :from => '+19175550000', :body => "Bob is paying for this text. What a guy!"
269
+ </pre>
270
+
93
271
  # Building TwiML documents
94
272
 
95
273
  A TwiML document is an XML document. The best way to build XML in Ruby is with Builder, and so it follows that we should use builder for TwiML. `Twilio::TwiML.build` behaves like builder except element names are capitalised for you and attributes are camelized for you as well. This is so you may continue to write beautiful code.
96
274
 
97
275
  The following Ruby code:
98
276
 
99
- <pre>Twilio::TwiML.build do |res|
277
+ <pre>Twilio::TwiML.build do |res|
100
278
  res.say 'Hey man! Listen to this!', :voice => 'man'
101
279
  res.play 'http://foo.com/cowbell.mp3'
102
280
  res.say 'What did you think of that?!', :voice => 'man'
@@ -151,109 +329,6 @@ res.say 'Damn this library is so ill dude!'
151
329
 
152
330
  It's now easier than ever to integrate Twilio in your Rails app cleanly and easily.
153
331
 
154
- # Basics
155
-
156
- Each super-resource, e.g. Calls, OutgoingCallerIds, etc has a Ruby object in the Twilio namespace representing it, Twilio::Call, Twilio::OutgoingCallerId, etc.
157
-
158
- ## Summary
159
-
160
- Resources that can be created via the API, using the HTTP POST verb can be done so in the library using the `.create` class method, e.g.
161
-
162
- <pre>Twilio::Call.create :to => '+16465551234', :from => '+19175550000',
163
- :url => "http://example.com/call_handler"</pre>
164
-
165
- Resources that can be removed via the API, using the HTTP DELETE verb can be done so in the library using the `#destroy` instance method, e.g.
166
-
167
- <pre>
168
- # Delete all log entries
169
- Twilio::Notification.all.each &:destroy
170
- </pre>
171
-
172
- Object representations instantiated by the library respond to all methods that match attributes on its corresponding resource. The method names are those of the parameters in snake case (underscored), i.e. as they are returned in the JSON representation.
173
-
174
- The Twilio API documentation itself is the canonical reference for which resources have what properties, and which of those can be updated by the API. Please refer to the Twilio REST API documentation for thos information.
175
-
176
- ## Accessing resource instances
177
-
178
- Resource instances can be accessed ad hoc passsing the resource sid to the `.find` class method on the resource class, e.g.
179
-
180
- <pre>call = Twilio::Call.find 'CAe1644a7eed5088b159577c5802d8be38'</pre>
181
-
182
- This will return an instance of the resource class, in this case `Twilio::Call`, with the attributes of the resource. These attributes are accessed using dynamically defined getter methods, where the method name is the attribute name underscored, i.e. as they are returned in a JSON response from the API.
183
-
184
- Sometimes these method name might collide with native Ruby methods, one such example is the `method` parameter colliding with `Object#method`. Native Ruby methods are never overridden by the library as they are lazily defined using `method_missing`. To access these otherwise unreachable attributes, there is another syntax for accessing resource attributes:
185
-
186
-
187
- <pre>
188
- call = Twilio::Call.find 'CAe1644a7eed5088b159577c5802d8be38'
189
- call[:method] # With a symbol or
190
- call['method'] # or with a string. Access is indifferent.
191
- </pre>
192
-
193
- ## Querying list resources
194
-
195
- List resources can be accessed ad hoc by calling the `.all` class method on the resource class, e.g.
196
-
197
- <pre>calls = Twilio::Call.all</pre>
198
-
199
- This will return a collection of objects, each a representation of the corresponding resource.
200
-
201
- ### Using filter parameters to refine a query
202
-
203
- The `.all` class method will ask Twilio for all resource instances on that list resource, this can easily result in a useless response if there are numerous resource instances on a given resource. The `.all` class method accepts a hash of options for parameters to filter the response, e.g.
204
-
205
- <pre>Twilio::Call.all :to => '+19175550000', :status => 'complete'</pre>
206
-
207
- Twilio does some fancy stuff to implement date ranges, consider the API request:
208
-
209
- <pre>GET /2010-04-01/Accounts/AC5ef87.../Calls?StartTime&gt;=2009-07-06&EndTime&lt;=2009-07-10</pre>
210
-
211
- This will return all calls started after midnight July 06th 2009 and completed before July 10th 2009. Any call started and ended within that time range matches those criteria and will be returned. To make the same reqest using this library:
212
-
213
- <pre>
214
- require 'date'
215
- start_date, end_date = Date.parse('2009-07-06'), Date.parse('2009-07-10')
216
-
217
- Twilio::Call.all :started_after => start_date, :ended_before => end_date
218
- </pre>
219
-
220
- All option parameters pertaining to dates accept a string or any object that returns a RFC 2822 date when `#to_s` is called on it, e.g. an instance of `Date`. If a date parameter is not a rnage but absolute, one can of course use the normal option, e.g.
221
-
222
- <pre>Twilio::Call.all :start_time => start_date</pre>
223
-
224
- The key names for these Date filters are inconsistent across resources, in the library they are:
225
-
226
- <pre>
227
- Twilio::SMS.all :created_before => date, :created_after => date, :sent_before => date, :sent_after # :"created_#{when}" and :"sent_#{when}" are synonomous
228
- Twilio::Notification.all :created_before => date, :created_after => date
229
- Twilio::Call.all :started_before => date, :started_after => date, :ended_before => date, :ended_after => date
230
- </pre>
231
-
232
- ### Pagination
233
-
234
- The Twilio API paginates API responses and by default it will return 30 objects in one response, this can be overridden to return up to a maximum of 1000 per response using the `:page_size` option, If more than 1000 resources instances exist, the `:page` option is available, e.g.
235
-
236
- <pre>Twilio::Call.all :started_after => start_date, :ended_before => end_date, :page_size => 1000, :page => 7</pre>
237
-
238
- To determine how many resources exist, the `.count` class method exists, which accepts the same options as `.all` in order to constrain the query e.g.
239
-
240
- <pre>Twilio::Call.count :started_after => start_date, :ended_before => end_date</pre>
241
-
242
- It returns an integer corresponding to how many resource instances exist with those conditions.
243
-
244
- ## Updating resource attributes
245
-
246
- Certain resources have attributes that can be updated with the REST API. Instances of those resources can be updated using either a setter method with a name that corresponds to the attribute, or by using the `#update_attributes`.
247
-
248
- <pre>
249
- call = Twilio::Call.all(:status => 'in-progress').first
250
-
251
- call.url = 'http://example.com/in_ur_apiz_hijackin_ur_callz.xml'
252
- call.update_attributes :url => 'http://example.com/in_ur_apiz_hijackin_ur_callz.xml'
253
- </pre>
254
-
255
- These are both equivalent, i.e. they immediately make an API request and update the state of the object with the API response. The first one in fact uses the second one internally and is just a shortcut. Use the second when there is more than one attribute to be updated in the same HTTP request.
256
-
257
332
  ## Manipulating conference participants
258
333
 
259
334
  The participants list resource is a subresource of a conference resource instance:
@@ -272,26 +347,17 @@ Participants can be removed from the conference using the '#destroy instance met
272
347
 
273
348
  # Singleton resources
274
349
 
275
- The Twilio API in its current incarnation has two singleton (scoped per account) resources, correspondingly there are the Twilio::Account, and Twilio::Sandbox singleton objects.
350
+ The Twilio API in its current incarnation has one singleton (scoped per account) resource, correspondingly there is Twilio::Sandbox singleton objects.
276
351
 
277
352
  To access properties of a singleton object the property name should be called as a method on the object itself, e.g.
278
353
 
279
- <pre>Twilio::Account.friendly_name</pre>
354
+ <pre>Twilio::Sandobox.friendly_name</pre>
280
355
 
281
356
  The first time a method is invoked on the object an API call is made to retrieve the data. The methods themselves are not defined until they are called, i.e. lazy evaluation. This strategy means that addtional properties added to subsequent versions of the API should not break the library.
282
357
 
283
358
  To reload the data when needed `Twilio::Account.reload!` will make another API call and update its own internal state.
284
359
 
285
- The account has a predicate method i.e. ending in `?`, it maps directly to the status of the account, e.g. `Twilio::Account.suspended?` returns true if Twilio have suspended your account. Again, this is defined on the fly.
286
-
287
- The only account property that can be modified via the REST API is the friendly name, e.g.
288
-
289
- <pre>Twilio::Account.friendly_name = "I'm so vain, I had to change my name!"</pre>
290
- <pre>Twilio::Account.update_attributes :friendly_name => "I'm so vain, I had to change my name!"</pre>
291
-
292
- This will update the API immediately with a POST request.
293
-
294
- Twilio::Sandbox supports more options. Please refer to the Twilio REST API documentation for an up to date list of properties.
360
+ Please refer to the Twilio REST API documentation for an up to date list of properties that the sandbox resource implements
295
361
 
296
362
  # Searching for and purchasing available phone numbers
297
363
 
@@ -311,6 +377,11 @@ Twilio::IncomingPhoneNumber.create :phone_number => numbers.first.phone_number,
311
377
 
312
378
  # Recordings
313
379
 
314
- A recording resource instance has an extra instance method: `#mp3` this returns a publicly accessible URL for the MP3 representation of the resource instance.
380
+ A recording resource instance has an extra instance method: `#mp3` this returns a publicly accessible URL for the MP3 representation of the resource instance.
315
381
 
382
+ # Contributors
316
383
 
384
+ * Stevie Graham
385
+ * TJ Singleton
386
+ * Christopher Durtschi
387
+ * Dan Imrie-Situnayake
data/lib/railtie.rb CHANGED
@@ -11,7 +11,7 @@ module Twilio
11
11
  def compile(template)
12
12
  <<-EOS
13
13
  controller.content_type = 'text/xml'
14
- Twilio::TwiML.build {|res| #{template.source} }
14
+ Twilio::TwiML.build { |res| #{template.source} }
15
15
  EOS
16
16
  end
17
17
  end
@@ -19,6 +19,8 @@ module Twilio
19
19
  end
20
20
  end
21
21
 
22
+ ActionController::Base.class_eval { before_filter Twilio::RequestFilter }
23
+
22
24
  ::ActionView::Template.register_template_handler(:voice, ActionView::Template::Handlers::TwiML)
23
25
  ::Mime::Type.register_alias 'text/xml', :voice
24
26
  end
@@ -1,25 +1,22 @@
1
1
  module Twilio
2
- module Account
2
+ class Account
3
3
  include Twilio::Resource
4
- @attributes = {}.with_indifferent_access
4
+ include Twilio::Persistable
5
+ extend Twilio::Associations
6
+ extend Twilio::Finder
5
7
 
6
- def attributes
7
- @attributes.empty? ? reload! : @attributes
8
- end
8
+ mutable_attributes :friendly_name, :status
9
9
 
10
- def reload!
11
- handle_response get path
12
- end
10
+ has_many :calls, :sms, :recordings, :conferences, :incoming_phone_numbers,
11
+ :notifications, :outgoing_caller_ids, :transcriptions
13
12
 
14
- def friendly_name=(name)
15
- update_attributes :friendly_name => name
13
+ class << self
14
+ private
15
+ def resource_path(account_sid)
16
+ "/Accounts"
17
+ end
16
18
  end
17
19
 
18
- private
19
- def path
20
- "/Accounts/#{Twilio::ACCOUNT_SID}.json"
21
- end
22
-
23
- extend self
24
20
  end
25
21
  end
22
+
@@ -0,0 +1,14 @@
1
+ module Twilio
2
+ class Application
3
+ extend Twilio::Finder
4
+ include Twilio::Resource
5
+ include Twilio::Persistable
6
+ include Twilio::Deletable
7
+
8
+ mutable_attributes :friendly_name, :api_version, :voice_url, :voice_method, :voice_fallback_url,
9
+ :voice_fallback_method, :status_callback, :status_callback_method, :sms_url, :sms_method,
10
+ :sms_fallback_url, :sms_fallback_method
11
+
12
+ end
13
+ end
14
+
@@ -0,0 +1,22 @@
1
+ require 'active_support/core_ext/string'
2
+
3
+ module Twilio
4
+ class AssociationProxy
5
+ instance_methods.each { |meth| undef_method meth unless meth.to_s =~ /^__/ }
6
+ def initialize(delegator, target)
7
+ @delegator, @target = delegator, target
8
+ @delegator_name = @delegator.class.name.demodulize.downcase
9
+ end
10
+
11
+ def inspect
12
+ @target.all :"#{@delegator_name}_sid" => @delegator.sid
13
+ end
14
+
15
+ def method_missing(meth, *args, &blk)
16
+ options = args.empty? ? args.<<({})[-1] : args[-1]
17
+ options.update :"#{@delegator_name}_sid" => @delegator.sid
18
+ @target.__send__ meth, *args, &blk
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,14 @@
1
+ require 'active_support/core_ext/string'
2
+
3
+ module Twilio
4
+ module Associations
5
+ def has_many(*collection)
6
+ collection.each do |objects|
7
+ define_method(objects) do
8
+ klass = Twilio.const_get objects.to_s.singularize.camelize
9
+ Twilio::AssociationProxy.new self, klass
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
data/lib/twilio/call.rb CHANGED
@@ -2,7 +2,12 @@ module Twilio
2
2
  class Call
3
3
  include Twilio::Resource
4
4
  include Twilio::Persistable
5
- extend Twilio::Finder
5
+ extend Twilio::Finder
6
+ extend Twilio::Associations
7
+
8
+ has_many :recordings
9
+
10
+ mutable_attributes :url, :method, :status
6
11
 
7
12
  class << self
8
13
  alias old_create create
@@ -17,11 +22,10 @@ module Twilio
17
22
  private
18
23
  def prepare_params(opts) # :nodoc:
19
24
  pairs = opts.map do |k,v|
20
- if [:started_before, :started_after, :ended_before, :ended_after].include? k
21
- k = k.to_s
25
+ if %w(started_before started_after ended_before ended_after).include? k
22
26
  # Fancy schmancy-ness to handle Twilio <= URI operator for dates
23
27
  comparator = k =~ /before$/ ? '<=' : '>='
24
- delineator = k =~ /started/ ? 'Start' : 'End'
28
+ delineator = k =~ /started/ ? 'Start' : 'End'
25
29
  CGI.escape(delineator << "Time" << comparator << v.to_s)
26
30
  else
27
31
  "#{k.to_s.camelize}=#{CGI.escape v.to_s}"
@@ -40,11 +44,5 @@ module Twilio
40
44
  update_attributes :status => 'completed'
41
45
  end
42
46
 
43
- # Update Handler URL
44
- def url=(url)
45
- # If this attribute exists it is assumed the API call to create a call has been made, so we need to tell Twilio.
46
- update_attributes :url => url if self[:status]
47
- self[:url] = url
48
- end
49
47
  end
50
- end
48
+ end
@@ -0,0 +1,51 @@
1
+ module Twilio
2
+ module CapabilityToken
3
+ def create(opts={})
4
+ opts.stringify_keys!
5
+ account_sid, auth_token = *credentials_for(opts)
6
+ payload = {
7
+ :exp => (opts.delete('expires') || 1.hour.from_now).to_i,
8
+ :scope => opts.map { |k,v| send k, v, opts }.join(' '),
9
+ :iss => account_sid
10
+ }
11
+ JWT.encode payload, auth_token
12
+ end
13
+
14
+ private
15
+
16
+ def credentials_for(opts)
17
+ if opts['account_sid'] && opts['auth_token']
18
+ [opts.delete('account_sid'), opts.delete('auth_token')]
19
+ else
20
+ [Twilio::ACCOUNT_SID, Twilio::AUTH_TOKEN]
21
+ end
22
+ end
23
+
24
+ def allow_incoming(client_id, opts)
25
+ token_for 'client', 'incoming', { 'clientName' => client_id }
26
+ end
27
+
28
+ def allow_outgoing(payload, opts)
29
+ p = {}
30
+ if payload.respond_to? :each
31
+ p['appSid'] = payload.shift
32
+ p['appParams'] = uri_encode payload.pop
33
+ else # it's a string
34
+ p['appSid'] = payload
35
+ end
36
+ p['clientName'] = opts['allow_incoming'] if opts['allow_incoming']
37
+ token_for 'client', 'outgoing', p
38
+ end
39
+
40
+ def uri_encode(hash)
41
+ hash.map { |k,v| "#{CGI.escape k.to_s}=#{CGI.escape v}" }.join '&'
42
+ end
43
+
44
+ def token_for(service, privilege, params = {})
45
+ token = "scope:#{service}:#{privilege}"
46
+ token << "?#{uri_encode params}" if params.any?
47
+ end
48
+
49
+ extend self
50
+ end
51
+ end
data/lib/twilio/config.rb CHANGED
@@ -1,7 +1,16 @@
1
1
  module Twilio
2
2
  module Config
3
- def setup &blk
4
- instance_eval &blk
3
+ def setup(opts={}, &blk)
4
+ if block_given?
5
+ instance_eval &blk
6
+ warn 'The block syntax for configuration is deprecated. Use an options hash instead, e.g. Twilio::Config.setup account_sid: "AC00000000000000000000000", auth_token: "xxxxxxxxxxxxxxxxxxx"'
7
+ else
8
+ opts.map do |k,v|
9
+ const = k.to_s.upcase
10
+ Twilio.const_set(const, v) unless Twilio.const_defined? const
11
+ end
12
+ end
13
+
5
14
  end
6
15
 
7
16
  def method_missing(meth, *args, &blk)
@@ -11,4 +20,4 @@ module Twilio
11
20
 
12
21
  extend self
13
22
  end
14
- end
23
+ end
data/lib/twilio/finder.rb CHANGED
@@ -1,7 +1,10 @@
1
1
  module Twilio
2
2
  module Finder
3
- def find(id)
4
- res = get "/Accounts/#{Twilio::ACCOUNT_SID}/#{resource_fragment}/#{id}.json"
3
+ def find(id, opts={})
4
+ opts = opts.with_indifferent_access
5
+ # Support subaccounts by optionally passing in an account_sid or account object
6
+ account_sid = opts.delete('account_sid') || opts.delete('account').try(:sid) || Twilio::ACCOUNT_SID
7
+ res = get "#{resource_path(account_sid)}/#{id}.json"
5
8
  hash = res.parsed_response
6
9
  if (200..299).include? res.code
7
10
  hash['api_version'] = hash['api_version'].to_s # api_version parsed as a date by http_party
@@ -10,27 +13,34 @@ module Twilio
10
13
  end
11
14
 
12
15
  def count(opts={})
13
- params = prepare_params opts if opts.any?
14
- get("/Accounts/#{Twilio::ACCOUNT_SID}/#{resource_fragment}.json#{params}").parsed_response['total']
16
+ opts = opts.with_indifferent_access
17
+ # Support subaccounts by optionally passing in an account_sid or account object
18
+ account_sid = opts.delete('account_sid') || opts.delete('account').try(:sid) || Twilio::ACCOUNT_SID
19
+ params = prepare_params opts if opts.any?
20
+ get("#{resource_path(account_sid)}.json#{params}").parsed_response['total']
15
21
  end
16
22
 
17
23
  def all(opts={})
18
- params = prepare_params opts if opts.any?
19
- handle_response get "/Accounts/#{Twilio::ACCOUNT_SID}/#{resource_fragment}.json#{params}"
24
+ opts = opts.with_indifferent_access
25
+ # Support subaccounts by optionally passing in an account_sid or account object
26
+ account_sid = opts.delete('account_sid') || opts.delete('account').try(:sid) || Twilio::ACCOUNT_SID
27
+ params = prepare_params opts if opts.any?
28
+ handle_response get "#{resource_path(account_sid)}.json#{params}"
20
29
  end
21
30
 
22
31
  private
23
32
 
24
- def resource_fragment # :nodoc:
25
- # All Twilio resources follow a convention, except SMS :(
26
- klass_name = name.demodulize
27
- resource = klass_name == 'SMS' ? "#{klass_name}/Messages" : klass_name.pluralize
33
+ def resource_path(account_sid)
34
+ "/Accounts/#{account_sid}/#{resource_name}"
35
+ end
36
+
37
+ def resource_name
38
+ name.demodulize.pluralize
28
39
  end
29
40
 
30
41
  def prepare_params(opts) # :nodoc:
31
42
  pairs = opts.map do |k,v|
32
- if [:updated_before, :created_before, :updated_after, :created_after].include? k
33
- k = k.to_s
43
+ if %w(updated_before created_before updated_after created_after).include? k
34
44
  # Fancy schmancy-ness to handle Twilio <= URI operator for dates
35
45
  comparator = k =~ /before$/ ? '<=' : '>='
36
46
  CGI.escape("Date" << k.gsub(/\_\w+$/, '').capitalize << comparator << v.to_s)
@@ -5,10 +5,9 @@ module Twilio
5
5
  include Twilio::Persistable
6
6
  include Twilio::Deletable
7
7
 
8
- %w<friendly_name api_version voice_url voice_method voice_fallback_url voice_fallback_method status_callback status_callback_method sms_url sms_method sms_fallback_url sms_fallback_method voice_caller_id_lookup>.each do |meth|
9
- define_method "#{meth}=" do |arg|
10
- update_attributes meth => arg
11
- end
12
- end
8
+ mutable_attributes :friendly_name, :api_version, :voice_url, :voice_method,
9
+ :voice_fallback_url, :voice_fallback_method, :status_callback, :status_callback_method,
10
+ :sms_url, :sms_method, :sms_method, :sms_fallback_url, :sms_fallback_method, :voice_caller_id_lookup
11
+
13
12
  end
14
13
  end
@@ -8,8 +8,7 @@ module Twilio
8
8
  private
9
9
  def prepare_params(opts) # :nodoc:
10
10
  pairs = opts.map do |k,v|
11
- if [:created_before, :created_after].include? k
12
- k = k.to_s
11
+ if %w(created_before created_after).include? k
13
12
  # Fancy schmancy-ness to handle Twilio <= URI operator for dates
14
13
  comparator = k =~ /before$/ ? '<=' : '>='
15
14
  CGI.escape("MessageDate" << comparator << v.to_s)
@@ -5,8 +5,6 @@ module Twilio
5
5
  include Twilio::Persistable
6
6
  extend Twilio::Finder
7
7
 
8
- def friendly_name=(value)
9
- update_attributes :friendly_name => value
10
- end
8
+ mutable_attributes :friendly_name
11
9
  end
12
10
  end
@@ -3,6 +3,8 @@ module Twilio
3
3
  include Twilio::Resource
4
4
  include Twilio::Deletable
5
5
 
6
+ mutable_attributes :muted
7
+
6
8
  alias kick! destroy
7
9
 
8
10
  def mute!
@@ -2,23 +2,31 @@ module Twilio
2
2
  module Persistable
3
3
 
4
4
  def self.included(base)
5
- base.class_eval do
6
- class << base
7
- def create(attrs={})
8
- # All Twilio resources follow a convention, except SMS :(
9
- resource = name.demodulize
10
- resource = name == 'Twilio::SMS' ? "SMS/Messages" : resource + 's'
11
- res = post "/Accounts/#{Twilio::ACCOUNT_SID}/#{resource}.json", :body => Hash[attrs.map { |k,v| [k.to_s.camelize, v]}]
12
- if (400..599).include? res.code
13
- raise Twilio::APIError.new "Error ##{res.parsed_response['code']}: #{res.parsed_response['message']}"
14
- else
15
- res.parsed_response['api_version'] = res.parsed_response['api_version'].to_s
16
- new res.parsed_response
17
- end
5
+ base.instance_eval do
6
+ def create(attrs={})
7
+ attrs = attrs.with_indifferent_access
8
+ # Support subaccounts by optionally passing in an account_sid or account object
9
+ account_sid = attrs.delete('account_sid') || attrs.delete('account').try(:sid) || Twilio::ACCOUNT_SID
10
+
11
+ res = post "#{resource_path(account_sid)}.json", :body => Hash[attrs.map { |k,v| [k.to_s.camelize, v]}]
12
+
13
+ if (400..599).include? res.code
14
+ raise Twilio::APIError.new "Error ##{res.parsed_response['code']}: #{res.parsed_response['message']}"
15
+ else
16
+ res.parsed_response['api_version'] = res.parsed_response['api_version'].to_s
17
+ new res.parsed_response
18
18
  end
19
19
  end
20
+
21
+ private
22
+ def resource_path(account_sid)
23
+ "/Accounts/#{account_sid}/#{resource_name}"
24
+ end
25
+
26
+ def resource_name
27
+ name.demodulize.pluralize
28
+ end
20
29
  end
21
30
  end
22
-
23
31
  end
24
32
  end
@@ -0,0 +1,25 @@
1
+ require 'base64'
2
+ require 'openssl'
3
+ require 'digest/sha1'
4
+
5
+ module Twilio
6
+ module RequestFilter
7
+ def filter(controller)
8
+ request = controller.request
9
+ if request.format.voice? && request.ssl?
10
+ controller.head(:forbidden) if expected_signature_for(request) != request.env['X-Twilio-Signature']
11
+ end
12
+ end
13
+
14
+ private
15
+ def expected_signature_for(request)
16
+ string_to_sign = request.url + request.params.sort.join
17
+ digest = OpenSSL::Digest::Digest.new 'sha1'
18
+ hash = OpenSSL::HMAC.digest digest, Twilio::AUTH_TOKEN, string_to_sign
19
+
20
+ Base64.encode64(hash).strip
21
+ end
22
+
23
+ extend self
24
+ end
25
+ end
@@ -7,6 +7,10 @@ module Twilio
7
7
  @attributes = attrs.with_indifferent_access
8
8
  end
9
9
 
10
+ def inspect
11
+ "#<#{self.class} #{@attributes.map { |k,v| "#{k}: #{v.inspect}" }.join ', '}>"
12
+ end
13
+
10
14
  def [](key)
11
15
  attributes[key]
12
16
  end
@@ -22,6 +26,10 @@ module Twilio
22
26
  end
23
27
 
24
28
  private
29
+ def resource_name
30
+ klass.name.demodulize.pluralize
31
+ end
32
+
25
33
  def klass
26
34
  self.class == Module ? self : self.class
27
35
  end
@@ -34,8 +42,8 @@ module Twilio
34
42
  end
35
43
  end
36
44
 
37
- def path # :nodoc:
38
- "/Accounts/#{Twilio::ACCOUNT_SID}/#{klass.name.demodulize.pluralize}/#{self[:sid]}.json"
45
+ def path
46
+ uri[11,uri.length]
39
47
  end
40
48
 
41
49
  def handle_response(res) # :nodoc:
@@ -55,7 +63,7 @@ module Twilio
55
63
  elsif meth =~ /^#{meth}\?$/i
56
64
  add_predicate meth
57
65
  send meth
58
- elsif attributes.keys.include? meth
66
+ elsif attributes.keys.include? meth
59
67
  add_attr_reader meth
60
68
  send meth
61
69
  else
@@ -95,12 +103,20 @@ module Twilio
95
103
 
96
104
  class << base
97
105
  # decorate http methods with authentication
98
- %w<post get put delete>.each do |meth|
99
- define_method(meth) do |*args| # splatted args necessary hack since <= 1.8.7 does not support optional block args
106
+ %w<post get put delete>.each do |meth|
107
+ define_method(meth) do |*args| # splatted args necessary hack since <= 1.8.7 does not support optional block args
100
108
  opts = args[1] || {}
101
109
  super args.first, opts.merge(:basic_auth => { :username => Twilio::ACCOUNT_SID, :password => Twilio::AUTH_TOKEN })
102
110
  end
103
111
  end
112
+
113
+ def mutable_attributes(*attrs)
114
+ attrs.each do |attr|
115
+ define_method "#{attr}=" do |arg|
116
+ update_attributes attr => arg
117
+ end
118
+ end
119
+ end
104
120
  end
105
121
  end
106
122
  end
@@ -0,0 +1,23 @@
1
+ module Twilio
2
+ class ShortCode
3
+ include Twilio::Resource
4
+ extend Twilio::Finder
5
+
6
+ class << self
7
+ private
8
+
9
+ def resource_name
10
+ "SMS/ShortCodes"
11
+ end
12
+ end
13
+
14
+ mutable_attributes :friendly_name, :api_version, :sms_url, :sms_method,
15
+ :sms_fallback_url, :sms_fallback_method
16
+
17
+ private
18
+ def resource_name
19
+ "SMS/ShortCodes"
20
+ end
21
+
22
+ end
23
+ end
data/lib/twilio/sms.rb CHANGED
@@ -6,10 +6,13 @@ module Twilio
6
6
 
7
7
  class << self
8
8
  private
9
+ def resource_name
10
+ "SMS/Messages"
11
+ end
12
+
9
13
  def prepare_params(opts) # :nodoc:
10
14
  pairs = opts.map do |k,v|
11
- if [:created_before, :created_after, :sent_before, :sent_after].include? k
12
- k = k.to_s
15
+ if %w(created_before created_after sent_before sent_after).include? k
13
16
  # Fancy schmancy-ness to handle Twilio <= URI operator for dates
14
17
  comparator = k =~ /before$/ ? '<=' : '>='
15
18
  URI.encode("DateSent" << comparator << v.to_s)
data/lib/twilio-rb.rb ADDED
@@ -0,0 +1,23 @@
1
+ %w<rubygems active_support active_support/inflector cgi jwt yajl yajl/json_gem httparty builder>.each { |lib| require lib }
2
+ %w<resource finder persistable deletable associations association_proxy>.each { |lib| require File.join(File.dirname(__FILE__), 'twilio', "#{lib}.rb") }
3
+
4
+ module Twilio
5
+ API_ENDPOINT = 'https://api.twilio.com/2010-04-01'
6
+ APIError = Class.new StandardError
7
+ ConfigurationError = Class.new StandardError
8
+ InvalidStateError = Class.new StandardError
9
+
10
+ class << self
11
+ def const_missing(const_name)
12
+ if [:ACCOUNT_SID, :AUTH_TOKEN].include? const_name
13
+ raise Twilio::ConfigurationError.new "Cannot complete request. Please set #{const_name.to_s.downcase} with Twilio::Config.setup first!"
14
+ else
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ Dir[File.join(File.dirname(__FILE__), 'twilio', '*.rb')].each { |lib| require lib }
22
+
23
+ require File.join(File.dirname(__FILE__), 'railtie.rb') if Object.const_defined?(:Rails) && Rails.version =~ /^3/
data/lib/twilio.rb CHANGED
@@ -1,23 +1,3 @@
1
- %w<rubygems active_support active_support/inflector cgi yajl yajl/json_gem httparty builder>.each { |lib| require lib }
2
- %w<resource finder persistable deletable>.each { |lib| require File.join(File.dirname(__FILE__), 'twilio', "#{lib}.rb") }
1
+ require File.dirname(__FILE__) +'/twilio-rb.rb'
2
+ warn 'require "twilio" is deprecated and will be removed in a future release. Use require "twilio-rb" instead.'
3
3
 
4
- module Twilio
5
- API_ENDPOINT = 'https://api.twilio.com/2010-04-01'
6
- APIError = Class.new StandardError
7
- ConfigurationError = Class.new StandardError
8
- InvalidStateError = Class.new StandardError
9
-
10
- class << self
11
- def const_missing(const_name)
12
- if [:ACCOUNT_SID, :AUTH_TOKEN].include? const_name
13
- raise Twilio::ConfigurationError.new "Cannot complete request. Please set #{const_name.to_s.downcase} with Twilio::Config.setup first!"
14
- else
15
- super
16
- end
17
- end
18
- end
19
- end
20
-
21
- Dir[File.join(File.dirname(__FILE__), 'twilio', '*.rb')].each { |lib| require lib }
22
-
23
- require File.join(File.dirname(__FILE__), 'railtie.rb') if Object.const_defined?(:Rails) && Rails.version =~ /^3/
metadata CHANGED
@@ -1,120 +1,152 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: twilio-rb
3
- version: !ruby/object:Gem::Version
4
- prerelease: 3
5
- version: 1.0beta2
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ prerelease:
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Stevie Graham
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-06-08 00:00:00 +01:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2011-09-20 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: activesupport
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70298512157240 !ruby/object:Gem::Requirement
20
17
  none: false
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
24
21
  version: 3.0.0
25
22
  type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: i18n
29
23
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70298512157240
25
+ - !ruby/object:Gem::Dependency
26
+ name: i18n
27
+ requirement: &70298512130420 !ruby/object:Gem::Requirement
31
28
  none: false
32
- requirements:
29
+ requirements:
33
30
  - - ~>
34
- - !ruby/object:Gem::Version
35
- version: 0.5.0
31
+ - !ruby/object:Gem::Version
32
+ version: '0.5'
36
33
  type: :runtime
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: yajl-ruby
40
34
  prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *70298512130420
36
+ - !ruby/object:Gem::Dependency
37
+ name: yajl-ruby
38
+ requirement: &70298512129800 !ruby/object:Gem::Requirement
42
39
  none: false
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
46
43
  version: 0.7.7
47
44
  type: :runtime
48
- version_requirements: *id003
49
- - !ruby/object:Gem::Dependency
50
- name: httparty
51
45
  prerelease: false
52
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *70298512129800
47
+ - !ruby/object:Gem::Dependency
48
+ name: httparty
49
+ requirement: &70298512129220 !ruby/object:Gem::Requirement
53
50
  none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
57
54
  version: 0.6.1
58
55
  type: :runtime
59
- version_requirements: *id004
60
- - !ruby/object:Gem::Dependency
56
+ prerelease: false
57
+ version_requirements: *70298512129220
58
+ - !ruby/object:Gem::Dependency
61
59
  name: builder
60
+ requirement: &70298512128620 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 3.0.0
66
+ type: :runtime
62
67
  prerelease: false
63
- requirement: &id005 !ruby/object:Gem::Requirement
68
+ version_requirements: *70298512128620
69
+ - !ruby/object:Gem::Dependency
70
+ name: jwt
71
+ requirement: &70298512127920 !ruby/object:Gem::Requirement
64
72
  none: false
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: 2.1.2
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: 0.1.3
69
77
  type: :runtime
70
- version_requirements: *id005
71
- - !ruby/object:Gem::Dependency
72
- name: webmock
73
78
  prerelease: false
74
- requirement: &id006 !ruby/object:Gem::Requirement
79
+ version_requirements: *70298512127920
80
+ - !ruby/object:Gem::Dependency
81
+ name: webmock
82
+ requirement: &70298512127380 !ruby/object:Gem::Requirement
75
83
  none: false
76
- requirements:
77
- - - ">="
78
- - !ruby/object:Gem::Version
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
79
87
  version: 1.6.1
80
88
  type: :development
81
- version_requirements: *id006
82
- - !ruby/object:Gem::Dependency
83
- name: rspec
84
89
  prerelease: false
85
- requirement: &id007 !ruby/object:Gem::Requirement
90
+ version_requirements: *70298512127380
91
+ - !ruby/object:Gem::Dependency
92
+ name: rspec
93
+ requirement: &70298512126660 !ruby/object:Gem::Requirement
86
94
  none: false
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
90
98
  version: 2.2.0
91
99
  type: :development
92
- version_requirements: *id007
93
- - !ruby/object:Gem::Dependency
94
- name: mocha
95
100
  prerelease: false
96
- requirement: &id008 !ruby/object:Gem::Requirement
101
+ version_requirements: *70298512126660
102
+ - !ruby/object:Gem::Dependency
103
+ name: mocha
104
+ requirement: &70298512126060 !ruby/object:Gem::Requirement
97
105
  none: false
98
- requirements:
99
- - - ">="
100
- - !ruby/object:Gem::Version
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
101
109
  version: 0.9.10
102
110
  type: :development
103
- version_requirements: *id008
111
+ prerelease: false
112
+ version_requirements: *70298512126060
113
+ - !ruby/object:Gem::Dependency
114
+ name: timecop
115
+ requirement: &70298512125460 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: 0.3.5
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *70298512125460
124
+ - !ruby/object:Gem::Dependency
125
+ name: rake
126
+ requirement: &70298512124880 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - =
130
+ - !ruby/object:Gem::Version
131
+ version: 0.8.7
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *70298512124880
104
135
  description: A nice Ruby wrapper for the Twilio REST API
105
136
  email: sjtgraham@mac.com
106
137
  executables: []
107
-
108
138
  extensions: []
109
-
110
139
  extra_rdoc_files: []
111
-
112
- files:
140
+ files:
113
141
  - README.md
114
142
  - lib/railtie.rb
115
143
  - lib/twilio/account.rb
144
+ - lib/twilio/application.rb
145
+ - lib/twilio/association_proxy.rb
146
+ - lib/twilio/associations.rb
116
147
  - lib/twilio/available_phone_number.rb
117
148
  - lib/twilio/call.rb
149
+ - lib/twilio/capability.rb
118
150
  - lib/twilio/conference.rb
119
151
  - lib/twilio/config.rb
120
152
  - lib/twilio/deletable.rb
@@ -125,39 +157,37 @@ files:
125
157
  - lib/twilio/participant.rb
126
158
  - lib/twilio/persistable.rb
127
159
  - lib/twilio/recording.rb
160
+ - lib/twilio/request_filter.rb
128
161
  - lib/twilio/resource.rb
129
162
  - lib/twilio/sandbox.rb
163
+ - lib/twilio/short_code.rb
130
164
  - lib/twilio/sms.rb
131
165
  - lib/twilio/transcription.rb
132
166
  - lib/twilio/twiml.rb
167
+ - lib/twilio-rb.rb
133
168
  - lib/twilio.rb
134
- has_rdoc: true
135
169
  homepage: http://github.com/stevegraham/twilio-rb
136
170
  licenses: []
137
-
138
171
  post_install_message:
139
172
  rdoc_options: []
140
-
141
- require_paths:
173
+ require_paths:
142
174
  - lib
143
- required_ruby_version: !ruby/object:Gem::Requirement
175
+ required_ruby_version: !ruby/object:Gem::Requirement
144
176
  none: false
145
- requirements:
146
- - - ">="
147
- - !ruby/object:Gem::Version
177
+ requirements:
178
+ - - ! '>='
179
+ - !ruby/object:Gem::Version
148
180
  version: 1.8.7
149
- required_rubygems_version: !ruby/object:Gem::Requirement
181
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
182
  none: false
151
- requirements:
152
- - - ">"
153
- - !ruby/object:Gem::Version
154
- version: 1.3.1
183
+ requirements:
184
+ - - ! '>='
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
155
187
  requirements: []
156
-
157
188
  rubyforge_project:
158
- rubygems_version: 1.5.2
189
+ rubygems_version: 1.8.6
159
190
  signing_key:
160
191
  specification_version: 3
161
192
  summary: Interact with the Twilio API in a nice Ruby way.
162
193
  test_files: []
163
-