twilio-ruby 3.15.0 → 3.15.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7e3f7fccd86f4d886d36e894f065fc04e8959589
4
- data.tar.gz: 1ee5bcddb4df870adcd8ee40d490a8509dae1c94
3
+ metadata.gz: fbf01b84361cd43929e39a6edee180274f39e52a
4
+ data.tar.gz: c88951b668570f7c2cf9eb5bce608917366357ea
5
5
  SHA512:
6
- metadata.gz: 568a300bd1658267aaee702e1f8d35f44245ede4c18de5ee8ec67f6f62834a232941697f18cfc2841a673d13c7d0782c8654b470a1c801303c8f4fc50d7b27cd
7
- data.tar.gz: a92cf749d641e562618dade1c21a80bb9dd2d8e48747e96b3a47b9432f0d581455583f19cc57e0a1f916a0fab2b5c7faff3d55d9fed73f7cf75adc2f239a4a2f
6
+ metadata.gz: 24a085c8ac996ba2b85848babda9246f5bffcdd378e73122884efbfc6dfa3506cd4cb47bb42bb3bb9a1d9cfa990e7b30c9a2e2b913da2b0bde9094fdd112d47c
7
+ data.tar.gz: 6495299185882caa6eeb2797b2f12863c1bc9e4d64aa24a643107ecf80d0b93627831d41f9d867a755ee9c1d68d96db7938cd9bc62f89578fde617456ca42efd
data/CHANGES.md CHANGED
@@ -1,6 +1,13 @@
1
1
  twilio-ruby changelog
2
2
  =====================
3
3
 
4
+ Version 3.15.1
5
+ --------------
6
+
7
+ Released February 18, 2015
8
+
9
+ - For real this time, add TaskRouterClient object and resources for new TaskRouter API
10
+
4
11
  Version 3.15.0
5
12
  --------------
6
13
 
@@ -1,5 +1,116 @@
1
1
  module Twilio
2
2
  module REST
3
+ class BaseClient
4
+ include Twilio::Util
5
+ include Twilio::REST::Utils
6
+
7
+ HTTP_HEADERS = {
8
+ 'Accept' => 'application/json',
9
+ 'Accept-Charset' => 'utf-8',
10
+ 'User-Agent' => "twilio-ruby/#{Twilio::VERSION}" \
11
+ " (#{RUBY_ENGINE}/#{RUBY_PLATFORM}" \
12
+ " #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL})"
13
+ }
14
+
15
+ DEFAULTS = {
16
+ host: 'api.twilio.com',
17
+ port: 443,
18
+ use_ssl: true,
19
+ ssl_verify_peer: true,
20
+ ssl_ca_file: File.dirname(__FILE__) + '/../../../conf/cacert.pem',
21
+ timeout: 30,
22
+ proxy_addr: nil,
23
+ proxy_port: nil,
24
+ proxy_user: nil,
25
+ proxy_pass: nil,
26
+ retry_limit: 1
27
+ }
28
+
29
+ attr_reader :account_sid, :last_request, :last_response
30
+
31
+ def initialize(*args)
32
+ options = args.last.is_a?(Hash) ? args.pop : {}
33
+ @config = get_defaults.merge! options
34
+
35
+ @account_sid = args[0] || Twilio.account_sid
36
+ @auth_token = args[1] || Twilio.auth_token
37
+ if @account_sid.nil? || @auth_token.nil?
38
+ raise ArgumentError, 'Account SID and auth token are required'
39
+ end
40
+
41
+ set_up_connection
42
+ set_up_subresources
43
+ end
44
+
45
+ protected
46
+
47
+ ##
48
+ # Get the default config values.
49
+ def get_defaults
50
+ # To be overridden
51
+ DEFAULTS
52
+ end
53
+
54
+ ##
55
+ # Set up and cache a Net::HTTP object to use when making requests. This is
56
+ # a private method documented for completeness.
57
+ def set_up_connection # :doc:
58
+ connection_class = Net::HTTP::Proxy @config[:proxy_addr],
59
+ @config[:proxy_port], @config[:proxy_user], @config[:proxy_pass]
60
+ @connection = connection_class.new @config[:host], @config[:port]
61
+ set_up_ssl
62
+ @connection.open_timeout = @config[:timeout]
63
+ @connection.read_timeout = @config[:timeout]
64
+ end
65
+
66
+ ##
67
+ # Set up the ssl properties of the <tt>@connection</tt> Net::HTTP object.
68
+ # This is a private method documented for completeness.
69
+ def set_up_ssl # :doc:
70
+ @connection.use_ssl = @config[:use_ssl]
71
+ if @config[:ssl_verify_peer]
72
+ @connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
73
+ @connection.ca_file = @config[:ssl_ca_file]
74
+ else
75
+ @connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
76
+ end
77
+ end
78
+
79
+ ##
80
+ # Set up sub resources attributes.
81
+ def set_up_subresources # :doc:
82
+ # To be overridden
83
+ end
84
+
85
+ ##
86
+ # Send an HTTP request using the cached <tt>@connection</tt> object and
87
+ # return the JSON response body parsed into a hash. Also save the raw
88
+ # Net::HTTP::Request and Net::HTTP::Response objects as
89
+ # <tt>@last_request</tt> and <tt>@last_response</tt> to allow for
90
+ # inspection later.
91
+ def connect_and_send(request) # :doc:
92
+ @last_request = request
93
+ retries_left = @config[:retry_limit]
94
+ begin
95
+ response = @connection.request request
96
+ @last_response = response
97
+ if response.kind_of? Net::HTTPServerError
98
+ raise Twilio::REST::ServerError
99
+ end
100
+ rescue Exception
101
+ raise if request.class == Net::HTTP::Post
102
+ if retries_left > 0 then retries_left -= 1; retry else raise end
103
+ end
104
+ if response.body and !response.body.empty?
105
+ object = MultiJson.load response.body
106
+ end
107
+ if response.kind_of? Net::HTTPClientError
108
+ raise Twilio::REST::RequestError.new object['message'], object['code']
109
+ end
110
+ object
111
+ end
112
+ end
113
+
3
114
  ##
4
115
  # The Twilio::REST::Client class caches authentication parameters and
5
116
  # exposes methods to make HTTP requests to Twilio's REST API. However, you
@@ -47,36 +158,10 @@ module Twilio
47
158
  # methods like ListResource#list to return a (possibly filtered) list of
48
159
  # accounts and ListResource#create to create a new account. Use
49
160
  # ListResource#get to grab a particular account once you know its sid.
50
- class Client
51
- include Twilio::Util
52
- include Twilio::REST::Utils
53
-
161
+ class Client < BaseClient
54
162
  API_VERSION = '2010-04-01'
55
163
 
56
- HTTP_HEADERS = {
57
- 'Accept' => 'application/json',
58
- 'Accept-Charset' => 'utf-8',
59
- 'User-Agent' => "twilio-ruby/#{Twilio::VERSION}" \
60
- " (#{RUBY_ENGINE}/#{RUBY_PLATFORM}" \
61
- " #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL})"
62
- }
63
-
64
- DEFAULTS = {
65
- host: 'api.twilio.com',
66
- port: 443,
67
- use_ssl: true,
68
- ssl_verify_peer: true,
69
- ssl_ca_file: File.dirname(__FILE__) + '/../../../conf/cacert.pem',
70
- timeout: 30,
71
- proxy_addr: nil,
72
- proxy_port: nil,
73
- proxy_user: nil,
74
- proxy_pass: nil,
75
- retry_limit: 1
76
- }
77
-
78
- attr_reader :account_sid, :account, :accounts, :last_request,
79
- :last_response
164
+ attr_reader :account, :accounts
80
165
 
81
166
  ##
82
167
  # Instantiate a new HTTP client to talk to Twilio. The parameters
@@ -145,17 +230,7 @@ module Twilio
145
230
  # The number of times to retry a request that has failed before throwing
146
231
  # an exception. Defaults to one.
147
232
  def initialize(*args)
148
- options = args.last.is_a?(Hash) ? args.pop : {}
149
- @config = DEFAULTS.merge! options
150
-
151
- @account_sid = args[0] || Twilio.account_sid
152
- @auth_token = args[1] || Twilio.auth_token
153
- if @account_sid.nil? || @auth_token.nil?
154
- raise ArgumentError, 'Account SID and auth token are required'
155
- end
156
-
157
- set_up_connection
158
- set_up_subresources
233
+ super(*args)
159
234
  end
160
235
 
161
236
  def inspect # :nodoc:
@@ -202,67 +277,225 @@ module Twilio
202
277
  end
203
278
  end
204
279
 
205
- private
280
+ protected
206
281
 
207
282
  ##
208
- # Set up and cache a Net::HTTP object to use when making requests. This is
209
- # a private method documented for completeness.
210
- def set_up_connection # :doc:
211
- connection_class = Net::HTTP::Proxy @config[:proxy_addr],
212
- @config[:proxy_port], @config[:proxy_user], @config[:proxy_pass]
213
- @connection = connection_class.new @config[:host], @config[:port]
214
- set_up_ssl
215
- @connection.open_timeout = @config[:timeout]
216
- @connection.read_timeout = @config[:timeout]
283
+ # Set up +account+ and +accounts+ attributes.
284
+ def set_up_subresources # :doc:
285
+ @accounts = Twilio::REST::Accounts.new "/#{API_VERSION}/Accounts", self
286
+ @account = @accounts.get @account_sid
217
287
  end
288
+ end
289
+
290
+ class TaskRouterClient < BaseClient
291
+ API_VERSION = 'v1'
292
+
293
+ DEFAULTS = {
294
+ host: 'taskrouter.twilio.com',
295
+ port: 443,
296
+ use_ssl: true,
297
+ ssl_verify_peer: true,
298
+ ssl_ca_file: File.dirname(__FILE__) + '/../../../conf/cacert.pem',
299
+ timeout: 30,
300
+ proxy_addr: nil,
301
+ proxy_port: nil,
302
+ proxy_user: nil,
303
+ proxy_pass: nil,
304
+ retry_limit: 1
305
+ }
306
+
307
+ attr_reader :workspace, :workspace_sid, :workspaces
218
308
 
219
309
  ##
220
- # Set up the ssl properties of the <tt>@connection</tt> Net::HTTP object.
221
- # This is a private method documented for completeness.
222
- def set_up_ssl # :doc:
223
- @connection.use_ssl = @config[:use_ssl]
224
- if @config[:ssl_verify_peer]
225
- @connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
226
- @connection.ca_file = @config[:ssl_ca_file]
227
- else
228
- @connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
310
+ # Instantiate a new HTTP TaskRouter client to talk to Twilio. The parameters
311
+ # +account_sid+, +auth_token+ and +workspace_sid are required, unless you
312
+ # have configured them already using the block configure syntax, and used
313
+ # to generate the HTTP basic auth header in each request. The +options+
314
+ # parameter is a hash of connection configuration options. the following
315
+ # keys are supported:
316
+ #
317
+ # === <tt>host: 'taskrouter.twilio.com'</tt>
318
+ #
319
+ # The domain to which you'd like the client to make HTTP requests. Useful
320
+ # for testing. Defaults to 'api.twilio.com'.
321
+ #
322
+ # === <tt>port: 443</tt>
323
+ #
324
+ # The port on which to connect to the above domain. Defaults to 443 and
325
+ # should be left that way except in testing environments.
326
+ #
327
+ # === <tt>use_ssl: true</tt>
328
+ #
329
+ # Declare whether ssl should be used for connections to the above domain.
330
+ # Defaults to true and should be left alone except when testing.
331
+ #
332
+ # === <tt>ssl_verify_peer: true</tt>
333
+ #
334
+ # Declare whether to verify the host's ssl cert when setting up the
335
+ # connection to the above domain. Defaults to true, but can be turned off
336
+ # to avoid ssl certificate verification failures in environments without
337
+ # the necessary ca certificates.
338
+ #
339
+ # === <tt>ssl_ca_file: '/path/to/ca/file'</tt>
340
+ #
341
+ # Specify the path to the certificate authority bundle you'd like to use
342
+ # to verify Twilio's SSL certificate on each request. If not specified, a
343
+ # certificate bundle extraced from Firefox is packaged with the gem and
344
+ # used by default.
345
+ #
346
+ # === <tt>timeout: 30</tt>
347
+ #
348
+ # Set the time in seconds to wait before timing out the HTTP request.
349
+ # Defaults to 30 seconds. If you aren't fetching giant pages of call or
350
+ # SMS logs you can safely decrease this to something like 3 seconds or
351
+ # lower. In paricular if you are sending SMS you can set this to 1 second
352
+ # or less and swallow the exception if you don't care about the response.
353
+ #
354
+ # === <tt>proxy_addr: 'proxy.host.domain'</tt>
355
+ #
356
+ # The domain of a proxy through which you'd like the client to make HTTP
357
+ # requests. Defaults to nil.
358
+ #
359
+ # === <tt>proxy_port: 3128</tt>
360
+ #
361
+ # The port on which to connect to the above proxy. Defaults to nil.
362
+ #
363
+ # === <tt>proxy_user: 'username'</tt>
364
+ #
365
+ # The user name to use for authentication with the proxy. Defaults to nil.
366
+ #
367
+ # === <tt>proxy_pass: 'password'</tt>
368
+ #
369
+ # The password to use for authentication with the proxy. Defaults to nil.
370
+ #
371
+ # === <tt>retry_limit: 1</tt>
372
+ #
373
+ # The number of times to retry a request that has failed before throwing
374
+ # an exception. Defaults to one.
375
+ def initialize(*args)
376
+ @workspace_sid = args[2]
377
+ if @workspace_sid.nil?
378
+ raise ArgumentError, 'Workspace SID is required'
229
379
  end
380
+ super(*args)
230
381
  end
231
382
 
232
383
  ##
233
- # Set up +account+ and +accounts+ attributes.
234
- def set_up_subresources # :doc:
235
- @accounts = Twilio::REST::Accounts.new "/#{API_VERSION}/Accounts", self
236
- @account = @accounts.get @account_sid
384
+ # Define #get, #put, #post and #delete helper methods for sending HTTP
385
+ # requests to Twilio. You shouldn't need to use these methods directly,
386
+ # but they can be useful for debugging. Each method returns a hash
387
+ # obtained from parsing the JSON object in the response body.
388
+ [:get, :put, :post, :delete].each do |method|
389
+ method_class = Net::HTTP.const_get method.to_s.capitalize
390
+ define_method method do |path, *args|
391
+ params = twilify args[0]; params = {} if params.empty?
392
+ unless args[1] # build the full path unless already given
393
+ path = path.dup
394
+ path << "?#{url_encode(params)}" if method == :get && !params.empty?
395
+ end
396
+ request = method_class.new path, HTTP_HEADERS
397
+ request.basic_auth @account_sid, @auth_token
398
+ request.form_data = params if [:post, :put].include? method
399
+ connect_and_send request
400
+ end
401
+ end
402
+
403
+ def inspect # :nodoc:
404
+ "<Twilio::REST::TaskRouterClient @account_sid=#{@account_sid}>"
237
405
  end
238
406
 
239
407
  ##
240
- # Send an HTTP request using the cached <tt>@connection</tt> object and
241
- # return the JSON response body parsed into a hash. Also save the raw
242
- # Net::HTTP::Request and Net::HTTP::Response objects as
243
- # <tt>@last_request</tt> and <tt>@last_response</tt> to allow for
244
- # inspection later.
245
- def connect_and_send(request) # :doc:
246
- @last_request = request
247
- retries_left = @config[:retry_limit]
248
- begin
249
- response = @connection.request request
250
- @last_response = response
251
- if response.kind_of? Net::HTTPServerError
252
- raise Twilio::REST::ServerError
253
- end
254
- rescue Exception
255
- raise if request.class == Net::HTTP::Post
256
- if retries_left > 0 then retries_left -= 1; retry else raise end
408
+ # Delegate workspace methods from the client. This saves having to call
409
+ # <tt>client.workspace</tt> every time for resources on the default
410
+ # workspace.
411
+ def method_missing(method_name, *args, &block)
412
+ if workspace.respond_to?(method_name)
413
+ workspace.send(method_name, *args, &block)
414
+ else
415
+ super
257
416
  end
258
- if response.body and !response.body.empty?
259
- object = MultiJson.load response.body
417
+ end
418
+
419
+ def respond_to?(method_name, include_private=false)
420
+ if workspace.respond_to?(method_name, include_private)
421
+ true
422
+ else
423
+ super
260
424
  end
261
- if response.kind_of? Net::HTTPClientError
262
- raise Twilio::REST::RequestError.new object['message'], object['code']
425
+ end
426
+
427
+ ##
428
+ # Get statistics of a task queue.
429
+ def task_queue_statistics(task_queue_sid, *args) # :doc:
430
+ if task_queue_sid.nil?
431
+ raise ArgumentError, 'Task queue SID is required'
263
432
  end
264
- object
433
+ path = "/#{API_VERSION}/Workspaces/#{@workspace_sid}/TaskQueues/#{task_queue_sid}/Statistics"
434
+ response = get path, args, true
435
+ Twilio::REST::TaskRouter::TaskQueueStatistics.new path, self, response
436
+ end
437
+
438
+ ##
439
+ # Get statistics of task queues.
440
+ def task_queues_statistics(*args) # :doc:
441
+ path = "/#{API_VERSION}/Workspaces/#{@workspace_sid}/TaskQueues/Statistics"
442
+ stats = Twilio::REST::TaskRouter::TaskQueuesStatistics.new path, self
443
+ stats.list args, true
444
+ end
445
+
446
+ ##
447
+ # Get statistics of a worker.
448
+ def worker_statistics(worker_sid, *args) # :doc:
449
+ if worker_sid.nil?
450
+ raise ArgumentError, 'Worker SID is required'
451
+ end
452
+ path = "/#{API_VERSION}/Workspaces/#{@workspace_sid}/Workers/#{worker_sid}/Statistics"
453
+ response = get path, args, true
454
+ Twilio::REST::TaskRouter::WorkerStatistics.new path, self, response
455
+ end
456
+
457
+ ##
458
+ # Get statistics of workers.
459
+ def workers_statistics(*args) # :doc:
460
+ path = "/#{API_VERSION}/Workspaces/#{@workspace_sid}/Workers/Statistics"
461
+ response = get path, args, true
462
+ Twilio::REST::TaskRouter::WorkersStatistics.new path, self, response
463
+ end
464
+
465
+ ##
466
+ # Get statistics of a workflow.
467
+ def workflow_statistics(workflow_sid, *args) # :doc:
468
+ if workflow_sid.nil?
469
+ raise ArgumentError, 'Workflow SID is required'
470
+ end
471
+ path = "/#{API_VERSION}/Workspaces/#{@workspace_sid}/Workflows/#{workflow_sid}/Statistics"
472
+ response = get path, args, true
473
+ Twilio::REST::TaskRouter::WorkflowStatistics.new path, self, response
265
474
  end
475
+
476
+ ##
477
+ # Get statistics of a workspace.
478
+ def workspace_statistics(*args) # :doc:
479
+ path = "/#{API_VERSION}/Workspaces/#{@workspace_sid}/Statistics"
480
+ response = get path, args, true
481
+ Twilio::REST::TaskRouter::WorkspaceStatistics.new path, self, response
482
+ end
483
+
484
+ protected
485
+
486
+ ##
487
+ # Get the default config values.
488
+ def get_defaults
489
+ DEFAULTS
490
+ end
491
+
492
+ ##
493
+ # Set up +workspace+ and +workspaces+ attributes.
494
+ def set_up_subresources # :doc:
495
+ @workspaces = Twilio::REST::TaskRouter::Workspaces.new "/#{API_VERSION}/Workspaces", self
496
+ @workspace = @workspaces.get @workspace_sid
497
+ end
498
+
266
499
  end
267
500
  end
268
501
  end
@@ -5,6 +5,7 @@ module Twilio
5
5
 
6
6
  def initialize(path, client)
7
7
  custom_names = {
8
+ 'Activities' => 'Activity',
8
9
  'Media' => 'MediaInstance',
9
10
  'IpAddresses' => 'IpAddress',
10
11
  'Feedback' => 'FeedbackInstance',
@@ -0,0 +1,29 @@
1
+ module Twilio
2
+ module REST
3
+ class NextGenListResource < Twilio::REST::ListResource
4
+ def list(params={}, full_path=false)
5
+ raise "Can't get a resource list without a REST Client" unless @client
6
+ response = @client.get @path, params, full_path
7
+ list_key = response['meta']['key']
8
+ raise "Couldn't find a list key in response meta" unless list_key
9
+ resources = response[list_key]
10
+ resource_list = resources.map do |resource|
11
+ @instance_class.new "#{@path}/#{resource[@instance_id_key]}", @client,
12
+ resource
13
+ end
14
+ client, list_class = @client, self.class
15
+ resource_list.instance_eval do
16
+ eigenclass = class << self; self; end
17
+ eigenclass.send :define_method, :next_page, &lambda {
18
+ if response['meta']['next_page_url']
19
+ list_class.new(response['meta']['next_page_url'], client).list({})
20
+ else
21
+ []
22
+ end
23
+ }
24
+ end
25
+ resource_list
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,8 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class Activities < Twilio::REST::NextGenListResource; end
5
+ class Activity < InstanceResource; end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class Events < ListResource; end
5
+ class Event < InstanceResource; end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class Reservations < Twilio::REST::NextGenListResource; end
5
+ class Reservation < InstanceResource; end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class TaskQueues < Twilio::REST::NextGenListResource; end
5
+ class TaskQueue < InstanceResource; end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class TaskQueuesStatistics < Twilio::REST::NextGenListResource
5
+ def initialize(path, client)
6
+ @path, @client = path, client
7
+ @instance_class = Twilio::REST::TaskRouter::TaskQueueStatistics
8
+ @list_key, @instance_id_key = 'task_queues_statistics', 'task_queue_sid'
9
+ end
10
+ end
11
+
12
+ class TaskQueueStatistics < InstanceResource; end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class Tasks < Twilio::REST::NextGenListResource; end
5
+
6
+ class Task < InstanceResource
7
+ def initialize(path, client, params={})
8
+ super path, client, params
9
+ @submodule = :TaskRouter
10
+ resource :reservations
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class Workers < Twilio::REST::NextGenListResource; end
5
+ class Worker < InstanceResource; end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class WorkersStatistics < Twilio::REST::InstanceResource; end
5
+ class WorkerStatistics < InstanceResource; end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class WorkflowStatistics < InstanceResource; end
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class Workflows < Twilio::REST::NextGenListResource; end
5
+ class Workflow < InstanceResource; end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class WorkspaceStatistics < InstanceResource; end
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module Twilio
2
+ module REST
3
+ module TaskRouter
4
+ class Workspaces < Twilio::REST::NextGenListResource; end
5
+
6
+ class Workspace < InstanceResource
7
+ def initialize(path, client, params={})
8
+ super path, client, params
9
+ @submodule = :TaskRouter
10
+ resource :activities, :events, :task_queues, :tasks, :workers, :workflows
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,87 @@
1
+ module Twilio
2
+ module TaskRouter
3
+ class Capability
4
+
5
+ TASK_ROUTER_BASE_URL = 'https://taskrouter.twilio.com'
6
+ TASK_ROUTER_VERSION = 'v1'
7
+ TASK_ROUTER_WEBSOCKET_BASE_URL = 'https://event-bridge.twilio.com/v1/wschannels'
8
+
9
+ REQUIRED = {required: true}
10
+ OPTIONAL = {required: false}
11
+
12
+ def initialize(account_sid, auth_token, workspace_sid, worker_sid)
13
+ @account_sid = account_sid
14
+ @auth_token = auth_token
15
+ @workspace_sid = workspace_sid
16
+ @worker_sid = worker_sid
17
+ @policies = []
18
+ allow_websocket_requests
19
+ allow_activity_list_fetch
20
+ end
21
+
22
+ def workspace_url
23
+ "#{TASK_ROUTER_BASE_URL}/#{TASK_ROUTER_VERSION}/Workspaces/#{@workspace_sid}"
24
+ end
25
+
26
+ def worker_url
27
+ "#{workspace_url}/Workers/#{@worker_sid}"
28
+ end
29
+
30
+ def allow_worker_activity_updates
31
+ add_policy(worker_url, "POST", nil, {ActivitySid: REQUIRED})
32
+ end
33
+
34
+ def allow_worker_fetch_attributes
35
+ add_policy(worker_url, "GET")
36
+ end
37
+
38
+ def allow_task_reservation_updates
39
+ task_url = "#{workspace_url}/Tasks/**"
40
+ add_policy(task_url, "POST", nil, {ReservationStatus: REQUIRED})
41
+ end
42
+
43
+ def add_policy(url, method, query_filters = nil, post_filters = nil, allowed = true)
44
+ policy = {
45
+ url: url,
46
+ method: method,
47
+ query_filter: query_filters || {},
48
+ post_filter: post_filters || {},
49
+ allow: allowed
50
+ }
51
+
52
+ @policies.push(policy)
53
+ end
54
+
55
+ def generate_token(ttl = 3600)
56
+ payload = {
57
+ iss: @account_sid,
58
+ exp: (Time.now.to_i + ttl),
59
+ version: @version,
60
+ friendly_name: @worker_sid,
61
+ policies: @policies,
62
+ account_sid: @account_sid,
63
+ worker_sid: @worker_sid,
64
+ channel: @worker_sid,
65
+ workspace_sid: @workspace_sid
66
+ }
67
+
68
+ JWT.encode payload, @auth_token
69
+ end
70
+
71
+ protected
72
+
73
+ def allow_websocket_requests
74
+ worker_url = "#{TASK_ROUTER_WEBSOCKET_BASE_URL}/#{@account_sid}/#{@worker_sid}"
75
+ ['GET', 'POST'].each do |meth|
76
+ add_policy(worker_url, meth)
77
+ end
78
+ end
79
+
80
+ def allow_activity_list_fetch
81
+ url = "#{workspace_url}/Activities"
82
+ add_policy(url, 'GET')
83
+ end
84
+
85
+ end
86
+ end
87
+ end
File without changes
@@ -1,3 +1,3 @@
1
1
  module Twilio
2
- VERSION = '3.15.0'
2
+ VERSION = '3.15.1'
3
3
  end
data/lib/twilio-ruby.rb CHANGED
@@ -14,9 +14,12 @@ require 'twilio-ruby/util/configuration'
14
14
  require 'twilio-ruby/util/request_validator'
15
15
  require 'twilio-ruby/util/capability'
16
16
  require 'twilio-ruby/twiml/response'
17
+ require 'twilio-ruby/task_router'
18
+ require 'twilio-ruby/task_router/capability'
17
19
  require 'twilio-ruby/rest/errors'
18
20
  require 'twilio-ruby/rest/utils'
19
21
  require 'twilio-ruby/rest/list_resource'
22
+ require 'twilio-ruby/rest/next_gen_list_resource'
20
23
  require 'twilio-ruby/rest/instance_resource'
21
24
  require 'twilio-ruby/rest/sandbox'
22
25
  require 'twilio-ruby/rest/accounts'
@@ -34,6 +37,18 @@ require 'twilio-ruby/rest/sip/credential_lists'
34
37
  require 'twilio-ruby/rest/sip/credential_lists/credentials'
35
38
  require 'twilio-ruby/rest/sip/ip_access_control_lists'
36
39
  require 'twilio-ruby/rest/sip/ip_access_control_lists/ip_addresses'
40
+ require 'twilio-ruby/rest/task_router/activities'
41
+ require 'twilio-ruby/rest/task_router/events'
42
+ require 'twilio-ruby/rest/task_router/reservations'
43
+ require 'twilio-ruby/rest/task_router/task_queues'
44
+ require 'twilio-ruby/rest/task_router/task_queues_statistics'
45
+ require 'twilio-ruby/rest/task_router/tasks'
46
+ require 'twilio-ruby/rest/task_router/workers'
47
+ require 'twilio-ruby/rest/task_router/workers_statistics'
48
+ require 'twilio-ruby/rest/task_router/workflow_statistics'
49
+ require 'twilio-ruby/rest/task_router/workflows'
50
+ require 'twilio-ruby/rest/task_router/workspaces'
51
+ require 'twilio-ruby/rest/task_router/workspace_statistics'
37
52
  require 'twilio-ruby/rest/media'
38
53
  require 'twilio-ruby/rest/messages'
39
54
  require 'twilio-ruby/rest/applications'
@@ -181,4 +181,78 @@ describe Twilio::REST::Client do
181
181
  expect(client.send(method)).to eq(client.account.send(method))
182
182
  end
183
183
  end
184
+
185
+ it 'should throw an argument error if the workspace_sid is not set' do
186
+ expect { Twilio::REST::TaskRouterClient.new 'someSid', 'someToken' }.to raise_error(ArgumentError)
187
+ end
188
+
189
+ it 'should have its host set to taskrouter.twilio.com' do
190
+ client = Twilio::REST::TaskRouterClient.new('someSid', 'someToken', 'someSid')
191
+ connection = client.instance_variable_get('@connection')
192
+ expect(connection.address).to eq('taskrouter.twilio.com')
193
+ end
194
+
195
+ it 'should have task queue statistics resource' do
196
+ FakeWeb.register_uri(:get, %r/taskrouter\.twilio\.com/, body: '{}')
197
+ client = Twilio::REST::TaskRouterClient.new('someSid', 'someToken', 'someSid')
198
+ expect(client).to respond_to(:task_queue_statistics)
199
+ expect(client.task_queue_statistics('someSid').instance_variable_get('@path')).to eq('/v1/Workspaces/someSid/TaskQueues/someSid/Statistics')
200
+ end
201
+
202
+ it 'should have task queues statistics resource' do
203
+ FakeWeb.register_uri(:get, %r/taskrouter\.twilio\.com/, body: '{"meta": {"key": "task_queues_statistics"}, "task_queues_statistics": [{"task_queue_sid": "WQ123"}]}')
204
+ client = Twilio::REST::TaskRouterClient.new('someSid', 'someToken', 'someSid')
205
+ expect(client).to respond_to(:task_queues_statistics)
206
+ expect(client.task_queues_statistics[0].task_queue_sid).to eq('WQ123')
207
+ end
208
+
209
+ it 'should have worker statistics resource' do
210
+ FakeWeb.register_uri(:get, %r/taskrouter\.twilio\.com/, body: '{}')
211
+ client = Twilio::REST::TaskRouterClient.new('someSid', 'someToken', 'someSid')
212
+ expect(client).to respond_to(:worker_statistics)
213
+ expect(client.worker_statistics('someSid').instance_variable_get('@path')).to eq('/v1/Workspaces/someSid/Workers/someSid/Statistics')
214
+ end
215
+
216
+ it 'should have workers statistics resource' do
217
+ FakeWeb.register_uri(:get, %r/taskrouter\.twilio\.com/, body: '{}')
218
+ client = Twilio::REST::TaskRouterClient.new('someSid', 'someToken', 'someSid')
219
+ expect(client).to respond_to(:workers_statistics)
220
+ expect(client.workers_statistics.instance_variable_get('@path')).to eq('/v1/Workspaces/someSid/Workers/Statistics')
221
+ end
222
+
223
+ it 'should have workflow statistics resource' do
224
+ FakeWeb.register_uri(:get, %r/taskrouter\.twilio\.com/, body: '{}')
225
+ client = Twilio::REST::TaskRouterClient.new('someSid', 'someToken', 'someSid')
226
+ expect(client).to respond_to(:workflow_statistics)
227
+ expect(client.workflow_statistics('someSid').instance_variable_get('@path')).to eq('/v1/Workspaces/someSid/Workflows/someSid/Statistics')
228
+ end
229
+
230
+ it 'should have workspace statistics resource' do
231
+ FakeWeb.register_uri(:get, %r/taskrouter\.twilio\.com/, body: '{}')
232
+ client = Twilio::REST::TaskRouterClient.new('someSid', 'someToken', 'someSid')
233
+ expect(client).to respond_to(:workspace_statistics)
234
+ expect(client.workspace_statistics.instance_variable_get('@path')).to eq('/v1/Workspaces/someSid/Statistics')
235
+ end
236
+
237
+ it 'should set up a workspaces resource object' do
238
+ client = Twilio::REST::TaskRouterClient.new('someSid', 'someToken', 'someSid')
239
+ expect(client).to respond_to(:workspaces)
240
+ expect(client.workspaces.instance_variable_get('@path')).to eq('/v1/Workspaces')
241
+ end
242
+
243
+ it 'should set up a workspace resource object' do
244
+ client = Twilio::REST::TaskRouterClient.new('someSid', 'someToken', 'someSid')
245
+ expect(client).to respond_to(:workspace)
246
+ expect(client.workspace.instance_variable_get('@path')).to eq('/v1/Workspaces/someSid')
247
+ end
248
+
249
+ [
250
+ :activities, :tasks, :task_queues, :workers, :workflows
251
+ ].each do |method|
252
+ it "should delegate the client method #{method} to the workspace object" do
253
+ client = Twilio::REST::TaskRouterClient.new('someSid', 'someToken', 'someSid')
254
+ expect(client).to respond_to(method)
255
+ expect(client.send(method)).to eq(client.workspace.send(method))
256
+ end
257
+ end
184
258
  end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twilio::REST::TaskRouter::Reservations do
4
+ it 'creates a reservation object' do
5
+ task = Twilio::REST::TaskRouter::Task.new('someUri', 'someClient')
6
+ expect(task).to respond_to(:reservations)
7
+ expect(task.reservations.instance_variable_get('@path')).to eq('someUri/Reservations')
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twilio::REST::TaskRouter::TaskQueues do
4
+ it 'creates a task queue object' do
5
+ workspace = Twilio::REST::TaskRouter::Workspace.new('someUri', 'someClient')
6
+ expect(workspace).to respond_to(:task_queues)
7
+ expect(workspace.task_queues.instance_variable_get('@path')).to eq('someUri/TaskQueues')
8
+ end
9
+ end
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twilio::TaskRouter::Capability do
4
+ describe 'with a capability' do
5
+ before :each do
6
+ @capability = Twilio::TaskRouter::Capability.new 'AC123', 'foobar', 'WS456', 'WK789'
7
+ end
8
+
9
+ it 'should return a valid jwt when #generate_token is called' do
10
+ token = @capability.generate_token
11
+ decoded, header = JWT.decode token, 'foobar'
12
+ expect(decoded['policies']).not_to be_nil
13
+ expect(decoded['iss']).not_to be_nil
14
+ expect(decoded['exp']).not_to be_nil
15
+ end
16
+
17
+ it 'should properly set the iss key in the payload' do
18
+ token = @capability.generate_token
19
+ decoded, header = JWT.decode token, 'foobar'
20
+ expect(decoded['iss']).to eq('AC123')
21
+ end
22
+
23
+ it 'should properly set exp based on the default 1-hour ttl' do
24
+ seconds = Time.now.to_i
25
+ token = @capability.generate_token
26
+ decoded, header = JWT.decode token, 'foobar'
27
+ expect(decoded['exp']).to eq(seconds + 3600)
28
+ end
29
+
30
+ it 'should properly set exp based on the ttl arg to #generate_token' do
31
+ seconds = Time.now.to_i
32
+ ttl = rand 10000
33
+ token = @capability.generate_token ttl
34
+ decoded, header = JWT.decode token, 'foobar'
35
+ expect(decoded['exp']).to eq(seconds + ttl)
36
+ end
37
+
38
+ it 'should allow websocket operations and activity list fetches by default' do
39
+ token = @capability.generate_token
40
+ decoded, header = JWT.decode token, 'foobar'
41
+ expect(decoded['policies'].size).to eq(3)
42
+ get_policy = {
43
+ "url" => 'https://event-bridge.twilio.com/v1/wschannels/AC123/WK789',
44
+ "method" => 'GET',
45
+ "query_filter" => {},
46
+ "post_filter" => {},
47
+ "allow" => true
48
+ }
49
+ expect(decoded['policies'][0]).to eq(get_policy)
50
+ post_policy = {
51
+ "url" => 'https://event-bridge.twilio.com/v1/wschannels/AC123/WK789',
52
+ "method" => 'POST',
53
+ "query_filter" => {},
54
+ "post_filter" => {},
55
+ "allow" => true
56
+ }
57
+ expect(decoded['policies'][1]).to eq(post_policy)
58
+
59
+ activities_policy = {
60
+ 'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Activities',
61
+ 'method' => 'GET',
62
+ 'query_filter' => {},
63
+ 'post_filter' => {},
64
+ 'allow' => true
65
+ }
66
+ expect(decoded['policies'][2]).to eq(activities_policy)
67
+ end
68
+
69
+ it 'should add a policy when #allow_worker_activity_updates is called' do
70
+ @capability.allow_worker_activity_updates
71
+ token = @capability.generate_token
72
+ decoded, header = JWT.decode token, 'foobar'
73
+ expect(decoded['policies'].size).to eq(4)
74
+ activity_policy = {
75
+ 'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Workers/WK789',
76
+ 'method' => 'POST',
77
+ 'query_filter' => {},
78
+ 'post_filter' => {'ActivitySid' => {'required' => true}},
79
+ 'allow' => true
80
+ }
81
+ expect(decoded['policies'][-1]).to eq(activity_policy)
82
+ end
83
+
84
+ it 'should add a policy when #allow_worker_fetch_attributes is called' do
85
+ @capability.allow_worker_fetch_attributes
86
+ token = @capability.generate_token
87
+ decoded, header = JWT.decode token, 'foobar'
88
+ expect(decoded['policies'].size).to eq(4)
89
+ worker_policy = {
90
+ 'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Workers/WK789',
91
+ 'method' => 'GET',
92
+ 'query_filter' => {},
93
+ 'post_filter' => {},
94
+ 'allow' => true
95
+ }
96
+ expect(decoded['policies'][-1]).to eq(worker_policy)
97
+ end
98
+
99
+ it 'should add a policy when #allow_task_reservation_updates is called' do
100
+ @capability.allow_task_reservation_updates
101
+ token = @capability.generate_token
102
+ decoded, header = JWT.decode token, 'foobar'
103
+ expect(decoded['policies'].size).to eq(4)
104
+ task_policy = {
105
+ 'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Tasks/**',
106
+ 'method' => 'POST',
107
+ 'query_filter' => {},
108
+ 'post_filter' => {'ReservationStatus' => {'required' => true}},
109
+ 'allow' => true
110
+ }
111
+ expect(decoded['policies'][-1]).to eq(task_policy)
112
+ end
113
+ end
114
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twilio-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.15.0
4
+ version: 3.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Benton
@@ -153,6 +153,7 @@ files:
153
153
  - lib/twilio-ruby/rest/list_resource.rb
154
154
  - lib/twilio-ruby/rest/media.rb
155
155
  - lib/twilio-ruby/rest/messages.rb
156
+ - lib/twilio-ruby/rest/next_gen_list_resource.rb
156
157
  - lib/twilio-ruby/rest/notifications.rb
157
158
  - lib/twilio-ruby/rest/outgoing_caller_ids.rb
158
159
  - lib/twilio-ruby/rest/queues.rb
@@ -170,12 +171,26 @@ files:
170
171
  - lib/twilio-ruby/rest/sms.rb
171
172
  - lib/twilio-ruby/rest/sms/messages.rb
172
173
  - lib/twilio-ruby/rest/sms/short_codes.rb
174
+ - lib/twilio-ruby/rest/task_router/activities.rb
175
+ - lib/twilio-ruby/rest/task_router/events.rb
176
+ - lib/twilio-ruby/rest/task_router/reservations.rb
177
+ - lib/twilio-ruby/rest/task_router/task_queues.rb
178
+ - lib/twilio-ruby/rest/task_router/task_queues_statistics.rb
179
+ - lib/twilio-ruby/rest/task_router/tasks.rb
180
+ - lib/twilio-ruby/rest/task_router/workers.rb
181
+ - lib/twilio-ruby/rest/task_router/workers_statistics.rb
182
+ - lib/twilio-ruby/rest/task_router/workflow_statistics.rb
183
+ - lib/twilio-ruby/rest/task_router/workflows.rb
184
+ - lib/twilio-ruby/rest/task_router/workspace_statistics.rb
185
+ - lib/twilio-ruby/rest/task_router/workspaces.rb
173
186
  - lib/twilio-ruby/rest/tokens.rb
174
187
  - lib/twilio-ruby/rest/transcriptions.rb
175
188
  - lib/twilio-ruby/rest/usage.rb
176
189
  - lib/twilio-ruby/rest/usage/records.rb
177
190
  - lib/twilio-ruby/rest/usage/triggers.rb
178
191
  - lib/twilio-ruby/rest/utils.rb
192
+ - lib/twilio-ruby/task_router.rb
193
+ - lib/twilio-ruby/task_router/capability.rb
179
194
  - lib/twilio-ruby/twiml/response.rb
180
195
  - lib/twilio-ruby/util.rb
181
196
  - lib/twilio-ruby/util/capability.rb
@@ -197,10 +212,13 @@ files:
197
212
  - spec/rest/recording_spec.rb
198
213
  - spec/rest/sms/message_spec.rb
199
214
  - spec/rest/sms/messages_spec.rb
215
+ - spec/rest/task_router/reservation_spec.rb
216
+ - spec/rest/task_router/task_queue_spec.rb
200
217
  - spec/rest/token_spec.rb
201
218
  - spec/rest/utils_spec.rb
202
219
  - spec/spec_helper.rb
203
220
  - spec/support/fakeweb.rb
221
+ - spec/task_router_spec.rb
204
222
  - spec/twilio_spec.rb
205
223
  - spec/util/capability_spec.rb
206
224
  - spec/util/configuration_spec.rb
@@ -254,10 +272,13 @@ test_files:
254
272
  - spec/rest/recording_spec.rb
255
273
  - spec/rest/sms/message_spec.rb
256
274
  - spec/rest/sms/messages_spec.rb
275
+ - spec/rest/task_router/reservation_spec.rb
276
+ - spec/rest/task_router/task_queue_spec.rb
257
277
  - spec/rest/token_spec.rb
258
278
  - spec/rest/utils_spec.rb
259
279
  - spec/spec_helper.rb
260
280
  - spec/support/fakeweb.rb
281
+ - spec/task_router_spec.rb
261
282
  - spec/twilio_spec.rb
262
283
  - spec/util/capability_spec.rb
263
284
  - spec/util/configuration_spec.rb