assinafy 1.5.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 +7 -0
- data/CHANGELOG.md +168 -0
- data/LICENSE +19 -0
- data/README.md +463 -0
- data/lib/assinafy/client.rb +245 -0
- data/lib/assinafy/configuration.rb +157 -0
- data/lib/assinafy/errors.rb +83 -0
- data/lib/assinafy/null_logger.rb +9 -0
- data/lib/assinafy/resources/account_resource.rb +267 -0
- data/lib/assinafy/resources/assignment_resource.rb +476 -0
- data/lib/assinafy/resources/auth_resource.rb +251 -0
- data/lib/assinafy/resources/base_resource.rb +250 -0
- data/lib/assinafy/resources/document_resource.rb +912 -0
- data/lib/assinafy/resources/field_resource.rb +274 -0
- data/lib/assinafy/resources/signer_document_resource.rb +222 -0
- data/lib/assinafy/resources/signer_resource.rb +422 -0
- data/lib/assinafy/resources/tag_resource.rb +183 -0
- data/lib/assinafy/resources/template_resource.rb +215 -0
- data/lib/assinafy/resources/user_resource.rb +182 -0
- data/lib/assinafy/resources/webhook_resource.rb +222 -0
- data/lib/assinafy/support/webhook_verifier.rb +129 -0
- data/lib/assinafy/utils.rb +122 -0
- data/lib/assinafy/version.rb +5 -0
- data/lib/assinafy.rb +25 -0
- metadata +195 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Assinafy
|
|
4
|
+
module Resources
|
|
5
|
+
# Accounts (workspaces): CRUD plus the per-account theme, KPI stats, and
|
|
6
|
+
# brand logo (upload/download/delete).
|
|
7
|
+
#
|
|
8
|
+
# See https://api.assinafy.com.br/v1/docs for the Account Object and its
|
|
9
|
+
# related endpoints.
|
|
10
|
+
class AccountResource < BaseResource
|
|
11
|
+
# List the accounts (workspaces) the authenticated user can access.
|
|
12
|
+
#
|
|
13
|
+
# @return [Hash{Symbol=>Array,nil}] `{ data: [Account, ...], meta: nil }`
|
|
14
|
+
# (this endpoint sends no pagination headers)
|
|
15
|
+
# @see GET /accounts
|
|
16
|
+
# @example List my accounts
|
|
17
|
+
# # Request: GET /accounts
|
|
18
|
+
# client.accounts.list
|
|
19
|
+
#
|
|
20
|
+
# # Response (unwrapped data payload):
|
|
21
|
+
# {
|
|
22
|
+
# data: [
|
|
23
|
+
# {
|
|
24
|
+
# 'id' => 'account-id',
|
|
25
|
+
# 'name' => 'MT',
|
|
26
|
+
# 'roles' => ['owner'],
|
|
27
|
+
# 'is_delete_allowed' => true,
|
|
28
|
+
# 'created_at' => '2026-05-12T18:05:11Z'
|
|
29
|
+
# }
|
|
30
|
+
# # ... (one Hash per accessible account)
|
|
31
|
+
# ],
|
|
32
|
+
# meta: nil
|
|
33
|
+
# }
|
|
34
|
+
def list
|
|
35
|
+
call_list('Failed to list accounts') do
|
|
36
|
+
http_get('accounts')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Create a new account (workspace).
|
|
41
|
+
#
|
|
42
|
+
# @param payload [Hash]
|
|
43
|
+
# @option payload [String] :name required display name
|
|
44
|
+
# @option payload [String] :notification_sender_type `"User"` or `"Account"`
|
|
45
|
+
# @return [Hash] the created account (envelope `data` unwrapped)
|
|
46
|
+
# @see POST /accounts
|
|
47
|
+
# @example Create an account
|
|
48
|
+
# # Request: POST /accounts
|
|
49
|
+
# # Body: { "name": "Acme Inc." }
|
|
50
|
+
# client.accounts.create(name: 'Acme Inc.')
|
|
51
|
+
#
|
|
52
|
+
# # Response (unwrapped data payload):
|
|
53
|
+
# {
|
|
54
|
+
# 'id' => 'account-id',
|
|
55
|
+
# 'name' => 'Acme Inc.',
|
|
56
|
+
# 'primary_color' => nil,
|
|
57
|
+
# 'secondary_color' => nil,
|
|
58
|
+
# 'created_at' => '2026-07-20T15:53:33Z'
|
|
59
|
+
# }
|
|
60
|
+
def create(payload)
|
|
61
|
+
body = body_params(require_payload(payload, 'Account payload'))
|
|
62
|
+
require_present(body['name'], 'name')
|
|
63
|
+
|
|
64
|
+
call('Failed to create account') do
|
|
65
|
+
http_post('accounts', body)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Fetch an account by ID (defaults to the client's account).
|
|
70
|
+
#
|
|
71
|
+
# @param account_id_override [String, nil]
|
|
72
|
+
# @return [Hash] the account (envelope `data` unwrapped)
|
|
73
|
+
# @see GET /accounts/{account_id}
|
|
74
|
+
# @example Fetch the current account
|
|
75
|
+
# # Request: GET /accounts/{account_id}
|
|
76
|
+
# client.accounts.get
|
|
77
|
+
#
|
|
78
|
+
# # Response (unwrapped data payload):
|
|
79
|
+
# {
|
|
80
|
+
# 'id' => 'account-id',
|
|
81
|
+
# 'name' => 'MT',
|
|
82
|
+
# 'primary_color' => nil,
|
|
83
|
+
# 'secondary_color' => nil,
|
|
84
|
+
# 'created_at' => '2026-05-12T18:05:11Z'
|
|
85
|
+
# }
|
|
86
|
+
def get(account_id_override = nil)
|
|
87
|
+
acc_id = account_id(account_id_override)
|
|
88
|
+
|
|
89
|
+
call('Failed to fetch account') do
|
|
90
|
+
http_get("accounts/#{acc_id}")
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Update an account.
|
|
95
|
+
#
|
|
96
|
+
# @param payload [Hash] `name` and/or `notification_sender_type`
|
|
97
|
+
# @param account_id_override [String, nil]
|
|
98
|
+
# @return [Hash] the updated account (envelope `data` unwrapped)
|
|
99
|
+
# @see PUT /accounts/{account_id}
|
|
100
|
+
# @example Rename the current account
|
|
101
|
+
# # Request: PUT /accounts/{account_id}
|
|
102
|
+
# # Body: { "name": "Acme Renamed" }
|
|
103
|
+
# client.accounts.update(name: 'Acme Renamed')
|
|
104
|
+
#
|
|
105
|
+
# # Response (unwrapped data payload):
|
|
106
|
+
# {
|
|
107
|
+
# 'id' => 'account-id',
|
|
108
|
+
# 'name' => 'Acme Renamed',
|
|
109
|
+
# 'primary_color' => nil,
|
|
110
|
+
# 'secondary_color' => nil,
|
|
111
|
+
# 'created_at' => '2026-07-20T15:53:33Z'
|
|
112
|
+
# }
|
|
113
|
+
def update(payload, account_id_override = nil)
|
|
114
|
+
acc_id = account_id(account_id_override)
|
|
115
|
+
body = body_params(require_payload(payload, 'Account payload'))
|
|
116
|
+
|
|
117
|
+
call('Failed to update account') do
|
|
118
|
+
http_put("accounts/#{acc_id}", body)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Delete an account. Pass `force: true` to delete an account that still
|
|
123
|
+
# owns documents.
|
|
124
|
+
#
|
|
125
|
+
# @param force [Boolean] force deletion (default false)
|
|
126
|
+
# @param account_id_override [String, nil]
|
|
127
|
+
# @return [nil] the API returns `data: []`; the SDK normalizes this to `nil`
|
|
128
|
+
# @see DELETE /accounts/{account_id}
|
|
129
|
+
# @example Force-delete a throwaway account
|
|
130
|
+
# # Request: DELETE /accounts/{account_id}
|
|
131
|
+
# # Body: { "force": true }
|
|
132
|
+
# client.accounts.delete(force: true, account_id_override: 'account-id')
|
|
133
|
+
# # => nil
|
|
134
|
+
def delete(force: false, account_id_override: nil)
|
|
135
|
+
acc_id = account_id(account_id_override)
|
|
136
|
+
force = require_boolean(force, 'force')
|
|
137
|
+
|
|
138
|
+
call_void('Failed to delete account') do
|
|
139
|
+
http_delete("accounts/#{acc_id}", body: body_params(force: force))
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Fetch the account's public theme (name, brand colors, logo URL).
|
|
144
|
+
#
|
|
145
|
+
# @param account_id_override [String, nil]
|
|
146
|
+
# @return [Hash] `{ 'account_name' =>, 'primary_color' =>, 'secondary_color' =>, 'logo' => }`
|
|
147
|
+
# @see GET /accounts/{account_id}/theme
|
|
148
|
+
# @example Fetch the account theme
|
|
149
|
+
# # Request: GET /accounts/{account_id}/theme
|
|
150
|
+
# client.accounts.theme
|
|
151
|
+
#
|
|
152
|
+
# # Response (unwrapped data payload):
|
|
153
|
+
# {
|
|
154
|
+
# 'account_name' => 'MT',
|
|
155
|
+
# 'primary_color' => '2072b9',
|
|
156
|
+
# 'secondary_color' => 'ffffff',
|
|
157
|
+
# 'logo' => nil
|
|
158
|
+
# }
|
|
159
|
+
def theme(account_id_override = nil)
|
|
160
|
+
acc_id = account_id(account_id_override)
|
|
161
|
+
|
|
162
|
+
call('Failed to fetch account theme') do
|
|
163
|
+
http_get("accounts/#{acc_id}/theme")
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Fetch per-account document KPIs.
|
|
168
|
+
#
|
|
169
|
+
# @note Documented in the API reference but not enabled on every
|
|
170
|
+
# environment — the sandbox currently returns 404 for this route.
|
|
171
|
+
# @param granularity [String, nil] `"monthly"` or `"daily"`
|
|
172
|
+
# @param month [String, nil] e.g. `"2026-06"`
|
|
173
|
+
# @param account_id_override [String, nil]
|
|
174
|
+
# @return [Array<Hash>] one KPI entry per period
|
|
175
|
+
# @see GET /accounts/{account_id}/stats
|
|
176
|
+
# @example Fetch monthly KPIs
|
|
177
|
+
# # Request: GET /accounts/{account_id}/stats?granularity=monthly&month=2026-06
|
|
178
|
+
# client.accounts.stats(granularity: 'monthly', month: '2026-06')
|
|
179
|
+
#
|
|
180
|
+
# # Response (unwrapped data payload):
|
|
181
|
+
# [
|
|
182
|
+
# {
|
|
183
|
+
# 'period' => '2026-06',
|
|
184
|
+
# 'documents_uploaded' => 42,
|
|
185
|
+
# 'documents_sent' => 37,
|
|
186
|
+
# 'signature_requests' => 61,
|
|
187
|
+
# 'signature_requests_email' => 45,
|
|
188
|
+
# 'signature_requests_whatsapp' => 16,
|
|
189
|
+
# 'signature_requests_viewed' => 58,
|
|
190
|
+
# 'signature_requests_completed' => 52,
|
|
191
|
+
# 'documents_certified' => 34
|
|
192
|
+
# }
|
|
193
|
+
# ]
|
|
194
|
+
def stats(granularity: nil, month: nil, account_id_override: nil)
|
|
195
|
+
acc_id = account_id(account_id_override)
|
|
196
|
+
|
|
197
|
+
call('Failed to fetch account stats') do
|
|
198
|
+
http_get("accounts/#{acc_id}/stats", query_params(granularity: granularity, month: month))
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Download the account brand logo as raw image bytes.
|
|
203
|
+
#
|
|
204
|
+
# @param account_id_override [String, nil]
|
|
205
|
+
# @return [String] binary image body
|
|
206
|
+
# @raise [Assinafy::ApiError] when no logo is configured (HTTP 404)
|
|
207
|
+
# @see GET /accounts/{account_id}/logo
|
|
208
|
+
# @example Download the logo and save it
|
|
209
|
+
# # Request: GET /accounts/{account_id}/logo
|
|
210
|
+
# bytes = client.accounts.download_logo
|
|
211
|
+
# File.binwrite('logo.png', bytes)
|
|
212
|
+
def download_logo(account_id_override = nil)
|
|
213
|
+
acc_id = account_id(account_id_override)
|
|
214
|
+
|
|
215
|
+
call_binary('Failed to download account logo') do
|
|
216
|
+
http_get("accounts/#{acc_id}/logo")
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Upload (replace) the account brand logo.
|
|
221
|
+
#
|
|
222
|
+
# @param source [String, Hash] a path to an image, or a Hash with
|
|
223
|
+
# `:file_path` (path) **or** `:buffer` + `:file_name` (raw bytes).
|
|
224
|
+
# @param account_id_override [String, nil]
|
|
225
|
+
# @return [nil, Hash] `nil` for the OpenAPI's no-data envelope; the current
|
|
226
|
+
# sandbox returns `{ 'mime_type' =>, 'version' =>, 'updated_at' => }`
|
|
227
|
+
# @see POST /accounts/{account_id}/logo
|
|
228
|
+
# @example Upload a PNG logo
|
|
229
|
+
# # Request: POST /accounts/{account_id}/logo (multipart/form-data)
|
|
230
|
+
# # Body: file=<binary image/png>
|
|
231
|
+
# client.accounts.upload_logo('/path/to/logo.png')
|
|
232
|
+
#
|
|
233
|
+
# # Current sandbox response (unwrapped data payload):
|
|
234
|
+
# {
|
|
235
|
+
# 'mime_type' => 'image/png',
|
|
236
|
+
# 'version' => 1784562814,
|
|
237
|
+
# 'updated_at' => '2026-07-20T15:53:35Z'
|
|
238
|
+
# }
|
|
239
|
+
# # => nil when the API returns the documented no-data envelope
|
|
240
|
+
def upload_logo(source, account_id_override = nil)
|
|
241
|
+
acc_id = account_id(account_id_override)
|
|
242
|
+
buffer, file_name = read_source(source)
|
|
243
|
+
|
|
244
|
+
call('Failed to upload account logo') do
|
|
245
|
+
http_post("accounts/#{acc_id}/logo", { file: file_part(buffer, file_name) })
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# Delete the account brand logo.
|
|
250
|
+
#
|
|
251
|
+
# @param account_id_override [String, nil]
|
|
252
|
+
# @return [nil] the documented success envelope has no `data` payload
|
|
253
|
+
# @see DELETE /accounts/{account_id}/logo
|
|
254
|
+
# @example Delete the logo
|
|
255
|
+
# # Request: DELETE /accounts/{account_id}/logo
|
|
256
|
+
# client.accounts.delete_logo
|
|
257
|
+
# # => nil
|
|
258
|
+
def delete_logo(account_id_override = nil)
|
|
259
|
+
acc_id = account_id(account_id_override)
|
|
260
|
+
|
|
261
|
+
call_void('Failed to delete account logo') do
|
|
262
|
+
http_delete("accounts/#{acc_id}/logo")
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|