zoho_hub 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +159 -31
- data/lib/zoho_hub/base_record.rb +35 -0
- data/lib/zoho_hub/connection.rb +14 -2
- data/lib/zoho_hub/errors.rb +12 -0
- data/lib/zoho_hub/response.rb +36 -14
- data/lib/zoho_hub/version.rb +1 -1
- data/lib/zoho_hub/with_attributes.rb +29 -5
- data/lib/zoho_hub/with_connection.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57cb4c2ca4e3b5f7f72773ae7b2492bd5335c7ff70b1ee014592b2f3f28eebe7
|
4
|
+
data.tar.gz: 64e3c1b8bf81edb48c6229d8e34b57f14ce9705bc4dbae8de32dddcccab54e2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c77c9a08e05a48efbb5e6472022d408a8e8c4902b34d04d95896408c2f17276ebc531bcf2969712c1528a8e93d0f0919e77f82df576bdc02a246419a753198e7
|
7
|
+
data.tar.gz: cd4d488c82598ec99a8c48b9823772b72041ebd2600965ffbbdec2b3a816776915cd72a28713c2c54cb1f7ec0b17db04955187e2f0a55bece5ed103aed06a19d
|
data/README.md
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
[![Build Status](https://travis-ci.com/rikas/zoho_hub.svg?branch=master)](https://travis-ci.com/rikas/zoho_hub)
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/zoho_hub.svg)](https://badge.fury.io/rb/zoho_hub)
|
5
5
|
|
6
|
-
Simple wrapper around Zoho CRM version2, using
|
7
|
-
for authentication.
|
6
|
+
Simple wrapper around Zoho CRM version2, using
|
7
|
+
[OAuth 2.0 protocol](https://www.zoho.com/crm/help/developer/api/oauth-overview.html) for authentication.
|
8
8
|
|
9
9
|
This gem reads your Module configuration and builds the corresponding classes for you, using some
|
10
10
|
reflection mechanisms. You should then be able to use simple classes with an API close to
|
@@ -12,6 +12,24 @@ ActiveRecord, to do CRUD operations.
|
|
12
12
|
|
13
13
|
**NOTE: this gem is WIP, please try to use it and open an issue if you run into limitations / problems**
|
14
14
|
|
15
|
+
## Table of Contents
|
16
|
+
|
17
|
+
* [Installation](#installation)
|
18
|
+
* [Setup](#setup-process)
|
19
|
+
1. [Register your application](#1-register-your-application)
|
20
|
+
2. [Configure ZohoHub with your credentials](#2-configure-zohohub-with-your-credentials)
|
21
|
+
3. [Authorization request](#3-authorization-request)
|
22
|
+
4. [Access token](#4-access-token)
|
23
|
+
5. [Refresh token](#5-refresh-token)
|
24
|
+
6. [BasicZohoHub flow](#6-basic-zohohub-flow)
|
25
|
+
7. [BaseRecord and record classes](#7-baserecord-and-record-classes)
|
26
|
+
* [Tips and suggestions](#tips-and-suggestions)
|
27
|
+
* [Examples](#examples)
|
28
|
+
1. [Setup auth token and request CurrentUser](#setup-auth-token-and-request-currentuser)
|
29
|
+
* [Development](#development)
|
30
|
+
* [Contributing](#contributing)
|
31
|
+
* [License](#license)
|
32
|
+
|
15
33
|
## Installation
|
16
34
|
|
17
35
|
Add this line to your application's Gemfile:
|
@@ -35,19 +53,21 @@ Or install it yourself as:
|
|
35
53
|
If you want to access your Zoho CRM account from your application you first need to create your
|
36
54
|
application as described here: https://www.zoho.com/crm/help/developer/api/register-client.html.
|
37
55
|
|
38
|
-
This will give you a **Client ID** and a **secret**, that you'll use in
|
56
|
+
This will give you a **Client ID** and a **secret**, that you'll use in
|
57
|
+
[step 2](#2-configure-zohohub-with-your-credentials).
|
39
58
|
|
40
59
|
#### 1.1 Zoho Accounts URL
|
41
60
|
|
42
61
|
Registration and authorization requests are made to Zoho's domain-specific Accounts URL which
|
43
62
|
varies depending on your region:
|
44
63
|
|
64
|
+
* China: https://accounts.zoho.com.cn
|
45
65
|
* EU: https://accounts.zoho.eu
|
66
|
+
* India: https://accounts.zoho.in
|
46
67
|
* US: https://accounts.zoho.com
|
47
|
-
* China: https://accounts.zoho.com.cn
|
48
68
|
|
49
|
-
ZohoHub uses the EU Account URL by default, but this can be overriden in a `ZohoHub.configure`
|
50
|
-
|
69
|
+
ZohoHub uses the EU Account URL by default, but this can be overriden in a `ZohoHub.configure` block
|
70
|
+
via the `api_domain` method ([step 2](#2-configure-zohohub-with-your-credentials).)
|
51
71
|
|
52
72
|
#### 1.2 Authorized Redirect URI
|
53
73
|
|
@@ -55,8 +75,11 @@ Per Zoho's API documentation, providing a **redirect URI** is optional. Doing so
|
|
55
75
|
your application to be redirected back to your app (to the **redirect URI**) with a **grant token**
|
56
76
|
upon successful authentication.
|
57
77
|
|
58
|
-
If you don't provide a **redirect URI**, you'll need to use the
|
59
|
-
|
78
|
+
If you don't provide a **redirect URI**, you'll need to use the
|
79
|
+
[self-client option](https://www.zoho.com/crm/help/developer/api/auth-request.html#self-client) for
|
80
|
+
authorization (see [3.2](#32-self-client-authorization).)
|
81
|
+
|
82
|
+
---
|
60
83
|
|
61
84
|
### 2. Configure ZohoHub with your credentials
|
62
85
|
|
@@ -65,7 +88,7 @@ for authorization (see 3.2 below.)
|
|
65
88
|
> code directly by referencing them via environment variables. Use something like the dotenv gem or
|
66
89
|
> encrypted credentials in Rails to keep them as secret and secure as possible.
|
67
90
|
|
68
|
-
You need to have a configuration block like the one below (in
|
91
|
+
You need to have a configuration block like the one below (in Rails add a `zoho_hub.rb` in your
|
69
92
|
`config/initializers` directory):
|
70
93
|
|
71
94
|
```ruby
|
@@ -78,6 +101,8 @@ ZohoHub.configure do |config|
|
|
78
101
|
end
|
79
102
|
```
|
80
103
|
|
104
|
+
---
|
105
|
+
|
81
106
|
### 3. Authorization request
|
82
107
|
|
83
108
|
In order to access data in Zoho CRM you need to authorize ZohoHub to access your account. To do so
|
@@ -94,7 +119,8 @@ ZohoHub::Auth.auth_url
|
|
94
119
|
# => "https://accounts.zoho.eu/oauth/v2/auth?access_type=offline&client_id=&redirect_uri=&response_type=code&scope=ZohoCRM.modules.custom.all,ZohoCRM.settings.all,ZohoCRM.modules.contacts.all,ZohoCRM.modules.all"
|
95
120
|
```
|
96
121
|
|
97
|
-
If you request this generated URL you should see a screen like this one, where you have to click on
|
122
|
+
If you request this generated URL you should see a screen like this one, where you have to click on
|
123
|
+
"Accept":
|
98
124
|
|
99
125
|
![](https://duaw26jehqd4r.cloudfront.net/items/1h1i3C1N0k0i02092F0S/Screen%20Shot%202018-11-25%20at%2019.18.38.png)
|
100
126
|
|
@@ -109,7 +135,8 @@ as follows (the value after `code=` is the **grant token**):
|
|
109
135
|
|
110
136
|
If you don't have a **redirect URI** or you want your application to be able to authorize with Zoho
|
111
137
|
programmatically (without a user required to be present and click the "Accept" prompt), Zoho
|
112
|
-
provides a
|
138
|
+
provides a
|
139
|
+
[self-client option](https://www.zoho.com/crm/help/developer/api/auth-request.html#self-client)
|
113
140
|
for authentication which will provide a **grant token**.
|
114
141
|
|
115
142
|
#### 3.3 More on scopes
|
@@ -131,7 +158,9 @@ ZohoHub::Auth.auth_url(scope: ['ZohoCRM.modules.custom.all', 'ZohoCRM.modules.al
|
|
131
158
|
# => "https://accounts.zoho.eu/oauth/v2/auth?access_type=offline&client_id=&redirect_uri=&response_type=code&scope=ZohoCRM.modules.custom.all,ZohoCRM.modules.all"
|
132
159
|
```
|
133
160
|
|
134
|
-
Refer to
|
161
|
+
Refer to
|
162
|
+
[Zoho's API documentation on scopes](https://www.zoho.com/crm/help/developer/api/oauth-overview.html#scopes)
|
163
|
+
for detailed information.
|
135
164
|
|
136
165
|
#### 3.4 Offline access
|
137
166
|
|
@@ -139,9 +168,9 @@ By design the **access tokens** returned by the OAuth flow expire after a period
|
|
139
168
|
default), as a safety mechanism. This means that any application that wants to work with a user's
|
140
169
|
data needs the user to have recently gone through the OAuth flow, aka be online.
|
141
170
|
|
142
|
-
When you request offline access the Zoho API returns a **refresh token**. **Refresh tokens** give
|
143
|
-
application the ability to request data on behalf of the user when the user is not present and
|
144
|
-
front of your application.
|
171
|
+
When you request offline access the Zoho API returns a **refresh token**. **Refresh tokens** give
|
172
|
+
your application the ability to request data on behalf of the user when the user is not present and
|
173
|
+
in front of your application.
|
145
174
|
|
146
175
|
**By default `ZohoHub::Auth.auth_url` will request offline access**
|
147
176
|
|
@@ -152,6 +181,8 @@ ZohoHub::Auth.auth_url(access_type: 'online')
|
|
152
181
|
# => "https://accounts.zoho.eu/oauth/v2/auth?access_type=online&client_id=&redirect_uri=&response_type=code&scope=ZohoCRM.modules.custom.all,ZohoCRM.settings.all,ZohoCRM.modules.contacts.all,ZohoCRM.modules.all"
|
153
182
|
```
|
154
183
|
|
184
|
+
---
|
185
|
+
|
155
186
|
### 4. Access token
|
156
187
|
|
157
188
|
See Zoho's API documentation for generating an initial **access token**:
|
@@ -163,11 +194,14 @@ To use an **access token** in a manual request, include it as a request header a
|
|
163
194
|
To use an **access token** with ZohoHub, pass it to the `ZohoHub.setup_connection` method as the
|
164
195
|
`access_token` parameter.
|
165
196
|
|
197
|
+
---
|
166
198
|
|
167
199
|
### 5. Refresh token
|
168
200
|
|
169
201
|
TODO
|
170
202
|
|
203
|
+
---
|
204
|
+
|
171
205
|
### 6. Basic ZohoHub flow
|
172
206
|
|
173
207
|
Once ZohoHub has been configured with your credentials (section 2) and you have a fresh **access
|
@@ -186,7 +220,10 @@ Now you can issue requests to Zoho's API with the Connection object, e.g.:
|
|
186
220
|
ZohoHub.connection.get 'Leads'
|
187
221
|
```
|
188
222
|
|
189
|
-
A successful request will receive a response like the sample here:
|
223
|
+
A successful request will receive a response like the sample here:
|
224
|
+
https://www.zoho.com/crm/help/developer/api/get-records.html.
|
225
|
+
|
226
|
+
---
|
190
227
|
|
191
228
|
### 7. BaseRecord and record classes
|
192
229
|
|
@@ -208,7 +245,7 @@ inherits from `ZohoHub::BaseRecord`. For example, to build a class for the Leads
|
|
208
245
|
```ruby
|
209
246
|
# lead.rb
|
210
247
|
|
211
|
-
class Lead < BaseRecord
|
248
|
+
class Lead < ZohoHub::BaseRecord
|
212
249
|
...
|
213
250
|
end
|
214
251
|
```
|
@@ -218,28 +255,34 @@ Specify this module's fields as attributes:
|
|
218
255
|
```ruby
|
219
256
|
# lead.rb
|
220
257
|
|
221
|
-
class Lead < BaseRecord
|
258
|
+
class Lead < ZohoHub::BaseRecord
|
222
259
|
attributes: :id, :first_name, :last_name, :phone, :email, :source, # etc.
|
223
260
|
end
|
224
261
|
```
|
225
262
|
|
226
|
-
|
263
|
+
Now you can issue requests more easily with your record class, e.g.:
|
227
264
|
|
228
265
|
```ruby
|
229
|
-
|
230
|
-
|
231
|
-
zoho_key = attr_to_zoho_key(attr)
|
266
|
+
# Request a (paginated) list of all Lead records
|
267
|
+
Lead.all
|
232
268
|
|
233
|
-
|
234
|
-
|
235
|
-
end
|
269
|
+
# Get the Lead instance with a specific ID
|
270
|
+
Lead.find('78265000003433063')
|
236
271
|
```
|
237
272
|
|
238
|
-
|
273
|
+
And even create new Lead entries in Zoho:
|
239
274
|
|
240
275
|
```ruby
|
241
|
-
|
242
|
-
|
276
|
+
lead = Lead.new(
|
277
|
+
first_name: 'First name',
|
278
|
+
last_name: 'Last name',
|
279
|
+
phone: '+35197736281',
|
280
|
+
email: 'myemail@gmail.com',
|
281
|
+
source: 'Homepage'
|
282
|
+
)
|
283
|
+
|
284
|
+
# Creates the new lead
|
285
|
+
lead.save
|
243
286
|
```
|
244
287
|
|
245
288
|
## Tips and suggestions
|
@@ -252,10 +295,94 @@ Lead.all
|
|
252
295
|
friend - especially the sample HTTP requests and responses in the various sections under "Rest
|
253
296
|
API" on the left.
|
254
297
|
* If you're manually implementing your record classes (rather than using the reflection mechanism),
|
255
|
-
the files in `/
|
256
|
-
* Requests can be issued to Zoho CRM's
|
298
|
+
the files in `/examples/models/` can help you get started.
|
299
|
+
* Requests can be issued to Zoho CRM's
|
300
|
+
[Sandbox](https://help.zoho.com/portal/kb/articles/using-sandbox)
|
257
301
|
by configuring `https://crmsandbox.zoho.com/crm` (or regional equivalent) as the `api_domain`.
|
258
302
|
|
303
|
+
## Examples
|
304
|
+
|
305
|
+
### Setup auth token and request CurrentUser
|
306
|
+
|
307
|
+
> This example assumes use of the dotenv gem and is written directly into
|
308
|
+
> ZohoHub's root directory (rather than using ZohoHub as a gem) for simplicity.
|
309
|
+
|
310
|
+
1. Edit `bin/console` to comment out refreshing the token and setting up the connection:
|
311
|
+
|
312
|
+
```ruby
|
313
|
+
# bin/console
|
314
|
+
|
315
|
+
...
|
316
|
+
# puts 'Refreshing token...'
|
317
|
+
# token_params = ZohoHub::Auth.refresh_token(ENV['ZOHO_REFRESH_TOKEN'])
|
318
|
+
# ZohoHub.setup_connection(token_params)
|
319
|
+
...
|
320
|
+
```
|
321
|
+
|
322
|
+
2. [Register your application](#1-register-your-application) to obtain a **client ID** and
|
323
|
+
**secret**. (Leave the [Zoho API Credentials page](https://accounts.zoho.com/developerconsole) open;
|
324
|
+
you'll need it in step 5.)
|
325
|
+
3. Determine your [Zoho Accounts URL](#11-zoho-accounts-url).
|
326
|
+
4. Add your registration and account URL information to a `.env` file:
|
327
|
+
|
328
|
+
```
|
329
|
+
# .env
|
330
|
+
|
331
|
+
ZOHO_CLIENT_ID=YOUR_CLIENT_ID
|
332
|
+
ZOHO_SECRET=YOUR_SECRET
|
333
|
+
ZOHO_API_DOMAIN=YOUR_ZOHO_ACCOUNTS_URL
|
334
|
+
```
|
335
|
+
|
336
|
+
5. On the [Zoho API Credentials page](https://accounts.zoho.com/developerconsole) from step 1, click
|
337
|
+
the three vertical dots and select `Self client`.
|
338
|
+
6. Paste this into the `Scope` field: `ZohoCRM.users.ALL`, choose an expiration time, and click
|
339
|
+
`View Code`; this is your **Grant token**.
|
340
|
+
7. Run the ZohoHub console from your terminal: `bin/console`
|
341
|
+
8. Issue a token request with the **grant token** (notice the quotes around the token value):
|
342
|
+
|
343
|
+
```ruby
|
344
|
+
ZohoHub::Auth.get_token('paste_your_grant_token_here')
|
345
|
+
```
|
346
|
+
|
347
|
+
This should return a response with an **access token**, e.g.:
|
348
|
+
|
349
|
+
```ruby
|
350
|
+
=> {:access_token=>"ACCESS_TOKEN_VALUE",
|
351
|
+
:expires_in_sec=>3600,
|
352
|
+
:api_domain=>"https://www.zohoapis.com",
|
353
|
+
:token_type=>"Bearer"
|
354
|
+
}
|
355
|
+
```
|
356
|
+
|
357
|
+
exit the console with `exit`.
|
358
|
+
|
359
|
+
9. Add the access token to your `.env` file:
|
360
|
+
|
361
|
+
```
|
362
|
+
# .env
|
363
|
+
|
364
|
+
ZOHO_CLIENT_ID=YOUR_CLIENT_ID
|
365
|
+
ZOHO_SECRET=YOUR_SECRET
|
366
|
+
ZOHO_API_DOMAIN=YOUR_ZOHO_ACCOUNTS_URL
|
367
|
+
ZOHO_ACCESS_TOKEN=YOUR_ACCESS_TOKEN
|
368
|
+
```
|
369
|
+
|
370
|
+
10. Edit `bin/console` to add a new `setup_connection` after the previously commented out one:
|
371
|
+
|
372
|
+
```ruby
|
373
|
+
# bin/console
|
374
|
+
|
375
|
+
...
|
376
|
+
# ZohoHub.setup_connection(token_params)
|
377
|
+
|
378
|
+
ZohoHub.setup_connection(access_token: ENV['ZOHO_ACCESS_TOKEN'])
|
379
|
+
...
|
380
|
+
```
|
381
|
+
|
382
|
+
11. Start the console again: `bin/console`.
|
383
|
+
|
384
|
+
12. Issue a request for the current user: `ZohoHub.connection.get 'users?type=CurrentUser'`
|
385
|
+
|
259
386
|
## Development
|
260
387
|
|
261
388
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run
|
@@ -270,4 +397,5 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/rikas/
|
|
270
397
|
|
271
398
|
## License
|
272
399
|
|
273
|
-
The gem is available as open source under the terms of the
|
400
|
+
The gem is available as open source under the terms of the
|
401
|
+
[MIT License](https://opensource.org/licenses/MIT).
|
data/lib/zoho_hub/base_record.rb
CHANGED
@@ -42,6 +42,17 @@ module ZohoHub
|
|
42
42
|
def where(params)
|
43
43
|
path = File.join(request_path, 'search')
|
44
44
|
|
45
|
+
if params.size == 1
|
46
|
+
params = case params.keys.first
|
47
|
+
when :criteria, :email, :phone, :word
|
48
|
+
# these attributes are directly handled by Zoho
|
49
|
+
# see https://www.zoho.com/crm/help/developer/api/search-records.html
|
50
|
+
params
|
51
|
+
else
|
52
|
+
{ criteria: "#{attr_to_zoho_key(params.keys.first)}:equals:#{params.values.first}" }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
45
56
|
body = get(path, params)
|
46
57
|
response = build_response(body)
|
47
58
|
|
@@ -59,6 +70,14 @@ module ZohoHub
|
|
59
70
|
new(params).save
|
60
71
|
end
|
61
72
|
|
73
|
+
def update(id, params)
|
74
|
+
new(id: id).update(params)
|
75
|
+
end
|
76
|
+
|
77
|
+
def blueprint_transition(id, transition_id, data = {})
|
78
|
+
new(id: id).blueprint_transition(transition_id, data)
|
79
|
+
end
|
80
|
+
|
62
81
|
def all(params = {})
|
63
82
|
params[:page] ||= DEFAULT_PAGE
|
64
83
|
params[:per_page] ||= DEFAULT_RECORDS_PER_PAGE
|
@@ -85,6 +104,10 @@ module ZohoHub
|
|
85
104
|
|
86
105
|
raise InvalidTokenError, response.msg if response.invalid_token?
|
87
106
|
raise RecordInvalid, response.msg if response.invalid_data?
|
107
|
+
raise InvalidModule, response.msg if response.invalid_module?
|
108
|
+
raise NoPermission, response.msg if response.no_permission?
|
109
|
+
raise MandatoryNotFound, response.msg if response.mandatory_not_found?
|
110
|
+
raise RecordInBlueprint, response.msg if response.record_in_blueprint?
|
88
111
|
|
89
112
|
response
|
90
113
|
end
|
@@ -110,6 +133,18 @@ module ZohoHub
|
|
110
133
|
response.data.first.dig(:details, :id)
|
111
134
|
end
|
112
135
|
|
136
|
+
def update(params)
|
137
|
+
zoho_params = Hash[params.map { |k, v| [attr_to_zoho_key(k), v] }]
|
138
|
+
body = put(File.join(self.class.request_path, id), data: [zoho_params])
|
139
|
+
build_response(body)
|
140
|
+
end
|
141
|
+
|
142
|
+
def blueprint_transition(transition_id, data = {})
|
143
|
+
body = put(File.join(self.class.request_path, id, 'actions/blueprint'),
|
144
|
+
blueprint: [{ transition_id: transition_id, data: data }])
|
145
|
+
build_response(body)
|
146
|
+
end
|
147
|
+
|
113
148
|
def new_record?
|
114
149
|
!id
|
115
150
|
end
|
data/lib/zoho_hub/connection.rb
CHANGED
@@ -9,6 +9,18 @@ require 'zoho_hub/response'
|
|
9
9
|
|
10
10
|
module ZohoHub
|
11
11
|
class Connection
|
12
|
+
class << self
|
13
|
+
def infer_api_domain
|
14
|
+
case ZohoHub.configuration.api_domain
|
15
|
+
when 'https://accounts.zoho.com' then 'https://www.zohoapis.com'
|
16
|
+
when 'https://accounts.zoho.com.cn' then 'https://www.zohoapis.com.cn'
|
17
|
+
when 'https://accounts.zoho.in' then 'https://www.zohoapis.in'
|
18
|
+
when 'https://accounts.zoho.eu' then 'https://www.zohoapis.eu'
|
19
|
+
else DEFAULT_DOMAIN
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
12
24
|
attr_accessor :debug, :access_token, :expires_in, :api_domain, :refresh_token
|
13
25
|
|
14
26
|
# This is a block to be run when the token is refreshed. This way you can do whatever you want
|
@@ -19,10 +31,10 @@ module ZohoHub
|
|
19
31
|
|
20
32
|
BASE_PATH = '/crm/v2/'
|
21
33
|
|
22
|
-
def initialize(access_token:, api_domain:
|
34
|
+
def initialize(access_token:, api_domain: nil, expires_in: 3600, refresh_token: nil)
|
23
35
|
@access_token = access_token
|
24
36
|
@expires_in = expires_in
|
25
|
-
@api_domain = api_domain
|
37
|
+
@api_domain = api_domain || self.class.infer_api_domain
|
26
38
|
@refresh_token ||= refresh_token # do not overwrite if it's already set
|
27
39
|
end
|
28
40
|
|
data/lib/zoho_hub/errors.rb
CHANGED
@@ -10,6 +10,18 @@ module ZohoHub
|
|
10
10
|
class InvalidTokenError < StandardError
|
11
11
|
end
|
12
12
|
|
13
|
+
class InvalidModule < StandardError
|
14
|
+
end
|
15
|
+
|
16
|
+
class NoPermission < StandardError
|
17
|
+
end
|
18
|
+
|
19
|
+
class MandatoryNotFound < StandardError
|
20
|
+
end
|
21
|
+
|
22
|
+
class RecordInBlueprint < StandardError
|
23
|
+
end
|
24
|
+
|
13
25
|
class ZohoAPIError < StandardError
|
14
26
|
end
|
15
27
|
end
|
data/lib/zoho_hub/response.rb
CHANGED
@@ -7,22 +7,31 @@ module ZohoHub
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def invalid_data?
|
10
|
-
|
11
|
-
|
12
|
-
data[:code] == 'INVALID_DATA'
|
10
|
+
error_code?('INVALID_DATA')
|
13
11
|
end
|
14
12
|
|
15
|
-
# {:code=>"INVALID_TOKEN", :details=>{}, :message=>"invalid oauth token", :status=>"error"}
|
16
13
|
def invalid_token?
|
17
|
-
|
18
|
-
|
19
|
-
data[:code] == 'INVALID_TOKEN'
|
14
|
+
error_code?('INVALID_TOKEN')
|
20
15
|
end
|
21
16
|
|
22
17
|
def authentication_failure?
|
23
|
-
|
18
|
+
error_code?('AUTHENTICATION_FAILURE')
|
19
|
+
end
|
20
|
+
|
21
|
+
def invalid_module?
|
22
|
+
error_code?('INVALID_MODULE')
|
23
|
+
end
|
24
|
+
|
25
|
+
def no_permission?
|
26
|
+
error_code?('NO_PERMISSION')
|
27
|
+
end
|
24
28
|
|
25
|
-
|
29
|
+
def mandatory_not_found?
|
30
|
+
error_code?('MANDATORY_NOT_FOUND')
|
31
|
+
end
|
32
|
+
|
33
|
+
def record_in_blueprint?
|
34
|
+
error_code?('RECORD_IN_BLUEPRINT')
|
26
35
|
end
|
27
36
|
|
28
37
|
def empty?
|
@@ -35,12 +44,13 @@ module ZohoHub
|
|
35
44
|
end
|
36
45
|
|
37
46
|
def msg
|
38
|
-
|
47
|
+
first_data = data.is_a?(Array) ? data.first : data
|
48
|
+
msg = first_data[:message]
|
39
49
|
|
40
|
-
if
|
41
|
-
expected =
|
42
|
-
field =
|
43
|
-
parent_api_name =
|
50
|
+
if first_data.dig(:details, :expected_data_type)
|
51
|
+
expected = first_data.dig(:details, :expected_data_type)
|
52
|
+
field = first_data.dig(:details, :api_name)
|
53
|
+
parent_api_name = first_data.dig(:details, :parent_api_name)
|
44
54
|
|
45
55
|
msg << ", expected #{expected} for '#{field}'"
|
46
56
|
msg << " in #{parent_api_name}" if parent_api_name
|
@@ -48,5 +58,17 @@ module ZohoHub
|
|
48
58
|
|
49
59
|
msg
|
50
60
|
end
|
61
|
+
|
62
|
+
# error response examples:
|
63
|
+
# {"data":[{"code":"INVALID_DATA","details":{},"message":"the id given seems to be invalid","status":"error"}]}
|
64
|
+
# {:code=>"INVALID_TOKEN", :details=>{}, :message=>"invalid oauth token", :status=>"error"}
|
65
|
+
def error_code?(code)
|
66
|
+
if data.is_a?(Array)
|
67
|
+
return false if data.size > 1
|
68
|
+
return data.first[:code] == code
|
69
|
+
end
|
70
|
+
|
71
|
+
data[:code] == code
|
72
|
+
end
|
51
73
|
end
|
52
74
|
end
|
data/lib/zoho_hub/version.rb
CHANGED
@@ -43,6 +43,11 @@ module ZohoHub
|
|
43
43
|
@attribute_translation = translation
|
44
44
|
end
|
45
45
|
|
46
|
+
def attr_to_zoho_key(attr_name)
|
47
|
+
return attribute_translation[attr_name.to_sym] if attribute_translation.key?(attr_name.to_sym)
|
48
|
+
attr_name.to_s.split('_').map(&:capitalize).join('_').to_sym
|
49
|
+
end
|
50
|
+
|
46
51
|
def zoho_key_translation
|
47
52
|
@attribute_translation.to_a.map(&:rotate).to_h
|
48
53
|
end
|
@@ -53,14 +58,24 @@ module ZohoHub
|
|
53
58
|
self.class.attributes
|
54
59
|
end
|
55
60
|
|
56
|
-
private
|
61
|
+
# This method and the correponding private methods are inspired from Rails ActiveModel
|
62
|
+
# github.com/rails/rails/blob/master/activemodel/lib/active_model/attribute_assignment.rb
|
63
|
+
def assign_attributes(new_attributes)
|
64
|
+
unless new_attributes.is_a?(Hash)
|
65
|
+
raise ArgumentError, "When assigning attributes, you must pass a hash as an argument"
|
66
|
+
end
|
67
|
+
return if new_attributes.empty?
|
57
68
|
|
58
|
-
|
59
|
-
|
69
|
+
attributes = Hash[new_attributes.map { |k, v| [k.to_s, v] }]
|
70
|
+
attributes.each do |k, v|
|
71
|
+
assign_attribute(k, v)
|
72
|
+
end
|
73
|
+
end
|
60
74
|
|
61
|
-
|
75
|
+
private
|
62
76
|
|
63
|
-
|
77
|
+
def attr_to_zoho_key(attr_name)
|
78
|
+
self.class.attr_to_zoho_key(attr_name)
|
64
79
|
end
|
65
80
|
|
66
81
|
def zoho_key_to_attr(zoho_key)
|
@@ -70,5 +85,14 @@ module ZohoHub
|
|
70
85
|
|
71
86
|
zoho_key.to_sym
|
72
87
|
end
|
88
|
+
|
89
|
+
def assign_attribute(k, v)
|
90
|
+
setter = :"#{k}="
|
91
|
+
if respond_to?(setter)
|
92
|
+
public_send(setter, v)
|
93
|
+
else
|
94
|
+
raise ArgumentError, "Unknown attribute #{k}"
|
95
|
+
end
|
96
|
+
end
|
73
97
|
end
|
74
98
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zoho_hub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ricardo Otero
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|