twilio-ruby 4.9.1 → 4.10.0.edge

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ad8c952ac5958e476622d7c2dc41af0b66c85cf
4
- data.tar.gz: 2058f8524b23c47d60956ed53c15531a7a483f15
3
+ metadata.gz: bb00225c470d6aa3ea0ba2a72c34f2078c3965a2
4
+ data.tar.gz: 32c48483bdd58ffa6e99fb842ad6fe82264300e2
5
5
  SHA512:
6
- metadata.gz: c5acd95e6d7843836eeeb0fb123857074b098818385a4c443bc4ce7ecce14bb56ad96c5c265ed326468eb8ba59407acc9313c44c0d6946cd05f7017eb9b02638
7
- data.tar.gz: 5b529ff5f673b78dc31cc6edc2f728646e35a70b3d31ca77931d1a1aadd9e84e9a22c7aebc7a32a0b0b401d5a91271ed9162f406d61b71bb39dc81e25515d1f3
6
+ metadata.gz: cc126639b3455f0be6c0d3f69d82e02d91e6dbcc5e3e958dcf4a42993dfacf3ee06cd9b94f74fb79dfd442138acc6d027f4ef8f403eacd198314ebf15c62d5ed
7
+ data.tar.gz: 00ca225a65c495655c163dc85df394272f4c993077701b74c590d897b81669a42aa89103debc669776bbea882ea0018e7c5869a46fa9b47b635ae22e3d26ce37
data/CHANGES.md CHANGED
@@ -1,10 +1,18 @@
1
1
  twilio-ruby changelog
2
2
  =====================
3
3
 
4
+ Version 4.10.0-edge
5
+ -------------
6
+
7
+ Released January 28, 2016:
8
+
9
+ - Add support for filter_friendly_name in WorkflowConfig
10
+ - Load reservations by default in TaskRouter
11
+
4
12
  Version 4.9.1
5
13
  -------------
6
14
 
7
- Release January 28, 2015
15
+ Release January 28, 2016
8
16
 
9
17
  - Fix ip messaging first person grant
10
18
 
@@ -36,6 +36,10 @@ require 'twilio-ruby/rest/pricing/phone_numbers'
36
36
  require 'twilio-ruby/rest/pricing/voice/numbers'
37
37
  require 'twilio-ruby/rest/pricing/voice'
38
38
  require 'twilio-ruby/rest/pricing/messaging'
39
+ require 'twilio-ruby/rest/conversations/in_progress'
40
+ require 'twilio-ruby/rest/conversations/completed'
41
+ require 'twilio-ruby/rest/conversations/conversations'
42
+ require 'twilio-ruby/rest/conversations/participants'
39
43
  require 'twilio-ruby/rest/ip-messaging/services'
40
44
  require 'twilio-ruby/rest/ip-messaging/channels'
41
45
  require 'twilio-ruby/rest/ip-messaging/members'
@@ -104,6 +108,7 @@ require 'twilio-ruby/rest/notifications'
104
108
  require 'twilio-ruby/rest/addresses'
105
109
  require 'twilio-ruby/rest/addresses/dependent_phone_numbers'
106
110
  require 'twilio-ruby/rest/client'
111
+ require 'twilio-ruby/rest/conversations_client'
107
112
  require 'twilio-ruby/rest/task_router_client'
108
113
  require 'twilio-ruby/rest/trunking_client'
109
114
  require 'twilio-ruby/rest/lookups_client'
@@ -0,0 +1,13 @@
1
+ module Twilio
2
+ module REST
3
+ module Conversations
4
+ class Completed < NextGenListResource
5
+ def initialize(path, client)
6
+ @path, @client = path, client
7
+ @instance_class = Twilio::REST::Conversations::Conversation
8
+ @instance_id_key = 'sid'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ module Twilio
2
+ module REST
3
+ module Conversations
4
+ class Conversations < NextGenListResource
5
+ def initialize(path, client)
6
+ @path, @client = path, client
7
+ @submodule = :Conversations
8
+ freeze_path
9
+ resource :in_progress,
10
+ :completed
11
+ end
12
+ end
13
+
14
+ class Conversation < InstanceResource
15
+ def initialize(path, client, params={})
16
+ super
17
+ @submodule = :Conversations
18
+ resource :participants
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ module Twilio
2
+ module REST
3
+ module Conversations
4
+ class InProgress < NextGenListResource
5
+ def initialize(path, client)
6
+ @path, @client = path, client
7
+ @instance_class = Twilio::REST::Conversations::Conversation
8
+ @instance_id_key = 'sid'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ module Twilio
2
+ module REST
3
+ module Conversations
4
+ class Participants < NextGenListResource; end
5
+ class Participant < InstanceResource; end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,99 @@
1
+ require 'twilio-ruby/rest/base_client'
2
+ module Twilio
3
+ module REST
4
+ class ConversationsClient < BaseClient
5
+ API_VERSION = 'v1'
6
+
7
+ attr_reader :conversations
8
+
9
+ host 'conversations.twilio.com'
10
+
11
+ ##
12
+ # Instantiate a new HTTP Conversations client to talk to Twilio. The parameters
13
+ # +account_sid+, +auth_token+ are required, unless you have configured
14
+ # them already using the block configure syntax, and used to generate the
15
+ # HTTP basic auth header in each request. The +options+ parameter is a
16
+ # hash of connection configuration options. the following keys are
17
+ # supported:
18
+ #
19
+ # === <tt>host: 'conversations.twilio.com'</tt>
20
+ #
21
+ # The domain to which you'd like the client to make HTTP requests. Useful
22
+ # for testing. Defaults to 'conversations.twilio.com'.
23
+ #
24
+ # === <tt>port: 443</tt>
25
+ #
26
+ # The port on which to connect to the above domain. Defaults to 443 and
27
+ # should be left that way except in testing environments.
28
+ #
29
+ # === <tt>use_ssl: true</tt>
30
+ #
31
+ # Declare whether ssl should be used for connections to the above domain.
32
+ # Defaults to true and should be left alone except when testing.
33
+ #
34
+ # === <tt>ssl_verify_peer: true</tt>
35
+ #
36
+ # Declare whether to verify the host's ssl cert when setting up the
37
+ # connection to the above domain. Defaults to true, but can be turned off
38
+ # to avoid ssl certificate verification failures in environments without
39
+ # the necessary ca certificates.
40
+ #
41
+ # === <tt>ssl_ca_file: '/path/to/ca/file'</tt>
42
+ #
43
+ # Specify the path to the certificate authority bundle you'd like to use
44
+ # to verify Twilio's SSL certificate on each request. If not specified, a
45
+ # certificate bundle extraced from Firefox is packaged with the gem and
46
+ # used by default.
47
+ #
48
+ # === <tt>timeout: 30</tt>
49
+ #
50
+ # Set the time in seconds to wait before timing out the HTTP request.
51
+ # Defaults to 30 seconds. If you aren't fetching giant pages of call or
52
+ # SMS logs you can safely decrease this to something like 3 seconds or
53
+ # lower. In paricular if you are sending SMS you can set this to 1 second
54
+ # or less and swallow the exception if you don't care about the response.
55
+ #
56
+ # === <tt>proxy_addr: 'proxy.host.domain'</tt>
57
+ #
58
+ # The domain of a proxy through which you'd like the client to make HTTP
59
+ # requests. Defaults to nil.
60
+ #
61
+ # === <tt>proxy_port: 3128</tt>
62
+ #
63
+ # The port on which to connect to the above proxy. Defaults to nil.
64
+ #
65
+ # === <tt>proxy_user: 'username'</tt>
66
+ #
67
+ # The user name to use for authentication with the proxy. Defaults to nil.
68
+ #
69
+ # === <tt>proxy_pass: 'password'</tt>
70
+ #
71
+ # The password to use for authentication with the proxy. Defaults to nil.
72
+ #
73
+ # === <tt>retry_limit: 1</tt>
74
+ #
75
+ # The number of times to retry a request that has failed before throwing
76
+ # an exception. Defaults to one.
77
+ def inspect # :nodoc:
78
+ "<Twilio::REST::ConversationsClient @account_sid=#{@account_sid}>"
79
+ end
80
+
81
+ protected
82
+
83
+ ##
84
+ # Create subresource properties
85
+ def set_up_subresources # :doc:
86
+ @conversations = Twilio::REST::Conversations::Conversations.new "/#{API_VERSION}/Conversations", self
87
+ end
88
+
89
+ ##
90
+ # Builds up full request path
91
+ def build_full_path(path, params, method)
92
+ path = path.dup
93
+ path << "?#{url_encode(params)}" if method == :get && !params.empty?
94
+ path
95
+ end
96
+
97
+ end
98
+ end
99
+ end
@@ -10,7 +10,7 @@ module Twilio
10
10
  'Countries' => 'Country',
11
11
  'Feedback' => 'FeedbackInstance',
12
12
  'IpAddresses' => 'IpAddress',
13
- 'Media' => 'MediaInstance',
13
+ 'Media' => 'MediaInstance'
14
14
  }
15
15
  @path, @client = path, client
16
16
  resource_name = self.class.name.split('::')[-1]
@@ -46,7 +46,8 @@ module Twilio
46
46
  raise "Can't get a resource list without a REST Client" unless @client
47
47
  response = @client.get @path, params, full_path
48
48
  resources = response[@list_key]
49
- path = full_path ? @path.split('.')[0] : @path
49
+ path = @frozen_path ? @frozen_path : @path
50
+ path = full_path ? path.split('.')[0] : path
50
51
  resource_list = resources.map do |resource|
51
52
  @instance_class.new "#{path}/#{resource[@instance_id_key]}", @client,
52
53
  resource
@@ -80,7 +81,7 @@ module Twilio
80
81
  # attribute of the returned instance resource object, such as
81
82
  # its #date_created or #voice_url attributes.
82
83
  def get(sid)
83
- @instance_class.new "#{@path}/#{sid}", @client
84
+ @instance_class.new "#{@frozen_path || @path}/#{sid}", @client
84
85
  end
85
86
  alias :find :get # for the ActiveRecord lovers
86
87
 
@@ -4,11 +4,12 @@ module Twilio
4
4
  def list(params={}, full_path=false)
5
5
  raise "Can't get a resource list without a REST Client" unless @client
6
6
  response = @client.get @path, params, full_path
7
- list_key = response['meta']['key']
7
+ list_key = response['meta']['key'] if response['meta']
8
8
  raise "Couldn't find a list key in response meta" unless list_key
9
9
  resources = response[list_key]
10
+ path = @frozen_path ? @frozen_path : @path
10
11
  resource_list = resources.map do |resource|
11
- @instance_class.new "#{@path}/#{resource[@instance_id_key]}", @client,
12
+ @instance_class.new "#{path}/#{resource[@instance_id_key]}", @client,
12
13
  resource
13
14
  end
14
15
  client, list_class = @client, self.class
@@ -19,6 +19,13 @@ module Twilio
19
19
 
20
20
  protected
21
21
 
22
+ # Freeze the base list path.
23
+ # Used on list resources so filters (such as /Local) do not affect the
24
+ # instance resource path.
25
+ def freeze_path
26
+ @frozen_path = @path
27
+ end
28
+
22
29
  def resource(*resources)
23
30
  custom_resource_names = { sms: 'SMS', sip: 'SIP' }
24
31
  resources.each do |r|
@@ -31,7 +38,11 @@ module Twilio
31
38
  Twilio::REST.const_get(@submodule)
32
39
  end
33
40
  resource_class = enclosing_module.const_get resource
34
- instance_variable_set("@#{r}", resource_class.new(path, @client))
41
+ resource_object = resource_class.new(path, @client)
42
+ instance_variable_set("@#{r}", resource_object)
43
+ if @frozen_path
44
+ resource_object.instance_variable_set(:@frozen_path, @frozen_path)
45
+ end
35
46
  end
36
47
  self.class.instance_eval { attr_reader *resources }
37
48
  end
@@ -136,8 +136,11 @@ module Twilio
136
136
  @activityUrl = @baseUrl + "/Activities"
137
137
  allow(@activityUrl, "GET")
138
138
 
139
- @reservationsUrl = @baseUrl + "/Tasks/**"
140
- allow(@reservationsUrl, "GET")
139
+ @tasksUrl = @baseUrl + "/Tasks/**"
140
+ allow(@tasksUrl, "GET")
141
+
142
+ @workerReservationsUrl = @resourceUrl + "/Reservations/**"
143
+ allow(@workerReservationsUrl, "GET")
141
144
 
142
145
  elsif(@channel_id[0..1] == 'WQ')
143
146
  @resourceUrl = @baseUrl + "/TaskQueues/" + @channel_id
@@ -171,11 +174,13 @@ module Twilio
171
174
 
172
175
  def initialize(account_sid, auth_token, workspace_sid, worker_sid)
173
176
  super(account_sid, auth_token, workspace_sid, worker_sid)
174
- @reservationsUrl = @baseUrl + "/Tasks/**"
177
+ @tasksUrl = @baseUrl + "/Tasks/**"
175
178
  @activityUrl = @baseUrl + "/Activities"
179
+ @workerReservationsUrl = @resourceUrl + "/Reservations/**"
176
180
 
177
181
  allow(@activityUrl, "GET")
178
- allow(@reservationsUrl, "GET")
182
+ allow(@tasksUrl, "GET")
183
+ allow(@workerReservationsUrl, "GET")
179
184
  end
180
185
 
181
186
  def allow_activity_updates
@@ -183,7 +188,8 @@ module Twilio
183
188
  end
184
189
 
185
190
  def allow_reservation_updates
186
- allow(@reservationsUrl, "POST", nil, nil)
191
+ allow(@tasksUrl, "POST", nil, nil)
192
+ allow(@workerReservationsUrl, "POST", nil, nil)
187
193
  end
188
194
 
189
195
  protected
@@ -79,7 +79,13 @@ module Twilio
79
79
  rule['targets'].each do |target|
80
80
  targets.push(Twilio::TaskRouter::WorkflowRuleTarget.parse_json(target))
81
81
  end
82
- Twilio::TaskRouter::WorkflowRule.new rule['expression'], targets, rule['friendly_name']
82
+ unless rule['filter_friendly_name'].nil?
83
+ friendly_name = rule['filter_friendly_name']
84
+ end
85
+ unless rule['friendly_name'].nil?
86
+ friendly_name = rule['friendly_name']
87
+ end
88
+ Twilio::TaskRouter::WorkflowRule.new rule['expression'], targets, friendly_name
83
89
  end
84
90
  end
85
91
  class WorkflowRuleTarget
@@ -1,3 +1,3 @@
1
1
  module Twilio
2
- VERSION = '4.9.1'
2
+ VERSION = '4.10.0.edge'
3
3
  end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twilio::REST::Conversations::Conversations do
4
+
5
+ it 'creates an in_progress property' do
6
+ client = Twilio::REST::ConversationsClient.new 'otherSid', 'otherToken'
7
+ conversations = Twilio::REST::Conversations::Conversations.new '/v1/Conversations', client
8
+ expect(conversations).to respond_to(:in_progress)
9
+ end
10
+
11
+ it 'creates a completed property' do
12
+ client = Twilio::REST::ConversationsClient.new 'otherSid', 'otherToken'
13
+ conversations = Twilio::REST::Conversations::Conversations.new '/v1/Conversations', client
14
+ expect(conversations).to respond_to(:completed)
15
+ end
16
+
17
+ end
18
+
19
+ describe Twilio::REST::Conversations::InProgress do
20
+ it 'gets constructed by conversations' do
21
+ client = Twilio::REST::ConversationsClient.new 'otherSid', 'otherToken'
22
+ conversations = Twilio::REST::Conversations::Conversations.new '/v1/Conversations', client
23
+ expect(conversations.in_progress.instance_variable_get('@path')).to eq('/v1/Conversations/InProgress')
24
+ end
25
+ it 'uses Conversation as its instance class' do
26
+ client = Twilio::REST::ConversationsClient.new 'otherSid', 'otherToken'
27
+ conversations = Twilio::REST::Conversations::Conversations.new '/v1/Conversations', client
28
+ expect(conversations.in_progress.instance_variable_get('@instance_class')).to eq(Twilio::REST::Conversations::Conversation)
29
+ end
30
+ end
31
+
32
+ describe Twilio::REST::Conversations::Completed do
33
+ it 'gets constructed by conversations' do
34
+ client = Twilio::REST::ConversationsClient.new 'otherSid', 'otherToken'
35
+ conversations = Twilio::REST::Conversations::Conversations.new '/v1/Conversations', client
36
+ expect(conversations.completed.instance_variable_get('@path')).to eq('/v1/Conversations/Completed')
37
+ end
38
+ it 'uses Conversation as its instance class' do
39
+ client = Twilio::REST::ConversationsClient.new 'otherSid', 'otherToken'
40
+ conversations = Twilio::REST::Conversations::Conversations.new '/v1/Conversations', client
41
+ expect(conversations.completed.instance_variable_get('@instance_class')).to eq(Twilio::REST::Conversations::Conversation)
42
+ end
43
+ end
44
+
45
+ describe Twilio::REST::Conversations::Conversation do
46
+ it 'has correct path when fetched from /InProgress' do
47
+ client = Twilio::REST::ConversationsClient.new 'otherSid', 'otherToken'
48
+ conversation = client.conversations.in_progress.get('CA123')
49
+ expect(conversation.instance_variable_get('@path')).to eq('/v1/Conversations/CA123')
50
+ end
51
+ it 'has correct path when fetched from /Completed' do
52
+ client = Twilio::REST::ConversationsClient.new 'otherSid', 'otherToken'
53
+ conversation = client.conversations.completed.get('CA123')
54
+ expect(conversation.instance_variable_get('@path')).to eq('/v1/Conversations/CA123')
55
+ end
56
+ it 'sets up participants subresource' do
57
+ client = Twilio::REST::ConversationsClient.new 'otherSid', 'otherToken'
58
+ conversation = Twilio::REST::Conversations::Conversation.new '/v1/Conversations/CA123', client
59
+ expect(conversation).to respond_to(:participants)
60
+ end
61
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twilio::REST::ConversationsClient do
4
+ before do
5
+ @client = Twilio::REST::ConversationsClient.new('AC123', 'foobar')
6
+ end
7
+
8
+ it 'should set up an conversations resources object' do
9
+ expect(@client).to respond_to(:conversations)
10
+ expect(@client.conversations.instance_variable_get('@path')).to eq('/v1/Conversations')
11
+ end
12
+
13
+ end
@@ -0,0 +1,501 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twilio::TaskRouter::WorkflowConfiguration do
4
+ describe 'with a workflow builder' do
5
+
6
+ it 'should construct a default rule target' do
7
+ everyoneQueue = 'WQf6724bd5005b30eeb6ea990c3e59e536'
8
+ defaultTarget = Twilio::TaskRouter::WorkflowRuleTarget.new everyoneQueue
9
+ expect(defaultTarget.queue).to eq(everyoneQueue)
10
+ expect(defaultTarget.priority).to be_nil
11
+ expect(defaultTarget.timeout).to be_nil
12
+ expect(defaultTarget.expression).to be_nil
13
+ end
14
+
15
+ it 'should construct a simple rule target' do
16
+ everyoneQueue = 'WQf6724bd5005b30eeb6ea990c3e59e536'
17
+ priority = 10
18
+ timeout = 60
19
+ defaultTarget = Twilio::TaskRouter::WorkflowRuleTarget.new everyoneQueue, priority, timeout
20
+ expect(defaultTarget.queue).to eq(everyoneQueue)
21
+ expect(defaultTarget.priority).to eq(priority)
22
+ expect(defaultTarget.timeout).to eq(timeout)
23
+ expect(defaultTarget.expression).to be_nil
24
+ end
25
+
26
+ it 'should construct a worker filter rule target' do
27
+ everyoneQueue = 'WQf6724bd5005b30eeb6ea990c3e59e536'
28
+ priority = 10
29
+ timeout = 60
30
+ filterWorkerExpression = "task.language IN worker.languages";
31
+ defaultTarget = Twilio::TaskRouter::WorkflowRuleTarget.new everyoneQueue, priority, timeout, filterWorkerExpression
32
+ expect(defaultTarget.queue).to eq(everyoneQueue)
33
+ expect(defaultTarget.priority).to eq(priority)
34
+ expect(defaultTarget.timeout).to eq(timeout)
35
+ expect(defaultTarget.expression).to eq(filterWorkerExpression)
36
+ end
37
+
38
+ it 'should construct simple rule' do
39
+ salesQueue = "WQf6724bd5005b30eeb6ea990c3e59e536"
40
+ salesTarget = Twilio::TaskRouter::WorkflowRuleTarget.new salesQueue
41
+ expression = "type=='sales'"
42
+ friendlyName = "Sales"
43
+ salesTargets = [salesTarget]
44
+ salesRule = Twilio::TaskRouter::WorkflowRule.new expression, salesTargets, friendlyName
45
+ expect(salesRule.expression).to eq(expression)
46
+ expect(salesRule.friendly_name).to eq(friendlyName)
47
+ expect(salesRule.targets[0]).to eq(salesTarget)
48
+ end
49
+
50
+ it 'should construct a full workflow' do
51
+ salesQueue = "WQf6724bd5005b30eeb6ea990c3e59e536"
52
+ marketingQueue = "WQ8c62f84b61ccfa6a333757cd508f0aae"
53
+ supportQueue = "WQ5940dc0da87eaf6e3321d62041d4403b"
54
+ everyoneQueue = "WQ6d29383312b24bd898a8df32779fc043"
55
+
56
+ defaultTarget = Twilio::TaskRouter::WorkflowRuleTarget.new everyoneQueue
57
+
58
+ salesTarget = Twilio::TaskRouter::WorkflowRuleTarget.new salesQueue
59
+ salesRule = Twilio::TaskRouter::WorkflowRule.new "type=='sales'", [salesTarget], 'Sales'
60
+
61
+ marketingTarget = Twilio::TaskRouter::WorkflowRuleTarget.new marketingQueue
62
+ marketingRule = Twilio::TaskRouter::WorkflowRule.new "type=='marketing'", [marketingTarget], 'Marketing'
63
+
64
+ supportTarget = Twilio::TaskRouter::WorkflowRuleTarget.new supportQueue
65
+ supportRule = Twilio::TaskRouter::WorkflowRule.new "type=='support'", [supportTarget], 'Support'
66
+
67
+ rules = [salesRule, marketingRule, supportRule]
68
+
69
+ config = Twilio::TaskRouter::WorkflowConfiguration.new rules, defaultTarget
70
+ json = config.to_json
71
+
72
+ expected = "{
73
+ \"task_routing\":{
74
+ \"filters\":[
75
+ {
76
+ \"expression\":\"type=='sales'\",
77
+ \"targets\":[
78
+ {
79
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\"
80
+ }
81
+ ],
82
+ \"friendly_name\":\"Sales\"
83
+ },
84
+ {
85
+ \"expression\":\"type=='marketing'\",
86
+ \"targets\":[
87
+ {
88
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\"
89
+ }
90
+ ],
91
+ \"friendly_name\":\"Marketing\"
92
+ },
93
+ {
94
+ \"expression\":\"type=='support'\",
95
+ \"targets\":[
96
+ {
97
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\"
98
+ }
99
+ ],
100
+ \"friendly_name\":\"Support\"
101
+ }
102
+ ],
103
+ \"default_filter\":{
104
+ \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
105
+ }
106
+ }
107
+ }"
108
+
109
+ expected = JSON.parse(expected).to_json
110
+
111
+ expect(expected).to eq(json)
112
+ end
113
+
114
+ it 'should construct a full workflow with timeouts' do
115
+ salesQueue = "WQf6724bd5005b30eeb6ea990c3e59e536"
116
+ marketingQueue = "WQ8c62f84b61ccfa6a333757cd508f0aae"
117
+ supportQueue = "WQ5940dc0da87eaf6e3321d62041d4403b"
118
+ everyoneQueue = "WQ6d29383312b24bd898a8df32779fc043"
119
+
120
+ defaultTarget = Twilio::TaskRouter::WorkflowRuleTarget.new everyoneQueue
121
+
122
+ salesTarget1 = Twilio::TaskRouter::WorkflowRuleTarget.new salesQueue, 5, 30
123
+ salesTarget2 = Twilio::TaskRouter::WorkflowRuleTarget.new salesQueue, 10
124
+ salesRule = Twilio::TaskRouter::WorkflowRule.new "type=='sales'", [salesTarget1, salesTarget2], 'Sales'
125
+
126
+ marketingTarget1 = Twilio::TaskRouter::WorkflowRuleTarget.new marketingQueue, 1, 120
127
+ marketingTarget2 = Twilio::TaskRouter::WorkflowRuleTarget.new marketingQueue, 3
128
+ marketingRule = Twilio::TaskRouter::WorkflowRule.new "type=='marketing'", [marketingTarget1, marketingTarget2], 'Marketing'
129
+
130
+ supportTarget1 = Twilio::TaskRouter::WorkflowRuleTarget.new supportQueue, 10, 30
131
+ supportTarget2 = Twilio::TaskRouter::WorkflowRuleTarget.new supportQueue, 15
132
+ supportRule = Twilio::TaskRouter::WorkflowRule.new "type=='support'", [supportTarget1, supportTarget2], 'Support'
133
+
134
+ rules = [salesRule, marketingRule, supportRule]
135
+
136
+ config = Twilio::TaskRouter::WorkflowConfiguration.new rules, defaultTarget
137
+ json = config.to_json
138
+
139
+ expected = "{
140
+ \"task_routing\":{
141
+ \"filters\":[
142
+ {
143
+ \"expression\":\"type=='sales'\",
144
+ \"targets\":[
145
+ {
146
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
147
+ \"priority\": 5,
148
+ \"timeout\": 30
149
+ },
150
+ {
151
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
152
+ \"priority\": 10
153
+ }
154
+ ],
155
+ \"friendly_name\":\"Sales\"
156
+ },
157
+ {
158
+ \"expression\":\"type=='marketing'\",
159
+ \"targets\":[
160
+ {
161
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
162
+ \"priority\": 1,
163
+ \"timeout\": 120
164
+ },
165
+ {
166
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
167
+ \"priority\": 3
168
+ }
169
+ ],
170
+ \"friendly_name\":\"Marketing\"
171
+ },
172
+ {
173
+ \"expression\":\"type=='support'\",
174
+ \"targets\":[
175
+ {
176
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
177
+ \"priority\": 10,
178
+ \"timeout\": 30
179
+ },
180
+ {
181
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
182
+ \"priority\": 15
183
+ }
184
+ ],
185
+ \"friendly_name\":\"Support\"
186
+ }
187
+ ],
188
+ \"default_filter\":{
189
+ \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
190
+ }
191
+ }
192
+ }";
193
+
194
+ expected = JSON.parse(expected).to_json
195
+
196
+ expect(expected).to eq(json)
197
+ end
198
+
199
+ it 'should be able to parse the workflow' do
200
+ json = "{
201
+ \"task_routing\":{
202
+ \"filters\":[
203
+ {
204
+ \"expression\":\"type=='sales'\",
205
+ \"targets\":[
206
+ {
207
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
208
+ \"priority\": 5,
209
+ \"timeout\": 30
210
+ },
211
+ {
212
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
213
+ \"priority\": 10
214
+ }
215
+ ],
216
+ \"friendly_name\":\"Sales\"
217
+ },
218
+ {
219
+ \"expression\":\"type=='marketing'\",
220
+ \"targets\":[
221
+ {
222
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
223
+ \"priority\": 1,
224
+ \"timeout\": 120
225
+ },
226
+ {
227
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
228
+ \"priority\": 3
229
+ }
230
+ ],
231
+ \"friendly_name\":\"Marketing\"
232
+ },
233
+ {
234
+ \"expression\":\"type=='support'\",
235
+ \"targets\":[
236
+ {
237
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
238
+ \"priority\": 10,
239
+ \"timeout\": 30
240
+ },
241
+ {
242
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
243
+ \"priority\": 15
244
+ }
245
+ ],
246
+ \"friendly_name\":\"Support\"
247
+ }
248
+ ],
249
+ \"default_filter\":{
250
+ \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
251
+ }
252
+ }
253
+ }"
254
+
255
+ config = Twilio::TaskRouter::WorkflowConfiguration.parse_json(json)
256
+
257
+ expect(config.rules.length).to eq(3)
258
+ expect(config.default_target).to_not be_nil
259
+ # sales assertions
260
+ expect(config.rules[0].expression).to eq("type=='sales'")
261
+ expect(config.rules[0].friendly_name).to eq("Sales")
262
+ expect(config.rules[0].targets.length).to eq(2)
263
+ expect(config.rules[0].targets[0].queue).to eq("WQf6724bd5005b30eeb6ea990c3e59e536")
264
+ expect(config.rules[0].targets[0].priority).to eq(5)
265
+ expect(config.rules[0].targets[0].timeout).to eq(30)
266
+ expect(config.rules[0].targets[1].queue).to eq("WQf6724bd5005b30eeb6ea990c3e59e536")
267
+ expect(config.rules[0].targets[1].priority).to eq(10)
268
+ # marketing assertions
269
+ expect(config.rules[1].expression).to eq("type=='marketing'")
270
+ expect(config.rules[1].friendly_name).to eq("Marketing")
271
+ expect(config.rules[1].targets.length).to eq(2)
272
+ expect(config.rules[1].targets[0].queue).to eq("WQ8c62f84b61ccfa6a333757cd508f0aae")
273
+ expect(config.rules[1].targets[0].priority).to eq(1)
274
+ expect(config.rules[1].targets[0].timeout).to eq(120)
275
+ expect(config.rules[1].targets[1].queue).to eq("WQ8c62f84b61ccfa6a333757cd508f0aae")
276
+ expect(config.rules[1].targets[1].priority).to eq(3)
277
+ # support assertions
278
+ expect(config.rules[2].expression).to eq("type=='support'")
279
+ expect(config.rules[2].friendly_name).to eq("Support")
280
+ expect(config.rules[2].targets.length).to eq(2)
281
+ expect(config.rules[2].targets[0].queue).to eq("WQ5940dc0da87eaf6e3321d62041d4403b")
282
+ expect(config.rules[2].targets[0].priority).to eq(10)
283
+ expect(config.rules[2].targets[0].timeout).to eq(30)
284
+ expect(config.rules[2].targets[1].queue).to eq("WQ5940dc0da87eaf6e3321d62041d4403b")
285
+ expect(config.rules[2].targets[1].priority).to eq(15)
286
+ # default filter
287
+ expect(config.default_target.queue).to eq("WQ6d29383312b24bd898a8df32779fc043")
288
+ end
289
+
290
+ it 'should be able to parse the workflow with filter friendly name' do
291
+ json = "{
292
+ \"task_routing\":{
293
+ \"filters\":[
294
+ {
295
+ \"expression\":\"type=='sales'\",
296
+ \"targets\":[
297
+ {
298
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
299
+ \"priority\": 5,
300
+ \"timeout\": 30
301
+ },
302
+ {
303
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
304
+ \"priority\": 10
305
+ }
306
+ ],
307
+ \"filter_friendly_name\":\"Sales\"
308
+ },
309
+ {
310
+ \"expression\":\"type=='marketing'\",
311
+ \"targets\":[
312
+ {
313
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
314
+ \"priority\": 1,
315
+ \"timeout\": 120
316
+ },
317
+ {
318
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
319
+ \"priority\": 3
320
+ }
321
+ ],
322
+ \"filter_friendly_name\":\"Marketing\"
323
+ },
324
+ {
325
+ \"expression\":\"type=='support'\",
326
+ \"targets\":[
327
+ {
328
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
329
+ \"priority\": 10,
330
+ \"timeout\": 30
331
+ },
332
+ {
333
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
334
+ \"priority\": 15
335
+ }
336
+ ],
337
+ \"filter_friendly_name\":\"Support\"
338
+ }
339
+ ],
340
+ \"default_filter\":{
341
+ \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
342
+ }
343
+ }
344
+ }"
345
+
346
+ config = Twilio::TaskRouter::WorkflowConfiguration.parse_json(json)
347
+
348
+ expect(config.rules.length).to eq(3)
349
+ expect(config.default_target).to_not be_nil
350
+ # sales assertions
351
+ expect(config.rules[0].expression).to eq("type=='sales'")
352
+ expect(config.rules[0].friendly_name).to eq("Sales")
353
+ expect(config.rules[0].targets.length).to eq(2)
354
+ expect(config.rules[0].targets[0].queue).to eq("WQf6724bd5005b30eeb6ea990c3e59e536")
355
+ expect(config.rules[0].targets[0].priority).to eq(5)
356
+ expect(config.rules[0].targets[0].timeout).to eq(30)
357
+ expect(config.rules[0].targets[1].queue).to eq("WQf6724bd5005b30eeb6ea990c3e59e536")
358
+ expect(config.rules[0].targets[1].priority).to eq(10)
359
+ # marketing assertions
360
+ expect(config.rules[1].expression).to eq("type=='marketing'")
361
+ expect(config.rules[1].friendly_name).to eq("Marketing")
362
+ expect(config.rules[1].targets.length).to eq(2)
363
+ expect(config.rules[1].targets[0].queue).to eq("WQ8c62f84b61ccfa6a333757cd508f0aae")
364
+ expect(config.rules[1].targets[0].priority).to eq(1)
365
+ expect(config.rules[1].targets[0].timeout).to eq(120)
366
+ expect(config.rules[1].targets[1].queue).to eq("WQ8c62f84b61ccfa6a333757cd508f0aae")
367
+ expect(config.rules[1].targets[1].priority).to eq(3)
368
+ # support assertions
369
+ expect(config.rules[2].expression).to eq("type=='support'")
370
+ expect(config.rules[2].friendly_name).to eq("Support")
371
+ expect(config.rules[2].targets.length).to eq(2)
372
+ expect(config.rules[2].targets[0].queue).to eq("WQ5940dc0da87eaf6e3321d62041d4403b")
373
+ expect(config.rules[2].targets[0].priority).to eq(10)
374
+ expect(config.rules[2].targets[0].timeout).to eq(30)
375
+ expect(config.rules[2].targets[1].queue).to eq("WQ5940dc0da87eaf6e3321d62041d4403b")
376
+ expect(config.rules[2].targets[1].priority).to eq(15)
377
+ # default filter
378
+ expect(config.default_target.queue).to eq("WQ6d29383312b24bd898a8df32779fc043")
379
+ end
380
+
381
+ it 'should be able to parse the workflow with filter friendly name and marshall as friendly name' do
382
+ json = "{
383
+ \"task_routing\":{
384
+ \"filters\":[
385
+ {
386
+ \"expression\":\"type=='sales'\",
387
+ \"targets\":[
388
+ {
389
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
390
+ \"priority\": 5,
391
+ \"timeout\": 30
392
+ },
393
+ {
394
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
395
+ \"priority\": 10
396
+ }
397
+ ],
398
+ \"filter_friendly_name\":\"Sales\"
399
+ },
400
+ {
401
+ \"expression\":\"type=='marketing'\",
402
+ \"targets\":[
403
+ {
404
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
405
+ \"priority\": 1,
406
+ \"timeout\": 120
407
+ },
408
+ {
409
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
410
+ \"priority\": 3
411
+ }
412
+ ],
413
+ \"filter_friendly_name\":\"Marketing\"
414
+ },
415
+ {
416
+ \"expression\":\"type=='support'\",
417
+ \"targets\":[
418
+ {
419
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
420
+ \"priority\": 10,
421
+ \"timeout\": 30
422
+ },
423
+ {
424
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
425
+ \"priority\": 15
426
+ }
427
+ ],
428
+ \"filter_friendly_name\":\"Support\"
429
+ }
430
+ ],
431
+ \"default_filter\":{
432
+ \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
433
+ }
434
+ }
435
+ }"
436
+
437
+ config = Twilio::TaskRouter::WorkflowConfiguration.parse_json(json)
438
+
439
+ newJSON = config.to_json
440
+
441
+ expected = "{
442
+ \"task_routing\":{
443
+ \"filters\":[
444
+ {
445
+ \"expression\":\"type=='sales'\",
446
+ \"targets\":[
447
+ {
448
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
449
+ \"priority\": 5,
450
+ \"timeout\": 30
451
+ },
452
+ {
453
+ \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
454
+ \"priority\": 10
455
+ }
456
+ ],
457
+ \"friendly_name\":\"Sales\"
458
+ },
459
+ {
460
+ \"expression\":\"type=='marketing'\",
461
+ \"targets\":[
462
+ {
463
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
464
+ \"priority\": 1,
465
+ \"timeout\": 120
466
+ },
467
+ {
468
+ \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
469
+ \"priority\": 3
470
+ }
471
+ ],
472
+ \"friendly_name\":\"Marketing\"
473
+ },
474
+ {
475
+ \"expression\":\"type=='support'\",
476
+ \"targets\":[
477
+ {
478
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
479
+ \"priority\": 10,
480
+ \"timeout\": 30
481
+ },
482
+ {
483
+ \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
484
+ \"priority\": 15
485
+ }
486
+ ],
487
+ \"friendly_name\":\"Support\"
488
+ }
489
+ ],
490
+ \"default_filter\":{
491
+ \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
492
+ }
493
+ }
494
+ }"
495
+
496
+ expected = JSON.parse(expected).to_json
497
+
498
+ expect(expected).to eq(newJSON)
499
+ end
500
+ end
501
+ end
@@ -42,7 +42,7 @@ describe Twilio::TaskRouter::Capability do
42
42
  it 'should allow websocket operations and fetching the workspace by default' do
43
43
  token = @capability.generate_token
44
44
  decoded, header = JWT.decode token, 'foobar'
45
- expect(decoded['policies'].size).to eq(5)
45
+ expect(decoded['policies'].size).to eq(6)
46
46
 
47
47
  activites_fetch_policy = {
48
48
  'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Activities',
@@ -53,14 +53,23 @@ describe Twilio::TaskRouter::Capability do
53
53
  }
54
54
  expect(decoded['policies'][0]).to eq(activites_fetch_policy)
55
55
 
56
- reservation_fetch_policy = {
56
+ task_fetch_policy = {
57
57
  'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Tasks/**',
58
58
  'method' => 'GET',
59
59
  'query_filter' => {},
60
60
  'post_filter' => {},
61
61
  'allow' => true
62
62
  }
63
- expect(decoded['policies'][1]).to eq(reservation_fetch_policy)
63
+ expect(decoded['policies'][1]).to eq(task_fetch_policy)
64
+
65
+ worker_reservation_fetch_policy = {
66
+ 'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Workers/WK789/Reservations/**',
67
+ 'method' => 'GET',
68
+ 'query_filter' => {},
69
+ 'post_filter' => {},
70
+ 'allow' => true
71
+ }
72
+ expect(decoded['policies'][2]).to eq(worker_reservation_fetch_policy)
64
73
 
65
74
  get_policy = {
66
75
  "url" => 'https://event-bridge.twilio.com/v1/wschannels/AC123/WK789',
@@ -69,7 +78,7 @@ describe Twilio::TaskRouter::Capability do
69
78
  "post_filter" => {},
70
79
  "allow" => true
71
80
  }
72
- expect(decoded['policies'][2]).to eq(get_policy)
81
+ expect(decoded['policies'][3]).to eq(get_policy)
73
82
  post_policy = {
74
83
  "url" => 'https://event-bridge.twilio.com/v1/wschannels/AC123/WK789',
75
84
  "method" => 'POST',
@@ -77,7 +86,7 @@ describe Twilio::TaskRouter::Capability do
77
86
  "post_filter" => {},
78
87
  "allow" => true
79
88
  }
80
- expect(decoded['policies'][3]).to eq(post_policy)
89
+ expect(decoded['policies'][4]).to eq(post_policy)
81
90
 
82
91
  worker_fetch_policy = {
83
92
  'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Workers/WK789',
@@ -86,7 +95,7 @@ describe Twilio::TaskRouter::Capability do
86
95
  'post_filter' => {},
87
96
  'allow' => true
88
97
  }
89
- expect(decoded['policies'][4]).to eq(worker_fetch_policy)
98
+ expect(decoded['policies'][5]).to eq(worker_fetch_policy)
90
99
  end
91
100
 
92
101
  it 'should add a policy when #allow_worker_activity_updates is called' do
@@ -42,7 +42,7 @@ describe Twilio::TaskRouter::WorkerCapability do
42
42
  it 'should allow websocket operations and activity list fetches by default' do
43
43
  token = @capability.generate_token
44
44
  decoded, header = JWT.decode token, 'foobar'
45
- expect(decoded['policies'].size).to eq(5)
45
+ expect(decoded['policies'].size).to eq(6)
46
46
  get_policy = {
47
47
  "url" => 'https://event-bridge.twilio.com/v1/wschannels/AC123/WK789',
48
48
  "method" => 'GET',
@@ -78,14 +78,23 @@ describe Twilio::TaskRouter::WorkerCapability do
78
78
  }
79
79
  expect(decoded['policies'][3]).to eq(activities_policy)
80
80
 
81
- reservations_policy = {
81
+ tasks_policy = {
82
82
  'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Tasks/**',
83
83
  'method' => 'GET',
84
84
  'query_filter' => {},
85
85
  'post_filter' => {},
86
86
  'allow' => true
87
87
  }
88
- expect(decoded['policies'][4]).to eq(reservations_policy)
88
+ expect(decoded['policies'][4]).to eq(tasks_policy)
89
+
90
+ worker_reservations_policy = {
91
+ 'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Workers/WK789/Reservations/**',
92
+ 'method' => 'GET',
93
+ 'query_filter' => {},
94
+ 'post_filter' => {},
95
+ 'allow' => true
96
+ }
97
+ expect(decoded['policies'][5]).to eq(worker_reservations_policy)
89
98
  end
90
99
 
91
100
  it 'should add a policy when #allow_activity_updates is called' do
@@ -107,7 +116,7 @@ describe Twilio::TaskRouter::WorkerCapability do
107
116
  expect(decoded['policies'].size).to eq(policies_size+1)
108
117
  end
109
118
 
110
- it 'should add a policy when #allow_reservation_updates is called' do
119
+ it 'should add two policies when #allow_reservation_updates is called' do
111
120
  token = @capability.generate_token
112
121
  decoded, header = JWT.decode token, 'foobar'
113
122
  policies_size = decoded['policies'].size
@@ -115,15 +124,23 @@ describe Twilio::TaskRouter::WorkerCapability do
115
124
  @capability.allow_reservation_updates
116
125
  token = @capability.generate_token
117
126
  decoded, header = JWT.decode token, 'foobar'
118
- reservation_policy = {
127
+ tasks_policy = {
119
128
  'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Tasks/**',
120
129
  'method' => 'POST',
121
130
  'query_filter' => {},
122
131
  'post_filter' => {},
123
132
  'allow' => true
124
133
  }
125
- expect(decoded['policies'][-1]).to eq(reservation_policy)
126
- expect(decoded['policies'].size).to eq(policies_size+1)
134
+ expect(decoded['policies'][-2]).to eq(tasks_policy)
135
+ worker_reservations_policy = {
136
+ 'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Workers/WK789/Reservations/**',
137
+ 'method' => 'POST',
138
+ 'query_filter' => {},
139
+ 'post_filter' => {},
140
+ 'allow' => true
141
+ }
142
+ expect(decoded['policies'][-1]).to eq(worker_reservations_policy)
143
+ expect(decoded['policies'].size).to eq(policies_size+2)
127
144
  end
128
145
  end
129
146
  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: 4.9.1
4
+ version: 4.10.0.edge
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Benton
@@ -150,6 +150,11 @@ files:
150
150
  - lib/twilio-ruby/rest/conferences.rb
151
151
  - lib/twilio-ruby/rest/conferences/participants.rb
152
152
  - lib/twilio-ruby/rest/connect_apps.rb
153
+ - lib/twilio-ruby/rest/conversations/completed.rb
154
+ - lib/twilio-ruby/rest/conversations/conversations.rb
155
+ - lib/twilio-ruby/rest/conversations/in_progress.rb
156
+ - lib/twilio-ruby/rest/conversations/participants.rb
157
+ - lib/twilio-ruby/rest/conversations_client.rb
153
158
  - lib/twilio-ruby/rest/errors.rb
154
159
  - lib/twilio-ruby/rest/incoming_phone_numbers.rb
155
160
  - lib/twilio-ruby/rest/incoming_phone_numbers/local.rb
@@ -235,6 +240,7 @@ files:
235
240
  - lib/twilio-ruby/util/configuration.rb
236
241
  - lib/twilio-ruby/util/request_validator.rb
237
242
  - lib/twilio-ruby/version.rb
243
+ - spec/conversations/conversations_spec.rb
238
244
  - spec/rack/twilio_webhook_authentication_spec.rb
239
245
  - spec/rest/account_spec.rb
240
246
  - spec/rest/address_spec.rb
@@ -243,6 +249,7 @@ files:
243
249
  - spec/rest/call_spec.rb
244
250
  - spec/rest/client_spec.rb
245
251
  - spec/rest/conference_spec.rb
252
+ - spec/rest/conversations_client_spec.rb
246
253
  - spec/rest/instance_resource_spec.rb
247
254
  - spec/rest/ip-messaging/channel_spec.rb
248
255
  - spec/rest/ip-messaging/service_spec.rb
@@ -265,6 +272,7 @@ files:
265
272
  - spec/rest/utils_spec.rb
266
273
  - spec/spec_helper.rb
267
274
  - spec/support/fakeweb.rb
275
+ - spec/task_router/workflow_builder_spec.rb
268
276
  - spec/task_router_deprecated_spec.rb
269
277
  - spec/task_router_spec.rb
270
278
  - spec/task_router_taskqueue_spec.rb
@@ -299,9 +307,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
299
307
  version: 1.9.3
300
308
  required_rubygems_version: !ruby/object:Gem::Requirement
301
309
  requirements:
302
- - - '>='
310
+ - - '>'
303
311
  - !ruby/object:Gem::Version
304
- version: '0'
312
+ version: 1.3.1
305
313
  requirements: []
306
314
  rubyforge_project:
307
315
  rubygems_version: 2.4.8
@@ -310,6 +318,7 @@ specification_version: 4
310
318
  summary: A simple library for communicating with the Twilio REST API, building TwiML,
311
319
  and generating Twilio Client Capability Tokens
312
320
  test_files:
321
+ - spec/conversations/conversations_spec.rb
313
322
  - spec/rack/twilio_webhook_authentication_spec.rb
314
323
  - spec/rest/account_spec.rb
315
324
  - spec/rest/address_spec.rb
@@ -318,6 +327,7 @@ test_files:
318
327
  - spec/rest/call_spec.rb
319
328
  - spec/rest/client_spec.rb
320
329
  - spec/rest/conference_spec.rb
330
+ - spec/rest/conversations_client_spec.rb
321
331
  - spec/rest/instance_resource_spec.rb
322
332
  - spec/rest/ip-messaging/channel_spec.rb
323
333
  - spec/rest/ip-messaging/service_spec.rb
@@ -340,6 +350,7 @@ test_files:
340
350
  - spec/rest/utils_spec.rb
341
351
  - spec/spec_helper.rb
342
352
  - spec/support/fakeweb.rb
353
+ - spec/task_router/workflow_builder_spec.rb
343
354
  - spec/task_router_deprecated_spec.rb
344
355
  - spec/task_router_spec.rb
345
356
  - spec/task_router_taskqueue_spec.rb