twilio-ruby 4.9.1 → 4.10.0.edge

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: 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