rdstation-ruby-client 2.1.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +121 -1
  3. data/README.md +106 -22
  4. data/Rakefile +4 -0
  5. data/lib/rdstation-ruby-client.rb +6 -1
  6. data/lib/rdstation.rb +19 -0
  7. data/lib/rdstation/api_response.rb +1 -2
  8. data/lib/rdstation/authentication.rb +8 -3
  9. data/lib/rdstation/{authorization_header.rb → authorization.rb} +11 -8
  10. data/lib/rdstation/builder/field.rb +70 -0
  11. data/lib/rdstation/client.rb +17 -7
  12. data/lib/rdstation/contacts.rb +22 -13
  13. data/lib/rdstation/error.rb +3 -0
  14. data/lib/rdstation/error/format.rb +29 -3
  15. data/lib/rdstation/error/formatter.rb +69 -8
  16. data/lib/rdstation/error_handler.rb +6 -1
  17. data/lib/rdstation/error_handler/invalid_refresh_token.rb +24 -0
  18. data/lib/rdstation/error_handler/unauthorized.rb +2 -0
  19. data/lib/rdstation/events.rb +7 -12
  20. data/lib/rdstation/fields.rb +35 -6
  21. data/lib/rdstation/retryable_request.rb +35 -0
  22. data/lib/rdstation/version.rb +1 -1
  23. data/lib/rdstation/webhooks.rb +25 -13
  24. data/rdstation-ruby-client.gemspec +2 -1
  25. data/spec/lib/rdstation/api_response_spec.rb +34 -0
  26. data/spec/lib/rdstation/authentication_spec.rb +105 -2
  27. data/spec/lib/rdstation/{authorization_header_spec.rb → authorization_spec.rb} +3 -3
  28. data/spec/lib/rdstation/builder/field_spec.rb +69 -0
  29. data/spec/lib/rdstation/client_spec.rb +6 -6
  30. data/spec/lib/rdstation/contacts_spec.rb +23 -3
  31. data/spec/lib/rdstation/error/format_spec.rb +63 -0
  32. data/spec/lib/rdstation/error/formatter_spec.rb +113 -0
  33. data/spec/lib/rdstation/error_handler/invalid_refresh_token_spec.rb +53 -0
  34. data/spec/lib/rdstation/error_handler_spec.rb +23 -0
  35. data/spec/lib/rdstation/events_spec.rb +8 -3
  36. data/spec/lib/rdstation/fields_spec.rb +6 -1
  37. data/spec/lib/rdstation/retryable_request_spec.rb +142 -0
  38. data/spec/lib/rdstation/webhooks_spec.rb +26 -1
  39. data/spec/lib/rdstation_spec.rb +18 -0
  40. metadata +36 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: adcf1abef180f5dd333152cc6956191fd637f09e
4
- data.tar.gz: 22ad74012fcef08e888ef1d72fb73989f84ee651
2
+ SHA256:
3
+ metadata.gz: 5df3763feda5bcb841946b403695b54933c0fcc9b0b9da1c907146454e5311ff
4
+ data.tar.gz: 63cd80564336415bc361c3dfce276611d1b1a6b61c68554e4f1a212c73fd9c7e
5
5
  SHA512:
6
- metadata.gz: ad4409d04b424d90f74bab2a3d5264b7a0fe1b74b233840befff8e21a8597c40cb1cd99767292322b65a3ee309d809ad9a00ec8a851855476471fc89bb1a240c
7
- data.tar.gz: 54f42eac6c63524bdacfb2c00548f3e9fdc5b0b63554c9c3ceca15f0afc24c800339506582127ebcc21b59e2b39f15ba5b3e20fe3eca9a658d0a258c9b380b5c
6
+ metadata.gz: 60eded16372c0d970d67b5f456a28d8adb9e7f013f8551e56b72598752ea9a0c24f99fdf4f3c943f040872d71a837279d769b43ac7b2e36d2c0c5eaa8ae9f405
7
+ data.tar.gz: 1107d1405d1984cd36de905403f3a53a6275505e55ff4c4d5661f7914d268f11031d81c5602464ca2f573b61831d5516a437abe9501a1fd8a34549ec3a36753f
@@ -1,3 +1,121 @@
1
+ ## 2.5.0
2
+
3
+ - InvalidRefreshToken error added. This error will be raised when the refresh token is invalid or it was revoked. When you get this error, you can safely disconnect the user from RD Station.
4
+
5
+ Usage example:
6
+
7
+ ```ruby
8
+ begin
9
+ rdstation.update_access_token(refresh_token)
10
+ rescue RDStation::Error::InvalidRefreshToken
11
+ # Disconnect user
12
+ end
13
+ ```
14
+
15
+ ## 2.4.0
16
+
17
+ - Add the TooManyRequests errors in case of rate limit exceeded. See [API request limit](https://developers.rdstation.com/en/request-limit) for more details
18
+
19
+ ## 2.3.1
20
+
21
+ - Fixed a bug when no error is found in the known errors list (issue [#52](https://github.com/ResultadosDigitais/rdstation-ruby-client/issues/52))
22
+
23
+ ## 2.3.0
24
+
25
+ ### Additions
26
+
27
+ #### 1. New Field methods
28
+
29
+ The following methods were added to "Fields" client:
30
+
31
+ - create
32
+ - update
33
+ - delete
34
+
35
+ Besides reading, this client is now capable of create, update or delete a field.
36
+
37
+ Usage example:
38
+
39
+ ```ruby
40
+ client = RDStation::Client.new(access_token: 'ACCESS_TOKEN', refresh_token: 'REFRESH_TOKEN')
41
+ client.fields.delete('FIELD_UUID')
42
+ ```
43
+
44
+ #### 2. New format of errors supported
45
+
46
+ Two new formats of errors are now supported by the error handler:
47
+
48
+ ##### `HASH_OF_HASHES`
49
+
50
+ When the error message is a hash containing other hashes as values, for example:
51
+
52
+ ```ruby
53
+ {
54
+ 'error' => {
55
+ 'field1' => {...},
56
+ 'field2' => {...}
57
+ }
58
+ }
59
+ ```
60
+
61
+ ##### `HASH_OF_MULTIPLE_TYPES`
62
+
63
+ When the error message is a hash that could contain multiple data types as values, for example:
64
+
65
+ ```ruby
66
+ {
67
+ 'error' => {
68
+ 'field1' => [...] # Array,
69
+ 'field2' => {...} # Hash
70
+ }
71
+ }
72
+ ```
73
+
74
+ ## 2.2.0
75
+
76
+ ### Additions
77
+
78
+ #### Configuration
79
+
80
+ Now it is possible to configure global params like client_id and client_secret only once, so you don't need to provide them to `RDStation::Authentication` every time.
81
+
82
+ This can be done in the following way:
83
+
84
+ ```ruby
85
+ RDStation.configure do |config|
86
+ config.client_id = YOUR_CLIENT_ID
87
+ config.client_secret = YOUR_CLIENT_SECRET
88
+ end
89
+ ```
90
+
91
+ If you're using Rails, this can be done in `config/initializers`.
92
+
93
+ #### Automatic refresh of access_tokens
94
+
95
+ When an access_token expires, a new one will be obtained automatically and the request will be made again.
96
+
97
+ For this to work, you have to use `RDStation.configure` as described above, and provide the refresh token when instantiating `RDStation::Client` (ex: RDStation::Client.new(access_token: MY_ACCESS_TOKEN, refresh_token: MY_REFRESH_TOKEN).
98
+
99
+ You can keep track of access_token changes, by providing a callback block inconfiguration. This block will be called with an `RDStation::Authorization` object, which contains the updated `access_token` and `refresh_token`. For example:
100
+
101
+ ```ruby
102
+ RDStation.configure do |config|
103
+ config.on_access_token_refresh do |authorization|
104
+ MyStoredAuth.where(refresh_token: authorization.refresh_token).update_all(access_token: authorization.access_token)
105
+ end
106
+ end
107
+ ```
108
+
109
+ ### Deprecations
110
+
111
+ Providing `client_id` and `client_secret` directly to `RDStation::Authentication.new` is deprecated and will be removed in future versions. Use `RDStation.configure` instead.
112
+
113
+ Specifying refresh_token in `RDStation::Client.new(access_token: 'at', refresh_token: 'rt')` is optional right now, but will be mandatory in future versions.
114
+
115
+ ## 2.1.1
116
+
117
+ - Fixed a bug in error handling (issue [#47](https://github.com/ResultadosDigitais/rdstation-ruby-client/issues/47))
118
+
1
119
  ## 2.1.0
2
120
 
3
121
  ### Additions
@@ -49,11 +167,13 @@ In case of a Bad Request (400), the following specific errors may be raised (tho
49
167
  - `RDStation::Error::ConflictingField`
50
168
  - `RDStation::Error::InvalidEventType`
51
169
 
52
- In cause of Unahtorized (401), the following specific errors may be raised (those are subclasses of `RDStation::Error::Unauthorized`):
170
+ In cause of Unauthorized (401), the following specific errors may be raised (those are subclasses of `RDStation::Error::Unauthorized`):
53
171
  - `RDStation::Error::ExpiredAccessToken`
54
172
  - `RDStation::Error::ExpiredCodeGrant`
55
173
  - `RDStation::Error::InvalidCredentials`
56
174
 
175
+ The specific message and the http code are now returned by the `details` method.
176
+
57
177
  ### Dependencies
58
178
 
59
179
  `rdstation-ruby-client` now requires `ruby >= 2.0.0`.
data/README.md CHANGED
@@ -10,12 +10,13 @@ Upgrading? Check the [migration guide](#Migration-guide) before bumping to a new
10
10
 
11
11
  1. [Installation](#Installation)
12
12
  2. [Usage](#Usage)
13
- 1. [Authentication](#Authentication)
14
- 2. [Contacts](#Contacts)
15
- 3. [Events](#Events)
16
- 4. [Fields](#Fields)
17
- 5. [Webhooks](#Webhooks)
18
- 6. [Errors](#Errors)
13
+ 1. [Configuration](#Configuration)
14
+ 2. [Authentication](#Authentication)
15
+ 3. [Contacts](#Contacts)
16
+ 4. [Events](#Events)
17
+ 5. [Fields](#Fields)
18
+ 6. [Webhooks](#Webhooks)
19
+ 7. [Errors](#Errors)
19
20
  3. [Changelog](#Changelog)
20
21
  4. [Migration guide](#Migration-guide)
21
22
  1. [Upgrading from 1.2.x to 2.0.0](#Upgrading-from-1.2.x-to-2.0.0)
@@ -39,6 +40,19 @@ Or install it yourself as:
39
40
 
40
41
  ## Usage
41
42
 
43
+ ### Configuration
44
+
45
+ Before getting youre credentials, you need to configure client_id and client_secret as following:
46
+
47
+ ```ruby
48
+ RDStation.configure do |config|
49
+ config.client_id = YOUR_CLIENT_ID
50
+ config.client_secret = YOUR_CLIENT_SECRET
51
+ end
52
+ ```
53
+
54
+ For details on what `client_id` and `client_secret` are, check the [developers portal](https://developers.rdstation.com/en/authentication).
55
+
42
56
  ### Authentication
43
57
 
44
58
  For more details, check the [developers portal](https://developers.rdstation.com/en/authentication).
@@ -46,7 +60,7 @@ For more details, check the [developers portal](https://developers.rdstation.com
46
60
  #### Getting authentication URL
47
61
 
48
62
  ```ruby
49
- rdstation_authentication = RDStation::Authentication.new('client_id', 'client_secret')
63
+ rdstation_authentication = RDStation::Authentication.new
50
64
 
51
65
  redirect_url = 'https://yourapp.org/auth/callback'
52
66
  rdstation_authentication.auth_url(redirect_url)
@@ -57,17 +71,35 @@ rdstation_authentication.auth_url(redirect_url)
57
71
  You will need the code param that is returned from RD Station to your application after the user confirms the access at the authorization dialog.
58
72
 
59
73
  ```ruby
60
- rdstation_authentication = RDStation::Authentication.new('client_id', 'client_secret')
74
+ rdstation_authentication = RDStation::Authentication.new
61
75
  rdstation_authentication.authenticate(code_returned_from_rdstation)
76
+ # => { 'access_token' => '54321', 'expires_in' => 86_400, 'refresh_token' => 'refresh' }
62
77
  ```
63
78
 
64
- #### Updating access_token
79
+ #### Updating an expired access_token
65
80
 
66
81
  ```ruby
67
- rdstation_authentication = RDStation::Authentication.new('client_id', 'client_secret')
82
+ rdstation_authentication = RDStation::Authentication.new
68
83
  rdstation_authentication.update_access_token('refresh_token')
69
84
  ```
70
85
 
86
+ **NOTE**: This is done automatically when a request fails due to access_token expiration. To keep track of the new token, you have to provide a callback block in configuration. For example:
87
+
88
+ ```ruby
89
+ RDStation.configure do |config|
90
+ config.client_id = YOUR_CLIENT_ID
91
+ config.client_secret = YOUR_CLIENT_SECRET
92
+ config.on_access_token_refresh do |authorization|
93
+ # authorization.access_token_expires_in is the time (in seconds for with the token is valid)
94
+ # authorization.access_token is the new token
95
+ # authorization.refresh_token is the existing refresh_token
96
+ #
97
+ # If you are using ActiveRecord, you may want to update the stored access_token, like in the following code:
98
+ MyStoredAuth.where(refresh_token: authorization.refresh_token).update_all(access_token: authorization.access_token)
99
+ end
100
+ end
101
+ ```
102
+
71
103
  #### Revoking an access_token
72
104
 
73
105
  ```ruby
@@ -83,7 +115,7 @@ Note: this will completely remove your credentials from RD Station (`update_acce
83
115
  Returns data about a specific Contact
84
116
 
85
117
  ```ruby
86
- client = RDStation::Client.new(access_token: 'access_token')
118
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
87
119
  client.contacts.by_uuid('uuid')
88
120
  ```
89
121
 
@@ -94,7 +126,7 @@ More info: https://developers.rdstation.com/pt-BR/reference/contacts#methodGetDe
94
126
  Returns data about a specific Contact
95
127
 
96
128
  ```ruby
97
- client = RDStation::Client.new(access_token: 'access_token')
129
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
98
130
  client.contacts.by_email('email')
99
131
  ```
100
132
 
@@ -109,7 +141,7 @@ contact_info = {
109
141
  name: "Joe Foo"
110
142
  }
111
143
 
112
- client = RDStation::Client.new(access_token: 'access_token')
144
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
113
145
  client.contacts.update('uuid', contact_info)
114
146
  ```
115
147
  Contact Default Parameters
@@ -139,7 +171,7 @@ contact_info = {
139
171
  identifier = "email"
140
172
  identifier_value = "joe@foo.bar"
141
173
 
142
- client = RDStation::Client.new(access_token: 'access_token')
174
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
143
175
  client.contacts.upsert(identifier, identifier_value, contact_info)
144
176
  ```
145
177
 
@@ -159,7 +191,7 @@ This creates a new event on RDSM:
159
191
 
160
192
  ```ruby
161
193
  payload = {} # hash representing the payload
162
- client = RDStation::Client.new(access_token: 'access_token')
194
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
163
195
  client.events.create(payload)
164
196
  ```
165
197
 
@@ -170,10 +202,59 @@ Endpoints to [manage Contact Fields](https://developers.rdstation.com/en/referen
170
202
  #### List all fields
171
203
 
172
204
  ```ruby
173
- client = RDStation::Client.new(access_token: 'access_token')
205
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
174
206
  client.fields.all
175
207
  ```
176
208
 
209
+ #### Create a field
210
+
211
+ ```ruby
212
+ payload = {} # hash representing the payload
213
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
214
+ client.fields.create payload
215
+ ```
216
+ Or you can use the new `RDStation::Builder::Field`
217
+
218
+ ```ruby
219
+ payload = {} # hash representing the payload
220
+ builder = RDStation::Builder::Field.new payload['api_identifier']
221
+ builder.data_type(payload['data_type'])
222
+ builder.presentation_type(payload['presentation_type'])
223
+ builder.name('pt-BR', payload['name'])
224
+ builder.label('pt-BR', payload['label'])
225
+
226
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
227
+ client.fields.create builder.build
228
+ ```
229
+
230
+ #### Update a field
231
+
232
+ ```ruby
233
+ payload = {} # hash representing the payload
234
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
235
+ client.fields.update('FIELD_UUID', payload)
236
+ ```
237
+ Or you can use the new `RDStation::Builder::Field`
238
+
239
+ ```ruby
240
+ payload = {} # hash representing the payload
241
+ builder = RDStation::Builder::Field.new payload['api_identifier']
242
+ builder.data_type(payload['data_type'])
243
+ builder.presentation_type(payload['presentation_type'])
244
+ builder.name('pt-BR', payload['name'])
245
+ builder.label('pt-BR', payload['label'])
246
+
247
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
248
+ client.fields.update('FIELD_UUID', builder.build)
249
+ ```
250
+ #### Deleting a field
251
+
252
+ ```ruby
253
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
254
+ client.fields.delete('FIELD_UUID')
255
+ ```
256
+
257
+
177
258
  ### Webhooks
178
259
 
179
260
  Webhooks provide the ability to receive real-time data updates about your contact activity.
@@ -183,14 +264,14 @@ Choose to receive data based on certain actions, re-cast or marked as an opportu
183
264
  #### List all webhooks
184
265
 
185
266
  ```ruby
186
- client = RDStation::Client.new(access_token: 'access_token')
267
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
187
268
  client.webhooks.all
188
269
  ```
189
270
 
190
271
  #### Getting a webhook by UUID
191
272
 
192
273
  ```ruby
193
- client = RDStation::Client.new(access_token: 'access_token')
274
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
194
275
  client.webhooks.by_uuid('WEBHOOK_UUID')
195
276
  ```
196
277
 
@@ -198,7 +279,7 @@ client.webhooks.by_uuid('WEBHOOK_UUID')
198
279
 
199
280
  ```ruby
200
281
  payload = {} # payload representing a webhook
201
- client = RDStation::Client.new(access_token: 'access_token')
282
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
202
283
  client.webhooks.create(payload)
203
284
  ```
204
285
 
@@ -208,7 +289,7 @@ The required strucutre of the payload is [described here](https://developers.rds
208
289
 
209
290
  ```ruby
210
291
  payload = {} # payload representing a webhook
211
- client = RDStation::Client.new(access_token: 'access_token')
292
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
212
293
  client.webhooks.create('WEBHOOK_UUID', payload)
213
294
  ```
214
295
 
@@ -217,7 +298,7 @@ The required strucutre of the payload is [described here](https://developers.rds
217
298
  #### Deleting a webhook
218
299
 
219
300
  ```ruby
220
- client = RDStation::Client.new(access_token: 'access_token')
301
+ client = RDStation::Client.new(access_token: 'access_token', refresh_token: 'refresh_token')
221
302
  client.webhooks.delete('WEBHOOK_UUID')
222
303
  ```
223
304
 
@@ -234,6 +315,7 @@ Each endpoint may raise errors accoording to the HTTP response code from RDStati
234
315
  - `RDStation::Error::Conflict` (409)
235
316
  - `RDStation::Error::UnsupportedMediaType` (415)
236
317
  - `RDStation::Error::UnprocessableEntity` (422)
318
+ - `RDStation::Error::TooManyRequests` (429)
237
319
  - `RDStation::Error::InternalServerError` (500)
238
320
  - `RDStation::Error::NotImplemented` (501)
239
321
  - `RDStation::Error::BadGateway` (502)
@@ -249,6 +331,8 @@ In cause of Unauthorized (401), the following specific errors may be raised (tho
249
331
  - `RDStation::Error::ExpiredCodeGrant`
250
332
  - `RDStation::Error::InvalidCredentials`
251
333
 
334
+ Any error class has a `details` method which returns the specific error message and the http_status.
335
+
252
336
  ## Changelog
253
337
 
254
338
  See [CHANGELOG.md](CHANGELOG.md)
@@ -263,7 +347,7 @@ So, here is a step-by-step guide on how to upgrade your app:
263
347
  - Ensure you're using `ruby >= 2.0.0`.
264
348
  - Remove every direct instantiation of `RDStation::Contacts`, `RDStation::Events`, `RDStation::Fields` and `RDStation::Webhooks` and use `RDStation::Client` to get them instead.
265
349
  - Replace any call of `RDStation::Client#create_lead`, `RDStation::Client#change_lead` or `RDStation::Client#change_lead_status` with the equivalent method in the [Contacts API](#Contacts).
266
- - Review your error handling, as [more options](CHANGELOG.md#Error-handling) are available now.
350
+ - Review your error handling, as [more options](CHANGELOG.md#Error-handling) are available now. `http_status` method will always return nil. To get the status now use `error.details[:http_status]` or check the type of the class.
267
351
 
268
352
  ## Contributing
269
353
 
data/Rakefile CHANGED
@@ -5,3 +5,7 @@ RSpec::Core::RakeTask.new
5
5
 
6
6
  task :default => :spec
7
7
  task :test => :spec
8
+
9
+ task :console do
10
+ exec 'pry -r rdstation-ruby-client -I ./lib'
11
+ end
@@ -4,8 +4,10 @@ require 'httparty'
4
4
  require 'rdstation/api_response'
5
5
 
6
6
  # API requests
7
+ require 'rdstation'
8
+ require 'rdstation/retryable_request'
7
9
  require 'rdstation/authentication'
8
- require 'rdstation/authorization_header'
10
+ require 'rdstation/authorization'
9
11
  require 'rdstation/client'
10
12
  require 'rdstation/contacts'
11
13
  require 'rdstation/events'
@@ -15,3 +17,6 @@ require 'rdstation/webhooks'
15
17
  # Error handling
16
18
  require 'rdstation/error'
17
19
  require 'rdstation/error_handler'
20
+
21
+ # Builders
22
+ require 'rdstation/builder/field'
@@ -0,0 +1,19 @@
1
+ module RDStation
2
+ class << self
3
+ attr_accessor :configuration
4
+
5
+ def configure
6
+ self.configuration ||= Configuration.new
7
+ yield(configuration)
8
+ end
9
+ end
10
+
11
+ class Configuration
12
+ attr_accessor :client_id, :client_secret
13
+ attr_reader :access_token_refresh_callback
14
+
15
+ def on_access_token_refresh(&block)
16
+ @access_token_refresh_callback = block
17
+ end
18
+ end
19
+ end