zoho_hub 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 57cb4c2ca4e3b5f7f72773ae7b2492bd5335c7ff70b1ee014592b2f3f28eebe7
4
- data.tar.gz: 64e3c1b8bf81edb48c6229d8e34b57f14ce9705bc4dbae8de32dddcccab54e2c
3
+ metadata.gz: f91e364b7e8432a5047a03f6fa2426201c502368c036bc604566de53de2e65fb
4
+ data.tar.gz: fc574d26b030f7d69025cc6004cb127a8eb7296ed9bba34566ac0c6de2c0b6fd
5
5
  SHA512:
6
- metadata.gz: c77c9a08e05a48efbb5e6472022d408a8e8c4902b34d04d95896408c2f17276ebc531bcf2969712c1528a8e93d0f0919e77f82df576bdc02a246419a753198e7
7
- data.tar.gz: cd4d488c82598ec99a8c48b9823772b72041ebd2600965ffbbdec2b3a816776915cd72a28713c2c54cb1f7ec0b17db04955187e2f0a55bece5ed103aed06a19d
6
+ metadata.gz: b4931bbcc3fcf425eae35d1b5a5eeca9c27112503e0444198504a2ab65667638f0a070808d8299d00ed7cd1ed03f71d63b0d0ad645cd22e0ef9823902b5028b5
7
+ data.tar.gz: 8898cf446859177ef26d0a73a066e7f5f0f7ede6fc2401833d4900f2524bc0a9d204890c0006ad59d79f822f8a0e1df7b0bd75f8ca9d60126829960aaad4eea5
@@ -0,0 +1,42 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ lint:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v2
10
+ - uses: ruby/setup-ruby@v1
11
+ with:
12
+ ruby-version: "2.5"
13
+ bundler-cache: true
14
+ - name: rubocop version
15
+ timeout-minutes: 1
16
+ run: bundle exec rubocop --version
17
+ - name: rubocop
18
+ timeout-minutes: 5
19
+ run: bundle exec rubocop -c .rubocop.yml
20
+
21
+ test:
22
+ runs-on: ubuntu-latest
23
+ continue-on-error: ${{ matrix.experimental }}
24
+ strategy:
25
+ fail-fast: false
26
+ matrix:
27
+ ruby: ["2.5", "2.6", "2.7", "3.0"]
28
+ experimental: [false]
29
+ include:
30
+ - ruby: "jruby"
31
+ experimental: true
32
+ - ruby: "truffleruby"
33
+ experimental: true
34
+ steps:
35
+ - uses: actions/checkout@v2
36
+ - uses: ruby/setup-ruby@v1
37
+ with:
38
+ ruby-version: ${{matrix.ruby}}
39
+ bundler-cache: true
40
+ - name: Run tests
41
+ timeout-minutes: 5
42
+ run: ${{matrix.env}} bundle exec rspec
data/.rubocop.yml CHANGED
@@ -3,6 +3,13 @@ require: rubocop-rspec
3
3
  AllCops:
4
4
  TargetRubyVersion: 2.5.1
5
5
 
6
+ Gemspec/RequiredRubyVersion:
7
+ Enabled: false
8
+
9
+ Lint:
10
+ Exclude:
11
+ - bin/*
12
+
6
13
  # Don't force top level comments in every class
7
14
  Style/Documentation:
8
15
  Enabled: false
@@ -25,6 +32,12 @@ Metrics/ClassLength:
25
32
  Metrics/MethodLength:
26
33
  Max: 20
27
34
 
35
+ Metrics/CyclomaticComplexity:
36
+ Max: 10
37
+
38
+ Metrics/PerceivedComplexity:
39
+ Max: 10
40
+
28
41
  Metrics/AbcSize:
29
42
  Max: 30
30
43
 
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.5.3
1
+ 2.5.8
data/README.md CHANGED
@@ -14,21 +14,35 @@ ActiveRecord, to do CRUD operations.
14
14
 
15
15
  ## Table of Contents
16
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)
17
+ - [ZohoHub](#zohohub)
18
+ - [Table of Contents](#table-of-contents)
19
+ - [Installation](#installation)
20
+ - [Setup process](#setup-process)
21
+ - [1. Register your application](#1-register-your-application)
22
+ - [1.1 Zoho Accounts URL](#11-zoho-accounts-url)
23
+ - [1.2 Authorized Redirect URI](#12-authorized-redirect-uri)
24
+ - [2. Configure ZohoHub with your credentials](#2-configure-zohohub-with-your-credentials)
25
+ - [3. Authorization request](#3-authorization-request)
26
+ - [3.1 Redirection based authentication](#31-redirection-based-authentication)
27
+ - [3.2 Self-Client Authorization](#32-self-client-authorization)
28
+ - [3.3 More on scopes](#33-more-on-scopes)
29
+ - [3.4 Offline access](#34-offline-access)
30
+ - [4. Access token](#4-access-token)
31
+ - [5. Refresh token](#5-refresh-token)
32
+ - [6. Basic ZohoHub flow](#6-basic-zohohub-flow)
33
+ - [7. BaseRecord and record classes](#7-baserecord-and-record-classes)
34
+ - [7.1 Reflection](#71-reflection)
35
+ - [7.2 Subclassing BaseRecord](#72-subclassing-baserecord)
36
+ - [8 Notifications](#8-notifications)
37
+ - [8.1 Enable notifications](#81-enable-notifications)
38
+ - [8.2 List notifications](#82-list-notifications)
39
+ - [8.3 Caveats](#83-caveats)
40
+ - [Tips and suggestions](#tips-and-suggestions)
41
+ - [Examples](#examples)
42
+ - [Setup auth token and request CurrentUser](#setup-auth-token-and-request-currentuser)
43
+ - [Development](#development)
44
+ - [Contributing](#contributing)
45
+ - [License](#license)
32
46
 
33
47
  ## Installation
34
48
 
@@ -198,7 +212,9 @@ To use an **access token** with ZohoHub, pass it to the `ZohoHub.setup_connectio
198
212
 
199
213
  ### 5. Refresh token
200
214
 
201
- TODO
215
+ This gem automatically refresh the access token.
216
+
217
+ If you want automatic refresh, use the refresh_token argument as in the next chapter.
202
218
 
203
219
  ---
204
220
 
@@ -210,7 +226,8 @@ token**, setup a ZohoHub connection:
210
226
  ```ruby
211
227
  ZohoHub.setup_connection access_token: 'ACCESS_TOKEN',
212
228
  expires_in: 'EXPIRES_IN_SEC',
213
- api_domain: 'API_DOMAIN'
229
+ api_domain: 'API_DOMAIN',
230
+ refresh_token: 'REFRESH_TOKEN'
214
231
  ```
215
232
 
216
233
  Now you can issue requests to Zoho's API with the Connection object, e.g.:
@@ -256,7 +273,7 @@ Specify this module's fields as attributes:
256
273
  # lead.rb
257
274
 
258
275
  class Lead < ZohoHub::BaseRecord
259
- attributes: :id, :first_name, :last_name, :phone, :email, :source, # etc.
276
+ attributes :id, :first_name, :last_name, :phone, :email, :source, # etc.
260
277
  end
261
278
  ```
262
279
 
@@ -283,8 +300,101 @@ lead = Lead.new(
283
300
 
284
301
  # Creates the new lead
285
302
  lead.save
303
+
304
+ # Or in one step:
305
+ lead = Lead.create(first_name: 'First name', ...)
306
+ ```
307
+
308
+ Updating records:
309
+
310
+ ```ruby
311
+ Lead.update(id: lead.id, first_name: "...", last_name: "...")
312
+
313
+ # Or
314
+ lead.update(first_name: "...", last_name: "...")
315
+
316
+ # Or update up to 100 records in one call:
317
+ leads = [{ id: id1, phone: "123" }, { id: id2, first_name: "..." }]
318
+ Lead.update_all(leads)
319
+ ```
320
+
321
+ Blueprint transition:
322
+
323
+ ```ruby
324
+ Lead.blueprint_transition(lead.id, transition_id)
325
+
326
+ # Or
327
+ lead.blueprint_transition(transition_id)
328
+ ```
329
+
330
+ Adding notes:
331
+
332
+ ```ruby
333
+ Lead.add_note(id: lead.id, title: 'Note title', content: 'Note content')
334
+ ```
335
+
336
+ Related records:
337
+
338
+ ```ruby
339
+ Product.all_related(parent_module: 'Lead', parent_id: lead.id)
340
+ Product.add_related(
341
+ parent_module: 'Lead',
342
+ parent_id: lead.id,
343
+ related_id: product.id
344
+ )
345
+ Product.remove_related(
346
+ parent_module: 'Lead',
347
+ parent_id: lead.id,
348
+ related_id: product.id
349
+ )
350
+ Product.update_related(...)
286
351
  ```
287
352
 
353
+ Attachments (`ZohoHub::Attachment` is defined in the gem):
354
+
355
+ ```ruby
356
+ Lead.related_attachments(parent_id: lead.id)
357
+ # -> Array of Attachments
358
+
359
+ attachment = Lead.download_attachment(parent_id: lead.id, attachment_id:attachment.id)
360
+ # -> Attachment (attachment.file contains the file as a Tempfile)
361
+
362
+ #NB: Lead.upload_attachment not implemented yet
363
+ ```
364
+
365
+ ## 8 Notifications
366
+ Zoho allows you to receive a notification when a record of a module changes. Supported operation types are create, delete, edit, all.
367
+
368
+ ### 8.1 Enable notifications
369
+ In order to receive notifications, you have to enable them first.
370
+ ```ruby
371
+ # Enable notifications for a given channel:
372
+ notification_url = 'https://example.org/api/notifications' # Zoho will send notifications by POST to this url
373
+ token = '123abc' # Zoho will send this token back to you, so you can ensure that the notification is from Zoho
374
+ channel_id = 1 # Choose a channel to handle the response
375
+ events = %w[Leads.create Deals.edit Contacts.delete Sales_Orders.all] # Which events to receive notifications for
376
+ channel_expiry = (DateTime.now + 1.day).iso8601 # choose a date when the channel should expire. 24h is the maximum, default is one hour
377
+
378
+ ZohoHub::Notifications.enable(notification_url, channel_id, events, channel_expiry, token)
379
+ ```
380
+
381
+ After enabling notifications, Zoho will execute a POST request to the provided notification_url every time the requested event occurs.
382
+
383
+ For a list of an in-depth description of the response, check the [Zoho documentation](https://www.zoho.com/crm/developer/docs/api/notifications/overview.html)
384
+
385
+ ### 8.2 List notifications
386
+ You can also retrieve all notifications that are currently enabled and that you are receiving uppdates for.
387
+
388
+ ```ruby
389
+ # Get all enabled notifications
390
+ ZohoHub::Notifications.all
391
+ ```
392
+
393
+ ### 8.3 Caveats
394
+
395
+ * Zoho does not notify you when records are merged.
396
+ * Since Zoho does not tell you what changed, you will have to request the record by yourself. Due to this you can miss changes, when they occur quickly after another. This is especially important for status changes, as you might miss state changes.
397
+
288
398
  ## Tips and suggestions
289
399
 
290
400
  * Using a tool such as Postman or curl to issue HTTP requests and verify responses in isolation
data/bin/console CHANGED
@@ -20,7 +20,7 @@ puts 'Refreshing token...'
20
20
  token_params = ZohoHub::Auth.refresh_token(ENV['ZOHO_REFRESH_TOKEN'])
21
21
  ZohoHub.setup_connection(token_params)
22
22
 
23
- self.send(:include, ZohoHub)
23
+ send(:include, ZohoHub)
24
24
 
25
25
  require 'pry'
26
26
  Pry.start
@@ -28,6 +28,8 @@ module ZohoHub
28
28
  )
29
29
 
30
30
  def initialize(params = {})
31
+ super
32
+
31
33
  attributes.each do |attr|
32
34
  zoho_key = attr_to_zoho_key(attr)
33
35
 
data/lib/zoho_hub.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'backports/2.3.0/hash' if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3.0')
4
+ require 'backports/2.5.0/hash' if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5.0')
4
5
 
5
6
  require 'zoho_hub/version'
6
7
  require 'zoho_hub/auth'
@@ -8,6 +9,7 @@ require 'zoho_hub/configuration'
8
9
  require 'zoho_hub/connection'
9
10
  require 'zoho_hub/errors'
10
11
  require 'zoho_hub/base_record'
12
+ require 'zoho_hub/modules/attachment'
11
13
  require 'zoho_hub/settings/module'
12
14
 
13
15
  require 'zoho_hub/reflection/module_builder'
@@ -39,7 +41,7 @@ module ZohoHub
39
41
 
40
42
  connection_params = params.dup.slice(:access_token, :expires_in, :api_domain, :refresh_token)
41
43
 
42
- @connection = Connection.new(connection_params)
44
+ @connection = Connection.new(**connection_params)
43
45
  end
44
46
 
45
47
  def connection
data/lib/zoho_hub/auth.rb CHANGED
@@ -20,6 +20,7 @@ module ZohoHub
20
20
  ZohoCRM.settings.all
21
21
  ZohoCRM.modules.contacts.all
22
22
  ZohoCRM.modules.all
23
+ ZohoCRM.notifications.all
23
24
  ].freeze
24
25
 
25
26
  DEFAULT_ACCESS_TYPE = 'offline'
@@ -12,7 +12,7 @@ module ZohoHub
12
12
  include WithAttributes
13
13
  include WithValidations
14
14
 
15
- # Default nnumber of records when fetching all.
15
+ # Default number of records when fetching all.
16
16
  DEFAULT_RECORDS_PER_PAGE = 200
17
17
 
18
18
  # Default page number when fetching all.
@@ -49,7 +49,11 @@ module ZohoHub
49
49
  # see https://www.zoho.com/crm/help/developer/api/search-records.html
50
50
  params
51
51
  else
52
- { criteria: "#{attr_to_zoho_key(params.keys.first)}:equals:#{params.values.first}" }
52
+ key = attr_to_zoho_key(params.keys.first)
53
+
54
+ {
55
+ criteria: "#{key}:equals:#{params.values.first}"
56
+ }
53
57
  end
54
58
  end
55
59
 
@@ -78,6 +82,53 @@ module ZohoHub
78
82
  new(id: id).blueprint_transition(transition_id, data)
79
83
  end
80
84
 
85
+ def blueprint_transitions(id)
86
+ new(id: id).blueprint_transitions
87
+ end
88
+
89
+ def add_note(id:, title: '', content: '')
90
+ path = File.join(request_path, id, 'Notes')
91
+ post(path, data: [{ Note_Title: title, Note_Content: content }])
92
+ end
93
+
94
+ def all_related(parent_module:, parent_id:)
95
+ body = get(File.join(parent_module.constantize.request_path, parent_id, request_path))
96
+ response = build_response(body)
97
+
98
+ data = response.nil? ? [] : response.data
99
+
100
+ data.map { |json| new(json) }
101
+ end
102
+
103
+ def update_related(parent_module:, parent_id:, related_id:, data:)
104
+ path = File.join(
105
+ parent_module.constantize.request_path, parent_id, request_path, related_id
106
+ )
107
+ body = put(path, data: data)
108
+ build_response(body)
109
+ end
110
+
111
+ def add_related(parent_module:, parent_id:, related_id:)
112
+ update_related(
113
+ parent_module: parent_module, parent_id: parent_id, related_id: related_id, data: [{}]
114
+ )
115
+ end
116
+
117
+ def remove_related(parent_module:, parent_id:, related_id:)
118
+ body = delete(
119
+ File.join(parent_module.constantize.request_path, parent_id, request_path, related_id)
120
+ )
121
+ build_response(body)
122
+ end
123
+
124
+ def update_all(records)
125
+ zoho_params = records.transform_keys { |key| attr_to_zoho_key(key) }
126
+
127
+ body = put(File.join(request_path), data: zoho_params)
128
+
129
+ build_response(body)
130
+ end
131
+
81
132
  def all(params = {})
82
133
  params[:page] ||= DEFAULT_PAGE
83
134
  params[:per_page] ||= DEFAULT_RECORDS_PER_PAGE
@@ -103,6 +154,7 @@ module ZohoHub
103
154
  response = Response.new(body)
104
155
 
105
156
  raise InvalidTokenError, response.msg if response.invalid_token?
157
+ raise InternalError, response.msg if response.internal_error?
106
158
  raise RecordInvalid, response.msg if response.invalid_data?
107
159
  raise InvalidModule, response.msg if response.invalid_module?
108
160
  raise NoPermission, response.msg if response.no_permission?
@@ -116,8 +168,9 @@ module ZohoHub
116
168
  def initialize(params = {})
117
169
  attributes.each do |attr|
118
170
  zoho_key = attr_to_zoho_key(attr)
171
+ value = params[zoho_key].nil? ? params[attr] : params[zoho_key]
119
172
 
120
- send("#{attr}=", params[zoho_key] || params[attr])
173
+ send("#{attr}=", value)
121
174
  end
122
175
  end
123
176
 
@@ -134,14 +187,21 @@ module ZohoHub
134
187
  end
135
188
 
136
189
  def update(params)
137
- zoho_params = Hash[params.map { |k, v| [attr_to_zoho_key(k), v] }]
190
+ zoho_params = params.transform_keys { |key| attr_to_zoho_key(key) }
138
191
  body = put(File.join(self.class.request_path, id), data: [zoho_params])
192
+
139
193
  build_response(body)
140
194
  end
141
195
 
142
196
  def blueprint_transition(transition_id, data = {})
143
197
  body = put(File.join(self.class.request_path, id, 'actions/blueprint'),
144
198
  blueprint: [{ transition_id: transition_id, data: data }])
199
+
200
+ build_response(body)
201
+ end
202
+
203
+ def blueprint_transitions
204
+ body = get(File.join(self.class.request_path, id, 'actions/blueprint'))
145
205
  build_response(body)
146
206
  end
147
207
 
@@ -62,7 +62,7 @@ module ZohoHub
62
62
  url = ZohoHub::Auth.auth_url
63
63
  Launchy.open(url)
64
64
 
65
- puts "Running callback server...."
65
+ puts 'Running callback server....'
66
66
  ZohoHub::OauthCallbackServer.run!
67
67
  end
68
68
 
@@ -79,13 +79,13 @@ module ZohoHub
79
79
  def parse(argv, _env)
80
80
  parser.parse!(argv)
81
81
  true
82
- rescue OptionParser::ParseError => error
83
- error_output(error)
82
+ rescue OptionParser::ParseError => e
83
+ error_output(e)
84
84
  end
85
85
 
86
86
  def error_output(error)
87
- $stderr.puts "Error: #{error}"
88
- $stderr.puts "Try `#{parser.program_name} server --help' for more information"
87
+ warn "Error: #{error}"
88
+ warn "Try `#{parser.program_name} server --help' for more information"
89
89
 
90
90
  false
91
91
  end
@@ -107,13 +107,13 @@ module ZohoHub
107
107
  def parse(argv, _env)
108
108
  parser.parse!(argv)
109
109
  true
110
- rescue OptionParser::ParseError => error
111
- error_output(error)
110
+ rescue OptionParser::ParseError => e
111
+ error_output(e)
112
112
  end
113
113
 
114
114
  def error_output(error)
115
- $stderr.puts "Error: #{error}"
116
- $stderr.puts "Try `#{parser.program_name} server --help' for more information"
115
+ warn "Error: #{error}"
116
+ warn "Try `#{parser.program_name} server --help' for more information"
117
117
 
118
118
  false
119
119
  end
@@ -31,7 +31,7 @@ module ZohoHub
31
31
 
32
32
  BASE_PATH = '/crm/v2/'
33
33
 
34
- def initialize(access_token:, api_domain: nil, expires_in: 3600, refresh_token: nil)
34
+ def initialize(access_token: nil, api_domain: nil, expires_in: 3600, refresh_token: nil)
35
35
  @access_token = access_token
36
36
  @expires_in = expires_in
37
37
  @api_domain = api_domain || self.class.infer_api_domain
@@ -88,7 +88,7 @@ module ZohoHub
88
88
  response = Response.new(http_response.body)
89
89
 
90
90
  # Try to refresh the token and try again
91
- if response.invalid_token? && refresh_token?
91
+ if (response.invalid_token? || response.authentication_failure?) && refresh_token?
92
92
  log "Refreshing outdated token... #{@access_token}"
93
93
  params = ZohoHub::Auth.refresh_token(@refresh_token)
94
94
 
@@ -116,6 +116,7 @@ module ZohoHub
116
116
  def adapter
117
117
  Faraday.new(url: base_url) do |conn|
118
118
  conn.headers = authorization_header if access_token?
119
+ conn.use FaradayMiddleware::EncodeJson
119
120
  conn.use FaradayMiddleware::ParseJson
120
121
  conn.response :json, parser_options: { symbolize_names: true }
121
122
  conn.response :logger if ZohoHub.configuration.debug?
@@ -10,6 +10,9 @@ module ZohoHub
10
10
  class InvalidTokenError < StandardError
11
11
  end
12
12
 
13
+ class InternalError < StandardError
14
+ end
15
+
13
16
  class InvalidModule < StandardError
14
17
  end
15
18
 
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zoho_hub/base_record'
4
+
5
+ module ZohoHub
6
+ class BaseRecord
7
+ class << self
8
+ def related_attachments(parent_id:)
9
+ body = get(File.join(request_path, parent_id, 'Attachments'))
10
+ response = build_response(body)
11
+
12
+ data = response.nil? ? [] : response.data
13
+
14
+ data.map { |json| Attachment.new(json) }
15
+ end
16
+
17
+ def download_attachment(parent_id:, attachment_id:)
18
+ attachment = related_attachments(parent_id: parent_id).find { |a| a.id == attachment_id }
19
+ uri = File.join(request_path, parent_id, 'Attachments', attachment_id)
20
+ res = ZohoHub.connection.adapter.get(uri)
21
+ attachment.content_type = res.headers['content-type']
22
+ extension = File.extname(attachment.file_name)
23
+ basename = File.basename(attachment.file_name, extension)
24
+ file = Tempfile.new([basename, extension])
25
+ file.binmode
26
+ file.write(res.body)
27
+ file.rewind
28
+ attachment.file = file
29
+ attachment
30
+ end
31
+ end
32
+ end
33
+
34
+ class Attachment < BaseRecord
35
+ attributes :id, :file_name, :created_by, :modified_by, :owner, :parent_id, :created_time,
36
+ :modified_time, :size
37
+
38
+ attribute_translation id: :id
39
+ attr_accessor :content_type, :file
40
+ end
41
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zoho_hub/response'
4
+ require 'zoho_hub/with_connection'
5
+
6
+ module ZohoHub
7
+ class Notifications
8
+ include WithConnection
9
+
10
+ # Default number of records when fetching all.
11
+ DEFAULT_RECORDS_PER_PAGE = 200
12
+
13
+ # Default page number when fetching all.
14
+ DEFAULT_PAGE = 1
15
+
16
+ # Minimum number of records to fetch when fetching all.
17
+ MIN_RECORDS = 2
18
+
19
+ class << self
20
+ def request_path
21
+ @request_path = 'actions/watch'
22
+ end
23
+
24
+ def all(params = {})
25
+ params[:page] ||= DEFAULT_PAGE
26
+ params[:per_page] ||= DEFAULT_RECORDS_PER_PAGE
27
+ params[:per_page] = MIN_RECORDS if params[:per_page] < MIN_RECORDS
28
+
29
+ body = get(request_path, params)
30
+ return [] if body.nil?
31
+
32
+ build_response(body)
33
+ end
34
+
35
+ def enable(notify_url, channel_id, events, channel_expiry = nil, token = nil)
36
+ body = post(request_path, watch: [{ notify_url: notify_url,
37
+ channel_id: channel_id,
38
+ events: events,
39
+ channel_expiry: channel_expiry,
40
+ token: token }])
41
+ build_response(body)
42
+ end
43
+
44
+ def build_response(body)
45
+ response = Response.new(body)
46
+
47
+ raise RecordInvalid, response.msg if response.invalid_data?
48
+ raise MandatoryNotFound, response.msg if response.mandatory_not_found?
49
+
50
+ response.data
51
+ end
52
+ end
53
+ end
54
+ end
@@ -14,6 +14,10 @@ module ZohoHub
14
14
  error_code?('INVALID_TOKEN')
15
15
  end
16
16
 
17
+ def internal_error?
18
+ error_code?('INTERNAL_ERROR')
19
+ end
20
+
17
21
  def authentication_failure?
18
22
  error_code?('AUTHENTICATION_FAILURE')
19
23
  end
@@ -39,7 +43,7 @@ module ZohoHub
39
43
  end
40
44
 
41
45
  def data
42
- data = @params[:data] if @params.dig(:data)
46
+ data = @params[:data] if @params[:data]
43
47
  data || @params
44
48
  end
45
49
 
@@ -59,12 +63,13 @@ module ZohoHub
59
63
  msg
60
64
  end
61
65
 
62
- # error response examples:
63
- # {"data":[{"code":"INVALID_DATA","details":{},"message":"the id given seems to be invalid","status":"error"}]}
66
+ # Error response examples:
67
+ # {"data":[{"code":"INVALID_DATA","details":{},"message":"the id given...","status":"error"}]}
64
68
  # {:code=>"INVALID_TOKEN", :details=>{}, :message=>"invalid oauth token", :status=>"error"}
65
69
  def error_code?(code)
66
70
  if data.is_a?(Array)
67
71
  return false if data.size > 1
72
+
68
73
  return data.first[:code] == code
69
74
  end
70
75
 
@@ -8,7 +8,7 @@ module ZohoHub
8
8
  end
9
9
 
10
10
  def pluralize(text)
11
- if ENV.key?('RAILS_ENV')
11
+ if defined?(ActiveSupport::Inflector)
12
12
  ActiveSupport::Inflector.pluralize(text)
13
13
  else
14
14
  "#{text}s"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ZohoHub
4
- VERSION = '0.4.0'
4
+ VERSION = '0.4.1'
5
5
  end
@@ -44,8 +44,11 @@ module ZohoHub
44
44
  end
45
45
 
46
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
47
+ if attribute_translation.key?(attr_name.to_sym)
48
+ return attribute_translation[attr_name.to_sym]
49
+ end
50
+
51
+ attr_name.to_s.split('_').map(&:capitalize).join('_').to_sym
49
52
  end
50
53
 
51
54
  def zoho_key_translation
@@ -62,11 +65,12 @@ module ZohoHub
62
65
  # github.com/rails/rails/blob/master/activemodel/lib/active_model/attribute_assignment.rb
63
66
  def assign_attributes(new_attributes)
64
67
  unless new_attributes.is_a?(Hash)
65
- raise ArgumentError, "When assigning attributes, you must pass a hash as an argument"
68
+ raise ArgumentError, 'When assigning attributes, you must pass a hash as an argument'
66
69
  end
70
+
67
71
  return if new_attributes.empty?
68
72
 
69
- attributes = Hash[new_attributes.map { |k, v| [k.to_s, v] }]
73
+ attributes = new_attributes.transform_keys(&:to_s)
70
74
  attributes.each do |k, v|
71
75
  assign_attribute(k, v)
72
76
  end
@@ -86,13 +90,12 @@ module ZohoHub
86
90
  zoho_key.to_sym
87
91
  end
88
92
 
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
93
+ def assign_attribute(key, value)
94
+ setter = :"#{key}="
95
+
96
+ return public_send(setter, value) if respond_to?(setter)
97
+
98
+ raise ArgumentError, "Unknown attribute #{key}"
96
99
  end
97
100
  end
98
101
  end
@@ -13,11 +13,11 @@ module ZohoHub
13
13
  end
14
14
 
15
15
  def post(path, params = {})
16
- ZohoHub.connection.post(path, params.to_json)
16
+ ZohoHub.connection.post(path, params)
17
17
  end
18
18
 
19
19
  def put(path, params = {})
20
- ZohoHub.connection.put(path, params.to_json)
20
+ ZohoHub.connection.put(path, params)
21
21
  end
22
22
 
23
23
  def delete(path, params = {})
data/zoho_hub.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.required_ruby_version = '>= 2.1.0'
27
27
 
28
28
  spec.add_dependency 'addressable'
29
- spec.add_dependency 'backports' if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3.0')
29
+ spec.add_dependency 'backports'
30
30
  spec.add_dependency 'faraday'
31
31
  spec.add_dependency 'faraday_middleware'
32
32
  spec.add_dependency 'launchy'
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.add_dependency 'rainbow'
35
35
  spec.add_dependency 'sinatra'
36
36
 
37
+ spec.add_development_dependency 'activesupport'
37
38
  spec.add_development_dependency 'bundler'
38
39
  spec.add_development_dependency 'dotenv'
39
40
  spec.add_development_dependency 'pry-byebug'
@@ -42,4 +43,5 @@ Gem::Specification.new do |spec|
42
43
  spec.add_development_dependency 'rubocop'
43
44
  spec.add_development_dependency 'rubocop-rspec'
44
45
  spec.add_development_dependency 'simplecov'
46
+ spec.add_development_dependency 'webmock'
45
47
  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.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ricardo Otero
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-18 00:00:00.000000000 Z
11
+ date: 2021-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: backports
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: faraday
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +122,20 @@ dependencies:
108
122
  - - ">="
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: activesupport
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
111
139
  - !ruby/object:Gem::Dependency
112
140
  name: bundler
113
141
  requirement: !ruby/object:Gem::Requirement
@@ -220,6 +248,20 @@ dependencies:
220
248
  - - ">="
221
249
  - !ruby/object:Gem::Version
222
250
  version: '0'
251
+ - !ruby/object:Gem::Dependency
252
+ name: webmock
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - ">="
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
223
265
  description: Simple gem to connect to Zoho CRM API V2
224
266
  email:
225
267
  - oterosantos@gmail.com
@@ -228,11 +270,11 @@ executables:
228
270
  extensions: []
229
271
  extra_rdoc_files: []
230
272
  files:
273
+ - ".github/workflows/ci.yml"
231
274
  - ".gitignore"
232
275
  - ".rspec"
233
276
  - ".rubocop.yml"
234
277
  - ".ruby-version"
235
- - ".travis.yml"
236
278
  - Gemfile
237
279
  - LICENSE.txt
238
280
  - README.md
@@ -253,6 +295,8 @@ files:
253
295
  - lib/zoho_hub/configuration.rb
254
296
  - lib/zoho_hub/connection.rb
255
297
  - lib/zoho_hub/errors.rb
298
+ - lib/zoho_hub/modules/attachment.rb
299
+ - lib/zoho_hub/notifications.rb
256
300
  - lib/zoho_hub/oauth_callback_server.rb
257
301
  - lib/zoho_hub/reflection/module_builder.rb
258
302
  - lib/zoho_hub/response.rb
@@ -272,7 +316,7 @@ homepage: https://github.com/rikas/zoho_hub
272
316
  licenses:
273
317
  - MIT
274
318
  metadata: {}
275
- post_install_message:
319
+ post_install_message:
276
320
  rdoc_options: []
277
321
  require_paths:
278
322
  - lib
@@ -287,9 +331,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
287
331
  - !ruby/object:Gem::Version
288
332
  version: '0'
289
333
  requirements: []
290
- rubyforge_project:
291
- rubygems_version: 2.7.6
292
- signing_key:
334
+ rubyforge_project:
335
+ rubygems_version: 2.7.6.2
336
+ signing_key:
293
337
  specification_version: 4
294
338
  summary: Simple gem to connect to Zoho CRM API V2
295
339
  test_files: []
data/.travis.yml DELETED
@@ -1,8 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.1.10
5
- - 2.2.10
6
- - 2.3.7
7
- - 2.4.4
8
- - 2.5.3