active_call-zoho_sign 0.1.5 → 0.1.6

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: ba562fec7bae27b72ad781e923c0b1db6f0076568a170769ed9490dd0927ca9d
4
- data.tar.gz: a2e7dc48e0a7b6cf7774e23a5b93be6026bf7c58b695598a79bd570a5a3e84a0
3
+ metadata.gz: d081ad9bfcfa500488f91ef33523321354c2e92125798dabf903b73455a36969
4
+ data.tar.gz: c1e116320af36f5a82b2c5fc438accc3417246c073957544e49ce31aa40baa1e
5
5
  SHA512:
6
- metadata.gz: 309cf5cdb4c67fbb25e470000a3a81dd21c19209018ecd8e206a8be79ef396537bd5e835e928a0e39ed454bf92327ad9f44c5e77c07279b71ea752d408245a7f
7
- data.tar.gz: ea0fd98f0da44b1c564a7f743187f71e3691cd820d8485700e6f21502bc5c9d308d9dcfe68e1e8ed0f2b75a27bffb3b7cafdeb7cfc7530389e656cb4d9105bfc
6
+ metadata.gz: 61d2c71ceb5d3cd761adf9bcba5c6b82c32df65de03059be03c53cf0b77756e591347cb93399ff01d0ef0cbef049aafd7dd5dbbf8cab204c6cad6ba823c404dc
7
+ data.tar.gz: 303712d85e4e32f67f060d0bfcffde7673d10f2c01f8b8e4f9890655097417b0bb53ef02ec75b79702049e0c9daf249ed2ecf7fdb9379418a0ae3756952dccfb
data/.rubocop.yml CHANGED
@@ -45,7 +45,7 @@ Metrics/MethodLength:
45
45
 
46
46
  Metrics/PerceivedComplexity:
47
47
  Exclude:
48
- - lib/zoho_sign/document/list_service.rb
48
+ - lib/zoho_sign/concerns/enumerable.rb
49
49
 
50
50
  Naming/FileName:
51
51
  Exclude:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [0.1.5] - 2025-04-05
2
+
3
+ - Added `ZohoSign::GrantToken::GetService`.
4
+ - Set access token in `before_call` hook instead of lambda so we can capture errors from the access token service objects.
5
+ - Fixed empty list enumerable errors.
6
+ - Remove spec dependencies already included in `active_call-api`.
7
+
1
8
  ## [0.1.5] - 2025-04-03
2
9
 
3
10
  - Refactor list endpoints to use `ZohoSign::Enumerable`.
data/README.md CHANGED
@@ -11,9 +11,7 @@ Zoho Sign exposes the [Zoho Sign API](https://www.zoho.com/sign/api) endpoints t
11
11
  - [Using call!](#using-call!)
12
12
  - [When to use call or call!](#using-call-or-call!)
13
13
  - [Using lists](#using-lists)
14
- - [Documents](#documents)
15
- - [Folders](#folders)
16
- - [Templates](#templates)
14
+ - [Service Objects](#service-objects)
17
15
  - [Development](#development)
18
16
  - [Contributing](#contributing)
19
17
  - [License](#license)
@@ -34,6 +32,12 @@ gem install active_call-zoho_sign
34
32
 
35
33
  ## Configuration
36
34
 
35
+ Create a new **Self Client** client type from the [Zoho Developer Console](https://api-console.zoho.com) to retrieve your **Client ID** and **Client Secret**.
36
+
37
+ Choose what you need from the list of [Zoho Scopes](https://www.zoho.com/sign/api/oauth.html) like `ZohoSign.documents.ALL` to generate your **Grant Token**.
38
+
39
+ Get your **Refresh Token** by calling `ZohoSign::GrantToken::GetService.call(grant_token: '', client_id: '', client_secret: '').refresh_token`
40
+
37
41
  Configure your API credentials.
38
42
 
39
43
  In a Rails application, the standard practice is to place this code in a file named `zoho_sign.rb` within the `config/initializers` directory.
@@ -173,7 +177,7 @@ rescue ZohoSign::RequestError => exception
173
177
  An example of where to use `call` would be in a **controller** doing an inline synchronous request.
174
178
 
175
179
  ```ruby
176
- class DocumentController < ApplicationController
180
+ class SomeController < ApplicationController
177
181
  def update
178
182
  @document = ZohoSign::Document::UpdateService.call(**params)
179
183
 
@@ -192,7 +196,7 @@ An example of where to use `call!` would be in a **job** doing an asynchronous r
192
196
  You can use the exceptions to determine which retry strategy to use and which to discard.
193
197
 
194
198
  ```ruby
195
- class DocumentJob < ApplicationJob
199
+ class SomeJob < ApplicationJob
196
200
  discard_on ZohoSign::NotFoundError
197
201
 
198
202
  retry_on ZohoSign::RequestTimeoutError, wait: 5.minutes, attempts: :unlimited
@@ -210,6 +214,11 @@ If you don't provide the `limit` argument, multiple API requests will be made un
210
214
 
211
215
  Note that the `offset` argument starts at `1` for the first item.
212
216
 
217
+ ## Service Objects
218
+
219
+ <details open>
220
+ <summary>Documents</summary>
221
+
213
222
  ### Documents
214
223
 
215
224
  #### List documents
@@ -306,24 +315,44 @@ service = ZohoSign::Document::Action::EmbedToken::GetService.call(request_id: ''
306
315
  service.sign_url
307
316
  ```
308
317
 
318
+ </details>
319
+
320
+ <details>
321
+ <summary>Folders</summary>
322
+
309
323
  ### Folders
310
324
 
311
325
  TODO: ...
312
326
 
327
+ </details>
328
+
329
+ <details>
330
+ <summary>Field Types</summary>
331
+
313
332
  ### Field Types
314
333
 
315
334
  TODO: ...
316
335
 
336
+ </details>
337
+
338
+ <details>
339
+ <summary>Request Types</summary>
340
+
317
341
  ### Request Types
318
342
 
319
343
  TODO: ...
320
344
 
345
+ </details>
346
+
347
+ <details>
348
+ <summary>Templates</summary>
349
+
321
350
  ### Templates
322
351
 
323
352
  #### List templates
324
353
 
325
354
  ```ruby
326
- service = ZohoSign::Template::ListService.call(offset: 1, limit: 10).each do |facade|
355
+ ZohoSign::Template::ListService.call(offset: 1, limit: 10).each do |facade|
327
356
  facade.description
328
357
  end
329
358
  ```
@@ -406,6 +435,8 @@ service = ZohoSign::Template::Document::CreateService.call!(
406
435
  )
407
436
  ```
408
437
 
438
+ </details>
439
+
409
440
  ## Development
410
441
 
411
442
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ZohoSign::AccessToken::GetService < ZohoSign::BaseService
4
+ skip_callback :call, :before, :set_access_token
5
+
4
6
  after_call :set_facade
5
7
 
6
8
  delegate_missing_to :@facade
@@ -38,7 +40,6 @@ class ZohoSign::AccessToken::GetService < ZohoSign::BaseService
38
40
  client_id: client_id,
39
41
  client_secret: client_secret,
40
42
  refresh_token: refresh_token,
41
- redirect_uri: 'https://sign.zoho.com',
42
43
  grant_type: 'refresh_token'
43
44
  }
44
45
  end
@@ -15,7 +15,15 @@ class ZohoSign::BaseService < ActiveCall::Base
15
15
  config_accessor :log_bodies, default: false, instance_writer: false
16
16
  config_accessor :client_id, :client_secret, :refresh_token, instance_writer: false
17
17
 
18
- attr_reader :facade
18
+ attr_reader :access_token, :facade
19
+
20
+ before_call :set_access_token
21
+
22
+ validate on: :request do
23
+ next if is_a?(ZohoSign::AccessToken::GetService)
24
+
25
+ errors.merge!(access_token_service.errors) if access_token.nil? && !access_token_service.success?
26
+ end
19
27
 
20
28
  class << self
21
29
  def exception_mapping
@@ -32,6 +40,7 @@ class ZohoSign::BaseService < ActiveCall::Base
32
40
  proxy_authentication_required: ZohoSign::ProxyAuthenticationRequiredError,
33
41
  request_timeout: ZohoSign::RequestTimeoutError,
34
42
  conflict: ZohoSign::ConflictError,
43
+ gone: ZohoSign::GoneError,
35
44
  unprocessable_entity: ZohoSign::UnprocessableEntityError,
36
45
  too_many_requests: ZohoSign::TooManyRequestsError,
37
46
  internal_server_error: ZohoSign::InternalServerError,
@@ -48,7 +57,7 @@ class ZohoSign::BaseService < ActiveCall::Base
48
57
  def connection
49
58
  @_connection ||= Faraday.new do |conn|
50
59
  conn.url_prefix = base_url
51
- conn.request :authorization, 'Zoho-oauthtoken', -> { access_token }
60
+ conn.request :authorization, 'Zoho-oauthtoken', access_token
52
61
  conn.request :multipart
53
62
  conn.request :url_encoded
54
63
  conn.request :retry
@@ -69,12 +78,18 @@ class ZohoSign::BaseService < ActiveCall::Base
69
78
  }
70
79
  end
71
80
 
72
- def access_token
73
- access_token = ENV['ZOHO_SIGN_ACCESS_TOKEN'].presence || cache.read(CACHE_KEY[:access_token])
74
- return access_token if access_token.present?
81
+ def set_access_token
82
+ @access_token = ENV['ZOHO_SIGN_ACCESS_TOKEN'].presence || cache.read(CACHE_KEY[:access_token])
83
+ return if @access_token.present?
84
+ return unless access_token_service.success?
85
+
86
+ @access_token = cache.fetch(CACHE_KEY[:access_token], expires_in: [access_token_service.expires_in - 10, 0].max) do
87
+ access_token_service.facade.access_token
88
+ end
89
+ end
75
90
 
76
- service = ZohoSign::AccessToken::GetService.call
77
- cache.fetch(CACHE_KEY[:access_token], expires_in: [service.expires_in - 10, 0].max) { service.facade.access_token }
91
+ def access_token_service
92
+ @_access_token_service ||= ZohoSign::AccessToken::GetService.call
78
93
  end
79
94
 
80
95
  def forbidden?
@@ -6,13 +6,13 @@ module ZohoSign::Enumerable
6
6
  included do
7
7
  include Enumerable
8
8
 
9
- attr_reader :path, :list_key, :facade_klass, :limit, :offset
9
+ attr_reader :path, :list_key, :facade_klass, :offset, :limit
10
10
 
11
11
  validates :path, :list_key, :facade_klass, presence: true
12
12
  validates :limit, presence: true, numericality: { greater_than_or_equal_to: 1 }
13
13
  end
14
14
 
15
- def initialize(path:, list_key:, facade_klass:, limit: Float::INFINITY, offset: 1)
15
+ def initialize(path:, list_key:, facade_klass:, offset: 1, limit: Float::INFINITY)
16
16
  @path = path
17
17
  @list_key = list_key
18
18
  @facade_klass = facade_klass
@@ -41,6 +41,8 @@ module ZohoSign::Enumerable
41
41
  throw :list_end
42
42
  end
43
43
 
44
+ throw :list_end unless response.body
45
+
44
46
  response.body[list_key].each do |hash|
45
47
  yield facade_klass.new(hash)
46
48
  total += 1
@@ -47,7 +47,7 @@ class ZohoSign::Document::ListService < ZohoSign::BaseService
47
47
  # and `created_time`.
48
48
  #
49
49
  # GET /api/v1/requests
50
- def initialize(limit: Float::INFINITY, offset: 1, sort_column: 'created_time', sort_order: 'DESC', search_columns: {})
50
+ def initialize(offset: 1, limit: Float::INFINITY, sort_column: 'created_time', sort_order: 'DESC', search_columns: {})
51
51
  @sort_column = sort_column
52
52
  @sort_order = sort_order
53
53
  @search_columns = search_columns
@@ -38,6 +38,9 @@ module ZohoSign
38
38
  # 409
39
39
  class ConflictError < ClientError; end
40
40
 
41
+ # 410
42
+ class GoneError < ClientError; end
43
+
41
44
  # 422
42
45
  class UnprocessableEntityError < ClientError; end
43
46
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ZohoSign::GrantToken::Facade
4
+ attr_reader :access_token, :refresh_token, :scope, :api_domain, :expires_in, :token_type
5
+
6
+ def initialize(hash)
7
+ @access_token = hash['access_token']
8
+ @api_domain = hash['api_domain']
9
+ @expires_in = hash['expires_in']
10
+ @refresh_token = hash['refresh_token']
11
+ @scope = hash['scope']
12
+ @token_type = hash['token_type']
13
+ end
14
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ZohoSign::GrantToken::GetService < ZohoSign::BaseService
4
+ attr_reader :grant_token, :client_id, :client_secret
5
+
6
+ after_call :set_facade
7
+
8
+ delegate_missing_to :@facade
9
+ delegate :refresh_token, to: :@facade, allow_nil: true
10
+
11
+ validates :grant_token, presence: true
12
+
13
+ def initialize(grant_token:, client_id: nil, client_secret: nil)
14
+ @grant_token = grant_token
15
+ @client_id = client_id.presence || ZohoSign::BaseService.client_id
16
+ @client_secret = client_secret.presence || ZohoSign::BaseService.client_secret
17
+ end
18
+
19
+ # Get refresh token from grant token.
20
+ #
21
+ # ==== Examples
22
+ #
23
+ # service = ZohoSign::GrantToken::GetService.call(grant_token: '', client_id: '', client_secret: '')
24
+ # service.refresh_token # => '1000.xxxx.yyyy'
25
+ # service.expires_in # => 3600
26
+ #
27
+ # POST /oauth/v2/token
28
+ def call
29
+ connection.post('oauth/v2/token', params.to_param)
30
+ end
31
+
32
+ private
33
+
34
+ def connection
35
+ @_connection ||= Faraday.new do |conn|
36
+ conn.url_prefix = 'https://accounts.zoho.com'
37
+ conn.request :retry
38
+ conn.response :json
39
+ conn.response :logger, logger, **logger_options do |logger|
40
+ logger.filter(/(code|client_id|client_secret)=([^&]+)/i, '\1=[FILTERED]')
41
+ logger.filter(/"access_token":"([^"]+)"/i, '"access_token":"[FILTERED]"')
42
+ logger.filter(/"refresh_token":"([^"]+)"/i, '"refresh_token":"[FILTERED]"')
43
+ end
44
+ conn.adapter Faraday.default_adapter
45
+ end
46
+ end
47
+
48
+ def params
49
+ {
50
+ client_id: client_id,
51
+ client_secret: client_secret,
52
+ code: grant_token,
53
+ grant_type: 'authorization_code'
54
+ }
55
+ end
56
+
57
+ def unauthorized?
58
+ response.status == 200 && response.body.key?('error')
59
+ end
60
+
61
+ def set_facade
62
+ @facade = ZohoCrm::GrantToken::Facade.new(response.body)
63
+ end
64
+ end
@@ -46,7 +46,7 @@ class ZohoSign::Template::ListService < ZohoSign::BaseService
46
46
  # Columns to sort and filter by are `template_name`, `owner_first_name` and `modified_time`.
47
47
  #
48
48
  # GET /api/v1/templates
49
- def initialize(limit: Float::INFINITY, offset: 1, sort_column: 'template_name', sort_order: 'DESC', search_columns: {})
49
+ def initialize(offset: 1, limit: Float::INFINITY, sort_column: 'template_name', sort_order: 'DESC', search_columns: {})
50
50
  @sort_column = sort_column
51
51
  @sort_order = sort_order
52
52
  @search_columns = search_columns
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ZohoSign
4
- VERSION = '0.1.5'
4
+ VERSION = '0.1.6'
5
5
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_call-zoho_sign
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kobus Joubert
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-04-03 00:00:00.000000000 Z
11
+ date: 2025-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: active_call
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '0.2'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '0.2'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: active_call-api
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -38,34 +24,6 @@ dependencies:
38
24
  - - "~>"
39
25
  - !ruby/object:Gem::Version
40
26
  version: '0.1'
41
- - !ruby/object:Gem::Dependency
42
- name: faraday
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '2.0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '2.0'
55
- - !ruby/object:Gem::Dependency
56
- name: faraday-retry
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '2.0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '2.0'
69
27
  - !ruby/object:Gem::Dependency
70
28
  name: faraday-multipart
71
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,20 +38,6 @@ dependencies:
80
38
  - - "~>"
81
39
  - !ruby/object:Gem::Version
82
40
  version: '1.1'
83
- - !ruby/object:Gem::Dependency
84
- name: faraday-logging-color_formatter
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '0.2'
90
- type: :runtime
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '0.2'
97
41
  description: Zoho Sign exposes the Zoho Sign API endpoints through service objects.
98
42
  email:
99
43
  - kobus@translate3d.com
@@ -124,6 +68,8 @@ files:
124
68
  - lib/zoho_sign/document/list_service.rb
125
69
  - lib/zoho_sign/document/update_service.rb
126
70
  - lib/zoho_sign/error.rb
71
+ - lib/zoho_sign/grant_token/facade.rb
72
+ - lib/zoho_sign/grant_token/get_service.rb
127
73
  - lib/zoho_sign/template/document/create_service.rb
128
74
  - lib/zoho_sign/template/document/facade.rb
129
75
  - lib/zoho_sign/template/facade.rb