rdstation-ruby-client 2.9.0 → 2.10.0

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
  SHA256:
3
- metadata.gz: c3de60aebf7582be38403250a4d049f3428241b66a18acb085cdd71f542cb8a0
4
- data.tar.gz: '0829e4b85cae5dd80c64395f6e460ebb315fee92853d81a5feb263adaa2e3efe'
3
+ metadata.gz: c499b97d9b81de525df7b34dc2f06d5e380c0c8b2238b25674b6f9302059018c
4
+ data.tar.gz: a703568e0f3dac1f44ae7f585a56cf1f4f6cf155d45b8993da46bde3f429dbff
5
5
  SHA512:
6
- metadata.gz: 1206caba197401915572f9bb66dd2c45ad2c019d8ce5899d0667753043066cce96edfc39207054549de900cf57e3eb1179c6e4bcf58bed5bac459ef37d49cc12
7
- data.tar.gz: c27a1e2c5d5d3ef4ddc3cfc1f0369f9be0cf09c040147fe1409bcc6d77a3c4d2fc7f697f3d40db2f83fbc2a0c79cad61e9378d4cbc3eedc9df0fe9ec9eaa91ef
6
+ metadata.gz: 84c2fa75ab56babd2b0e37d87d0068d44537f5c8e53a57c267ace3a65f5f0565be0c263475c4dac12aa29c37a737efc1e3d9083a54ed73a3a1246a3145373c0d
7
+ data.tar.gz: 75378898d369bda0ee3c2f848c1f56b5441be073c6ff9aad71b1956824bf6fcef09f5ec43cf2be65d62150a45e1a31a484958a0e1363423afac2fce91faa2a2a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,26 @@
1
+ ## 2.10.0
2
+
3
+ ### Additions
4
+
5
+ #### 1. Getting a Contact by Phone
6
+
7
+ Returns data about a specific Contact
8
+
9
+ ```ruby
10
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
11
+ client.contacts.by_phone('phone')
12
+ ```
13
+
14
+ #### 2. Getting a Contact by Identifier
15
+
16
+ Returns data about a specific Contact
17
+
18
+ ```ruby
19
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
20
+ client.contacts.by_identifier('identifier_type', 'identifier_value')
21
+ ```
22
+
23
+
1
24
  ## 2.9.0
2
25
 
3
26
  ### Additions
data/README.md CHANGED
@@ -124,7 +124,7 @@ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'ref
124
124
  client.contacts.by_uuid('uuid')
125
125
  ```
126
126
 
127
- More info: https://developers.rdstation.com/reference/get_platform-contacts-identifier-value
127
+ More info: https://developers.rdstation.com/reference/get_platform-contacts-identifier-value-1
128
128
 
129
129
  #### Getting a Contact by Email
130
130
 
@@ -135,7 +135,18 @@ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'ref
135
135
  client.contacts.by_email('email')
136
136
  ```
137
137
 
138
- More info: https://developers.rdstation.com/pt-BR/reference/contacts#methodGetDetailsuuid
138
+ More info: https://developers.rdstation.com/reference/get_platform-contacts-identifier-value-1
139
+
140
+ #### Getting a Contact by Phone
141
+
142
+ Returns data about a specific Contact
143
+
144
+ ```ruby
145
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
146
+ client.contacts.by_phone('phone')
147
+ ```
148
+
149
+ More info: https://developers.rdstation.com/reference/get_platform-contacts-identifier-value-1
139
150
 
140
151
  #### Update a Contact by UUID
141
152
 
@@ -10,21 +10,31 @@ module RDStation
10
10
  end
11
11
 
12
12
  #
13
- # param uuid:
14
- # The unique uuid associated to each RD Station Contact.
13
+ # param identifier_type:
14
+ # The type of identifier: :uuid, :email, or :phone
15
+ # param identifier_value:
16
+ # The value of the identifier
15
17
  #
16
- def by_uuid(uuid)
18
+ def by_identifier(identifier_type, identifier_value)
19
+ validate_by_identifier_args!(identifier_type, identifier_value)
20
+
17
21
  retryable_request(@authorization) do |authorization|
18
- response = self.class.get(base_url(uuid), headers: authorization.headers)
22
+ path = build_identifier_path(identifier_type, identifier_value)
23
+ response = self.class.get(base_url(path), headers: authorization.headers)
19
24
  ApiResponse.build(response)
20
25
  end
21
26
  end
22
27
 
28
+ def by_uuid(uuid)
29
+ by_identifier(:uuid, uuid)
30
+ end
31
+
23
32
  def by_email(email)
24
- retryable_request(@authorization) do |authorization|
25
- response = self.class.get(base_url("email:#{email}"), headers: authorization.headers)
26
- ApiResponse.build(response)
27
- end
33
+ by_identifier(:email, email)
34
+ end
35
+
36
+ def by_phone(phone)
37
+ by_identifier(:phone, phone)
28
38
  end
29
39
 
30
40
  # The Contact hash may contain the following parameters:
@@ -63,6 +73,30 @@ module RDStation
63
73
 
64
74
  private
65
75
 
76
+ def validate_by_identifier_args!(identifier_type, identifier_value)
77
+ unless valid_identifier_type?(identifier_type)
78
+ raise ArgumentError, "Invalid identifier type: #{identifier_type}"
79
+ end
80
+
81
+ if identifier_value.nil? || identifier_value.to_s.empty?
82
+ raise ArgumentError, 'identifier_value cannot be nil or empty'
83
+ end
84
+ end
85
+
86
+ def valid_identifier_type?(type)
87
+ %i[uuid email phone].include?(type)
88
+ end
89
+
90
+ def build_identifier_path(identifier_type, identifier_value)
91
+ encoded_value = URI.encode_www_form_component(identifier_value.to_s)
92
+ case identifier_type
93
+ when :uuid
94
+ encoded_value
95
+ when :email, :phone
96
+ "#{identifier_type}:#{encoded_value}"
97
+ end
98
+ end
99
+
66
100
  def base_url(path = '')
67
101
  "#{RDStation.host}/platform/contacts/#{path}"
68
102
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RDStation
4
- VERSION = '2.9.0'
4
+ VERSION = '2.10.0'
5
5
  end
@@ -5,11 +5,20 @@ RSpec.describe RDStation::Contacts do
5
5
  let(:invalid_uuid) { 'invalid_uuid' }
6
6
  let(:valid_email) { 'valid@email.com' }
7
7
  let(:invalid_email) { 'invalid@email.com' }
8
+ let(:special_chars_email) { 'valid+user@example.com' }
9
+ let(:valid_phone) { '11999999999' }
10
+ let(:invalid_phone) { '11888888888' }
8
11
 
9
12
  let(:endpoint_with_valid_uuid) { "https://api.rd.services/platform/contacts/#{valid_uuid}" }
10
13
  let(:endpoint_with_invalid_uuid) { "https://api.rd.services/platform/contacts/#{invalid_uuid}" }
11
14
  let(:endpoint_with_valid_email) { "https://api.rd.services/platform/contacts/email:#{valid_email}" }
12
15
  let(:endpoint_with_invalid_email) { "https://api.rd.services/platform/contacts/email:#{invalid_email}" }
16
+ let(:endpoint_with_special_chars_email) do
17
+ encoded_email = URI.encode_www_form_component(special_chars_email)
18
+ "https://api.rd.services/platform/contacts/email:#{encoded_email}"
19
+ end
20
+ let(:endpoint_with_valid_phone) { "https://api.rd.services/platform/contacts/phone:#{valid_phone}" }
21
+ let(:endpoint_with_invalid_phone) { "https://api.rd.services/platform/contacts/phone:#{invalid_phone}" }
13
22
 
14
23
  let(:valid_access_token) { 'valid_access_token' }
15
24
  let(:invalid_access_token) { 'invalid_access_token' }
@@ -25,7 +34,6 @@ RSpec.describe RDStation::Contacts do
25
34
  described_class.new(authorization: RDStation::Authorization.new(access_token: invalid_access_token))
26
35
  end
27
36
 
28
-
29
37
  let(:valid_headers) do
30
38
  {
31
39
  'Authorization' => "Bearer #{valid_access_token}",
@@ -108,142 +116,290 @@ RSpec.describe RDStation::Contacts do
108
116
  }
109
117
  end
110
118
 
111
- describe '#by_uuid' do
112
- it 'calls retryable_request' do
113
- expect(contact_with_valid_token).to receive(:retryable_request)
114
- contact_with_valid_token.by_uuid('valid_uuid')
115
- end
119
+ describe '#by_identifier' do
120
+ describe 'with identifier_type :uuid' do
121
+ it 'calls retryable_request' do
122
+ expect(contact_with_valid_token).to receive(:retryable_request)
123
+ contact_with_valid_token.by_identifier(:uuid, valid_uuid)
124
+ end
116
125
 
117
- context 'with a valid auth token' do
118
- context 'when the contact exists' do
119
- let(:contact) do
120
- { 'name' => 'Lead', 'email' => 'valid@email.com' }
126
+ context 'with a valid auth token' do
127
+ context 'when the contact exists' do
128
+ let(:contact) do
129
+ { 'name' => 'Lead', 'email' => 'valid@email.com' }
130
+ end
131
+
132
+ before do
133
+ stub_request(:get, endpoint_with_valid_uuid)
134
+ .with(headers: valid_headers)
135
+ .to_return(status: 200, body: contact.to_json)
136
+ end
137
+
138
+ it 'returns the contact' do
139
+ response = contact_with_valid_token.by_identifier(:uuid, valid_uuid)
140
+ expect(response).to eq(contact)
141
+ end
121
142
  end
122
143
 
144
+ context 'when the contact does not exist' do
145
+ before do
146
+ stub_request(:get, endpoint_with_invalid_uuid)
147
+ .with(headers: valid_headers)
148
+ .to_return(not_found_response)
149
+ end
150
+
151
+ it 'raises a not found error' do
152
+ expect do
153
+ contact_with_valid_token.by_identifier(:uuid, invalid_uuid)
154
+ end.to raise_error(RDStation::Error::NotFound)
155
+ end
156
+ end
157
+ end
158
+
159
+ context 'with an invalid auth token' do
123
160
  before do
124
161
  stub_request(:get, endpoint_with_valid_uuid)
125
- .with(headers: valid_headers)
126
- .to_return(status: 200, body: contact.to_json)
162
+ .with(headers: invalid_token_headers)
163
+ .to_return(invalid_token_response)
127
164
  end
128
165
 
129
- it 'returns the contact' do
130
- response = contact_with_valid_token.by_uuid('valid_uuid')
131
- expect(response).to eq(contact)
166
+ it 'raises an invalid token error' do
167
+ expect do
168
+ contact_with_invalid_token.by_identifier(:uuid, valid_uuid)
169
+ end.to raise_error(RDStation::Error::Unauthorized)
132
170
  end
133
171
  end
134
172
 
135
- context 'when the contact does not exist' do
173
+ context 'with an expired auth token' do
136
174
  before do
137
- stub_request(:get, endpoint_with_invalid_uuid)
138
- .with(headers: valid_headers)
139
- .to_return(not_found_response)
175
+ stub_request(:get, endpoint_with_valid_uuid)
176
+ .with(headers: expired_token_headers)
177
+ .to_return(expired_token_response)
140
178
  end
141
179
 
142
- it 'raises a not found error' do
180
+ it 'raises a expired token error' do
143
181
  expect do
144
- contact_with_valid_token.by_uuid(invalid_uuid)
145
- end.to raise_error(RDStation::Error::NotFound)
182
+ contact_with_expired_token.by_identifier(:uuid, valid_uuid)
183
+ end.to raise_error(RDStation::Error::ExpiredAccessToken)
146
184
  end
147
185
  end
148
- end
149
186
 
150
- context 'with an invalid auth token' do
151
- before do
152
- stub_request(:get, endpoint_with_valid_uuid)
153
- .with(headers: invalid_token_headers)
154
- .to_return(invalid_token_response)
155
- end
187
+ describe 'with non-string identifier_value' do
188
+ let(:numeric_uuid) { 123 }
189
+ let(:endpoint_with_numeric_uuid) do
190
+ "https://api.rd.services/platform/contacts/#{numeric_uuid}"
191
+ end
156
192
 
157
- it 'raises an invalid token error' do
158
- expect do
159
- contact_with_invalid_token.by_uuid(valid_uuid)
160
- end.to raise_error(RDStation::Error::Unauthorized)
193
+ before do
194
+ stub_request(:get, endpoint_with_numeric_uuid)
195
+ .with(headers: valid_headers)
196
+ .to_return(status: 200, body: {}.to_json)
197
+ end
198
+
199
+ it 'converts identifier_value to string before building the path' do
200
+ response = contact_with_valid_token.by_identifier(:uuid, numeric_uuid)
201
+ expect(response).to eq({})
202
+ end
161
203
  end
162
204
  end
163
205
 
164
- context 'with an expired auth token' do
165
- before do
166
- stub_request(:get, endpoint_with_valid_uuid)
167
- .with(headers: expired_token_headers)
168
- .to_return(expired_token_response)
206
+ describe 'with identifier_type :email' do
207
+ it 'calls retryable_request' do
208
+ expect(contact_with_valid_token).to receive(:retryable_request)
209
+ contact_with_valid_token.by_identifier(:email, valid_email)
169
210
  end
170
211
 
171
- it 'raises a expired token error' do
172
- expect do
173
- contact_with_expired_token.by_uuid(valid_uuid)
174
- end.to raise_error(RDStation::Error::ExpiredAccessToken)
212
+ context 'with a valid auth token' do
213
+ context 'when the contact exists' do
214
+ let(:contact) do
215
+ { 'name' => 'Lead', 'email' => 'valid@email.com' }
216
+ end
217
+
218
+ before do
219
+ stub_request(:get, endpoint_with_valid_email)
220
+ .with(headers: valid_headers)
221
+ .to_return(status: 200, body: contact.to_json)
222
+ end
223
+
224
+ it 'returns the contact' do
225
+ response = contact_with_valid_token.by_identifier(:email, valid_email)
226
+ expect(response).to eq(contact)
227
+ end
228
+ end
229
+
230
+ context 'when the contact does not exist' do
231
+ before do
232
+ stub_request(:get, endpoint_with_invalid_email)
233
+ .with(headers: valid_headers)
234
+ .to_return(not_found_response)
235
+ end
236
+
237
+ it 'raises a not found error' do
238
+ expect do
239
+ contact_with_valid_token.by_identifier(:email, invalid_email)
240
+ end.to raise_error(RDStation::Error::NotFound)
241
+ end
242
+ end
175
243
  end
176
- end
177
- end
178
244
 
179
- describe '#by_email' do
180
- it 'calls retryable_request' do
181
- expect(contact_with_valid_token).to receive(:retryable_request)
182
- contact_with_valid_token.by_email('x@xpto.com')
183
- end
245
+ context 'with an invalid auth token' do
246
+ before do
247
+ stub_request(:get, endpoint_with_valid_email)
248
+ .with(headers: invalid_token_headers)
249
+ .to_return(invalid_token_response)
250
+ end
184
251
 
185
- context 'with a valid auth token' do
186
- context 'when the contact exists' do
187
- let(:contact) do
188
- { 'name' => 'Lead', 'email' => 'valid@email.com' }
252
+ it 'raises an invalid token error' do
253
+ expect do
254
+ contact_with_invalid_token.by_identifier(:email, valid_email)
255
+ end.to raise_error(RDStation::Error::Unauthorized)
189
256
  end
257
+ end
190
258
 
259
+ context 'with an expired auth token' do
191
260
  before do
192
261
  stub_request(:get, endpoint_with_valid_email)
262
+ .with(headers: expired_token_headers)
263
+ .to_return(expired_token_response)
264
+ end
265
+
266
+ it 'raises a expired token error' do
267
+ expect do
268
+ contact_with_expired_token.by_identifier(:email, valid_email)
269
+ end.to raise_error(RDStation::Error::ExpiredAccessToken)
270
+ end
271
+ end
272
+
273
+ context 'when the email contains characters that must be URL encoded' do
274
+ let(:contact) do
275
+ { 'name' => 'Lead', 'email' => special_chars_email }
276
+ end
277
+
278
+ before do
279
+ stub_request(:get, endpoint_with_special_chars_email)
193
280
  .with(headers: valid_headers)
194
281
  .to_return(status: 200, body: contact.to_json)
195
282
  end
196
283
 
197
- it 'returns the contact' do
198
- response = contact_with_valid_token.by_email(valid_email)
284
+ it 'encodes identifier_value in the request path' do
285
+ response = contact_with_valid_token.by_identifier(:email, special_chars_email)
199
286
  expect(response).to eq(contact)
200
287
  end
201
288
  end
289
+ end
290
+
291
+ describe 'with identifier_type :phone' do
292
+ it 'calls retryable_request' do
293
+ expect(contact_with_valid_token).to receive(:retryable_request)
294
+ contact_with_valid_token.by_identifier(:phone, valid_phone)
295
+ end
296
+
297
+ context 'with a valid auth token' do
298
+ context 'when the contact exists' do
299
+ let(:contact) do
300
+ { 'name' => 'Lead', 'phone' => valid_phone }
301
+ end
302
+
303
+ before do
304
+ stub_request(:get, endpoint_with_valid_phone)
305
+ .with(headers: valid_headers)
306
+ .to_return(status: 200, body: contact.to_json)
307
+ end
308
+
309
+ it 'returns the contact' do
310
+ response = contact_with_valid_token.by_identifier(:phone, valid_phone)
311
+ expect(response).to eq(contact)
312
+ end
313
+ end
314
+
315
+ context 'when the contact does not exist' do
316
+ before do
317
+ stub_request(:get, endpoint_with_invalid_phone)
318
+ .with(headers: valid_headers)
319
+ .to_return(not_found_response)
320
+ end
321
+
322
+ it 'raises a not found error' do
323
+ expect do
324
+ contact_with_valid_token.by_identifier(:phone, invalid_phone)
325
+ end.to raise_error(RDStation::Error::NotFound)
326
+ end
327
+ end
328
+ end
202
329
 
203
- context 'when the contact does not exist' do
330
+ context 'with an invalid auth token' do
204
331
  before do
205
- stub_request(:get, endpoint_with_invalid_email)
206
- .with(headers: valid_headers)
207
- .to_return(not_found_response)
332
+ stub_request(:get, endpoint_with_valid_phone)
333
+ .with(headers: invalid_token_headers)
334
+ .to_return(invalid_token_response)
208
335
  end
209
336
 
210
- it 'raises a not found error' do
337
+ it 'raises an invalid token error' do
211
338
  expect do
212
- contact_with_valid_token.by_email(invalid_email)
213
- end.to raise_error(RDStation::Error::NotFound)
339
+ contact_with_invalid_token.by_identifier(:phone, valid_phone)
340
+ end.to raise_error(RDStation::Error::Unauthorized)
214
341
  end
215
342
  end
216
- end
217
343
 
218
- context 'with an invalid auth token' do
219
- before do
220
- stub_request(:get, endpoint_with_valid_email)
221
- .with(headers: invalid_token_headers)
222
- .to_return(invalid_token_response)
344
+ context 'with an expired auth token' do
345
+ before do
346
+ stub_request(:get, endpoint_with_valid_phone)
347
+ .with(headers: expired_token_headers)
348
+ .to_return(expired_token_response)
349
+ end
350
+
351
+ it 'raises a expired token error' do
352
+ expect do
353
+ contact_with_expired_token.by_identifier(:phone, valid_phone)
354
+ end.to raise_error(RDStation::Error::ExpiredAccessToken)
355
+ end
223
356
  end
357
+ end
224
358
 
225
- it 'raises an invalid token error' do
359
+ describe 'with invalid identifier_type' do
360
+ it 'raises an ArgumentError' do
226
361
  expect do
227
- contact_with_invalid_token.by_email(valid_email)
228
- end.to raise_error(RDStation::Error::Unauthorized)
362
+ contact_with_valid_token.by_identifier(:invalid, 'some_value')
363
+ end.to raise_error(ArgumentError, /Invalid identifier type/)
229
364
  end
230
365
  end
231
366
 
232
- context 'with an expired auth token' do
233
- before do
234
- stub_request(:get, endpoint_with_valid_email)
235
- .with(headers: expired_token_headers)
236
- .to_return(expired_token_response)
367
+ describe 'with invalid identifier_value' do
368
+ it 'raises ArgumentError when identifier_value is nil' do
369
+ expect do
370
+ contact_with_valid_token.by_identifier(:email, nil)
371
+ end.to raise_error(ArgumentError, /identifier_value cannot be nil or empty/)
237
372
  end
238
373
 
239
- it 'raises a expired token error' do
374
+ it 'raises ArgumentError when identifier_value is an empty string' do
240
375
  expect do
241
- contact_with_expired_token.by_email(valid_email)
242
- end.to raise_error(RDStation::Error::ExpiredAccessToken)
376
+ contact_with_valid_token.by_identifier(:email, '')
377
+ end.to raise_error(ArgumentError, /identifier_value cannot be nil or empty/)
243
378
  end
244
379
  end
245
380
  end
246
381
 
382
+ describe '#by_uuid' do
383
+ it 'delegates to by_identifier with :uuid' do
384
+ expect(contact_with_valid_token).to receive(:by_identifier).with(:uuid, valid_uuid)
385
+ contact_with_valid_token.by_uuid(valid_uuid)
386
+ end
387
+ end
388
+
389
+ describe '#by_email' do
390
+ it 'delegates to by_identifier with :email' do
391
+ expect(contact_with_valid_token).to receive(:by_identifier).with(:email, valid_email)
392
+ contact_with_valid_token.by_email(valid_email)
393
+ end
394
+ end
395
+
396
+ describe '#by_phone' do
397
+ it 'delegates to by_identifier with :phone' do
398
+ expect(contact_with_valid_token).to receive(:by_identifier).with(:phone, valid_phone)
399
+ contact_with_valid_token.by_phone(valid_phone)
400
+ end
401
+ end
402
+
247
403
  describe '#update' do
248
404
  it 'calls retryable_request' do
249
405
  expect(contact_with_valid_token).to receive(:retryable_request)
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,3 @@
1
1
  require 'rdstation-ruby-client'
2
2
  require 'webmock/rspec'
3
+ require 'uri'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdstation-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.0
4
+ version: 2.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paulo L F Casaretto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-14 00:00:00.000000000 Z
11
+ date: 2025-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -218,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
218
218
  - !ruby/object:Gem::Version
219
219
  version: '0'
220
220
  requirements: []
221
- rubygems_version: 3.2.32
221
+ rubygems_version: 3.4.20
222
222
  signing_key:
223
223
  specification_version: 4
224
224
  summary: Ruby API wrapper for RD Station