zendesk_api 1.37.0 → 3.0.2
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 +4 -4
- data/lib/zendesk_api/client.rb +29 -25
- data/lib/zendesk_api/collection.rb +53 -78
- data/lib/zendesk_api/configuration.rb +3 -0
- data/lib/zendesk_api/error.rb +1 -6
- data/lib/zendesk_api/helpers.rb +4 -0
- data/lib/zendesk_api/middleware/request/encode_json.rb +0 -1
- data/lib/zendesk_api/middleware/response/callback.rb +1 -1
- data/lib/zendesk_api/middleware/response/deflate.rb +5 -4
- data/lib/zendesk_api/middleware/response/gzip.rb +5 -4
- data/lib/zendesk_api/middleware/response/parse_iso_dates.rb +1 -1
- data/lib/zendesk_api/middleware/response/parse_json.rb +1 -2
- data/lib/zendesk_api/middleware/response/sanitize_response.rb +1 -1
- data/lib/zendesk_api/pagination.rb +99 -0
- data/lib/zendesk_api/resource.rb +4 -0
- data/lib/zendesk_api/resources.rb +61 -21
- data/lib/zendesk_api/search.rb +4 -0
- data/lib/zendesk_api/verbs.rb +6 -8
- data/lib/zendesk_api/version.rb +1 -1
- data/lib/zendesk_api.rb +4 -0
- metadata +26 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bb7a7899050cd837be40995be562bb7c95a04e7d631a34cdddaa671c1eeca9b3
|
|
4
|
+
data.tar.gz: c042f01365e91e868c54e7aa5fc1318fc490efa2440093e24df86df6800feaba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: efafbaa0881befe0fd827e9fa465a3f7be19ec566199dd1640f5bba68ec101a6a0eb8b30efe850a08ca5f2adc2004ab809e74ba96eb52b3f8ac2e63f75c07e72
|
|
7
|
+
data.tar.gz: 6c81354976ef9ce6adf2f6ae084d7a60ae04fd49e10033e5025e5697a1f7adaac9385834f1c22a671e08cb94c3132d5c365a2e2a969b42f3035e301e94ed0a68
|
data/lib/zendesk_api/client.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'faraday'
|
|
2
|
-
|
|
3
1
|
require 'zendesk_api/version'
|
|
4
2
|
require 'zendesk_api/sideloading'
|
|
5
3
|
require 'zendesk_api/configuration'
|
|
@@ -26,7 +24,7 @@ module ZendeskAPI
|
|
|
26
24
|
# The top-level class that handles configuration and connection to the Zendesk API.
|
|
27
25
|
# Can also be used as an accessor to resource collections.
|
|
28
26
|
class Client
|
|
29
|
-
GZIP_EXCEPTIONS = [:em_http, :httpclient]
|
|
27
|
+
GZIP_EXCEPTIONS = [:em_http, :httpclient, :httpx]
|
|
30
28
|
|
|
31
29
|
# @return [Configuration] Config instance
|
|
32
30
|
attr_reader :config
|
|
@@ -39,24 +37,25 @@ module ZendeskAPI
|
|
|
39
37
|
def method_missing(method, *args, &block)
|
|
40
38
|
method = method.to_s
|
|
41
39
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
|
42
|
-
|
|
43
40
|
unless config.use_resource_cache
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
resource_class = resource_class_for(method)
|
|
42
|
+
raise "Resource for #{method} does not exist" unless resource_class
|
|
43
|
+
return ZendeskAPI::Collection.new(self, resource_class, options)
|
|
46
44
|
end
|
|
47
45
|
|
|
48
46
|
@resource_cache[method] ||= { :class => nil, :cache => ZendeskAPI::LRUCache.new }
|
|
49
47
|
if !options.delete(:reload) && (cached = @resource_cache[method][:cache].read(options.hash))
|
|
50
48
|
cached
|
|
51
49
|
else
|
|
52
|
-
@resource_cache[method][:class] ||=
|
|
50
|
+
@resource_cache[method][:class] ||= resource_class_for(method)
|
|
53
51
|
raise "Resource for #{method} does not exist" unless @resource_cache[method][:class]
|
|
54
52
|
@resource_cache[method][:cache].write(options.hash, ZendeskAPI::Collection.new(self, @resource_cache[method][:class], options))
|
|
55
53
|
end
|
|
56
54
|
end
|
|
57
55
|
|
|
58
56
|
def respond_to?(method, *args)
|
|
59
|
-
|
|
57
|
+
cache = @resource_cache[method]
|
|
58
|
+
!!(cache.to_h[:class] || resource_class_for(method) || super)
|
|
60
59
|
end
|
|
61
60
|
|
|
62
61
|
# Returns the current user (aka me)
|
|
@@ -100,9 +99,7 @@ module ZendeskAPI
|
|
|
100
99
|
config.retry = !!config.retry # nil -> false
|
|
101
100
|
|
|
102
101
|
set_raise_error_when_rated_limited
|
|
103
|
-
|
|
104
102
|
set_token_auth
|
|
105
|
-
|
|
106
103
|
set_default_logger
|
|
107
104
|
add_warning_callback
|
|
108
105
|
end
|
|
@@ -112,7 +109,6 @@ module ZendeskAPI
|
|
|
112
109
|
# @return [Faraday::Connection] Faraday connection for the client
|
|
113
110
|
def connection
|
|
114
111
|
@connection ||= build_connection
|
|
115
|
-
return @connection
|
|
116
112
|
end
|
|
117
113
|
|
|
118
114
|
# Pushes a callback onto the stack. Callbacks are executed on responses, last in the Faraday middleware stack.
|
|
@@ -155,7 +151,6 @@ module ZendeskAPI
|
|
|
155
151
|
builder.use ZendeskAPI::Middleware::Response::ParseIsoDates
|
|
156
152
|
builder.use ZendeskAPI::Middleware::Response::ParseJson
|
|
157
153
|
builder.use ZendeskAPI::Middleware::Response::SanitizeResponse
|
|
158
|
-
|
|
159
154
|
adapter = config.adapter || Faraday.default_adapter
|
|
160
155
|
|
|
161
156
|
unless GZIP_EXCEPTIONS.include?(adapter)
|
|
@@ -163,14 +158,7 @@ module ZendeskAPI
|
|
|
163
158
|
builder.use ZendeskAPI::Middleware::Response::Deflate
|
|
164
159
|
end
|
|
165
160
|
|
|
166
|
-
|
|
167
|
-
if config.access_token && !config.url_based_access_token
|
|
168
|
-
builder.request(:authorization, "Bearer", config.access_token)
|
|
169
|
-
elsif config.access_token
|
|
170
|
-
builder.use ZendeskAPI::Middleware::Request::UrlBasedAccessToken, config.access_token
|
|
171
|
-
else
|
|
172
|
-
builder.use Faraday::Request::BasicAuthentication, config.username, config.password
|
|
173
|
-
end
|
|
161
|
+
set_authentication(builder, config)
|
|
174
162
|
|
|
175
163
|
if config.cache
|
|
176
164
|
builder.use ZendeskAPI::Middleware::Request::EtagCache, :cache => config.cache
|
|
@@ -181,20 +169,25 @@ module ZendeskAPI
|
|
|
181
169
|
builder.use ZendeskAPI::Middleware::Request::EncodeJson
|
|
182
170
|
|
|
183
171
|
# Should always be first in the stack
|
|
184
|
-
|
|
172
|
+
if config.retry
|
|
173
|
+
builder.use ZendeskAPI::Middleware::Request::Retry,
|
|
174
|
+
:logger => config.logger,
|
|
175
|
+
:retry_codes => config.retry_codes,
|
|
176
|
+
:retry_on_exception => config.retry_on_exception
|
|
177
|
+
end
|
|
185
178
|
if config.raise_error_when_rate_limited
|
|
186
179
|
builder.use ZendeskAPI::Middleware::Request::RaiseRateLimited, :logger => config.logger
|
|
187
180
|
end
|
|
188
181
|
|
|
189
|
-
builder.adapter(*adapter)
|
|
182
|
+
builder.adapter(*adapter, &config.adapter_proc)
|
|
190
183
|
end
|
|
191
184
|
end
|
|
192
185
|
|
|
193
186
|
private
|
|
194
187
|
|
|
195
|
-
def
|
|
196
|
-
|
|
197
|
-
ZendeskAPI::Association.class_from_namespace(
|
|
188
|
+
def resource_class_for(method)
|
|
189
|
+
resource_name = ZendeskAPI::Helpers.modulize_string(Inflection.singular(method.to_s.gsub(/\W/, '')))
|
|
190
|
+
ZendeskAPI::Association.class_from_namespace(resource_name)
|
|
198
191
|
end
|
|
199
192
|
|
|
200
193
|
def check_url
|
|
@@ -239,5 +232,16 @@ module ZendeskAPI
|
|
|
239
232
|
end
|
|
240
233
|
end
|
|
241
234
|
end
|
|
235
|
+
|
|
236
|
+
# See https://lostisland.github.io/faraday/middleware/authentication
|
|
237
|
+
def set_authentication(builder, config)
|
|
238
|
+
if config.access_token && !config.url_based_access_token
|
|
239
|
+
builder.request :authorization, "Bearer", config.access_token
|
|
240
|
+
elsif config.access_token
|
|
241
|
+
builder.use ZendeskAPI::Middleware::Request::UrlBasedAccessToken, config.access_token
|
|
242
|
+
else
|
|
243
|
+
builder.request :authorization, :basic, config.username, config.password
|
|
244
|
+
end
|
|
245
|
+
end
|
|
242
246
|
end
|
|
243
247
|
end
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
require 'zendesk_api/resource'
|
|
2
2
|
require 'zendesk_api/resources'
|
|
3
3
|
require 'zendesk_api/search'
|
|
4
|
+
require 'zendesk_api/pagination'
|
|
4
5
|
|
|
5
6
|
module ZendeskAPI
|
|
6
7
|
# Represents a collection of resources. Lazily loaded, resources aren't
|
|
7
8
|
# actually fetched until explicitly needed (e.g. #each, {#fetch}).
|
|
8
9
|
class Collection
|
|
9
10
|
include ZendeskAPI::Sideloading
|
|
11
|
+
include Pagination
|
|
10
12
|
|
|
11
13
|
# Options passed in that are automatically converted from an array to a comma-separated list.
|
|
12
14
|
SPECIALLY_JOINED_PARAMS = [:ids, :only]
|
|
@@ -114,30 +116,6 @@ module ZendeskAPI
|
|
|
114
116
|
@count || -1
|
|
115
117
|
end
|
|
116
118
|
|
|
117
|
-
# Changes the per_page option. Returns self, so it can be chained. No execution.
|
|
118
|
-
# @return [Collection] self
|
|
119
|
-
def per_page(count)
|
|
120
|
-
clear_cache if count
|
|
121
|
-
@options["per_page"] = count
|
|
122
|
-
self
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# Changes the page option. Returns self, so it can be chained. No execution.
|
|
126
|
-
# @return [Collection] self
|
|
127
|
-
def page(number)
|
|
128
|
-
clear_cache if number
|
|
129
|
-
@options["page"] = number
|
|
130
|
-
self
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def first_page?
|
|
134
|
-
!@prev_page
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def last_page?
|
|
138
|
-
!@next_page || @next_page == @query
|
|
139
|
-
end
|
|
140
|
-
|
|
141
119
|
# Saves all newly created resources stored in this collection.
|
|
142
120
|
# @return [Collection] self
|
|
143
121
|
def save
|
|
@@ -186,17 +164,8 @@ module ZendeskAPI
|
|
|
186
164
|
elsif association && association.options.parent && association.options.parent.new_record?
|
|
187
165
|
return (@resources = [])
|
|
188
166
|
end
|
|
189
|
-
path_query_link = (@query || path)
|
|
190
|
-
|
|
191
|
-
@response = get_response(path_query_link)
|
|
192
|
-
|
|
193
|
-
if path_query_link == "search/export"
|
|
194
|
-
handle_cursor_response(@response.body)
|
|
195
|
-
else
|
|
196
|
-
handle_response(@response.body)
|
|
197
|
-
end
|
|
198
167
|
|
|
199
|
-
@
|
|
168
|
+
get_resources(@query || path)
|
|
200
169
|
end
|
|
201
170
|
|
|
202
171
|
def fetch(*args)
|
|
@@ -252,10 +221,12 @@ module ZendeskAPI
|
|
|
252
221
|
# * If there is a next_page url cached, it executes a fetch on that url and returns the results.
|
|
253
222
|
# * Otherwise, returns an empty array.
|
|
254
223
|
def next
|
|
255
|
-
if @options["page"]
|
|
224
|
+
if @options["page"] && !cbp_request?
|
|
256
225
|
clear_cache
|
|
257
|
-
@options["page"]
|
|
226
|
+
@options["page"] = @options["page"].to_i + 1
|
|
258
227
|
elsif (@query = @next_page)
|
|
228
|
+
# Send _only_ url param "?after=token" to get the next page
|
|
229
|
+
@options.page&.delete("before")
|
|
259
230
|
fetch(true)
|
|
260
231
|
else
|
|
261
232
|
clear_cache
|
|
@@ -268,10 +239,12 @@ module ZendeskAPI
|
|
|
268
239
|
# * If there is a prev_page url cached, it executes a fetch on that url and returns the results.
|
|
269
240
|
# * Otherwise, returns an empty array.
|
|
270
241
|
def prev
|
|
271
|
-
if
|
|
242
|
+
if !cbp_request? && @options["page"].to_i > 1
|
|
272
243
|
clear_cache
|
|
273
244
|
@options["page"] -= 1
|
|
274
245
|
elsif (@query = @prev_page)
|
|
246
|
+
# Send _only_ url param "?before=token" to get the prev page
|
|
247
|
+
@options.page&.delete("after")
|
|
275
248
|
fetch(true)
|
|
276
249
|
else
|
|
277
250
|
clear_cache
|
|
@@ -326,22 +299,13 @@ module ZendeskAPI
|
|
|
326
299
|
map(&:to_param)
|
|
327
300
|
end
|
|
328
301
|
|
|
329
|
-
def more_results?(response)
|
|
330
|
-
response["meta"].present? && response["results"].present?
|
|
331
|
-
end
|
|
332
|
-
alias_method :has_more_results?, :more_results? # For backward compatibility with 1.33.0 and 1.34.0
|
|
333
|
-
|
|
334
|
-
def get_response_body(link)
|
|
335
|
-
@client.connection.send("get", link).body
|
|
336
|
-
end
|
|
337
|
-
|
|
338
302
|
def get_next_page_data(original_response_body)
|
|
339
303
|
link = original_response_body["links"]["next"]
|
|
340
|
-
|
|
304
|
+
result_key = @resource_class.model_key || "results"
|
|
341
305
|
while link
|
|
342
|
-
response =
|
|
306
|
+
response = @client.connection.send("get", link).body
|
|
343
307
|
|
|
344
|
-
original_response_body[
|
|
308
|
+
original_response_body[result_key] = original_response_body[result_key] + response[result_key]
|
|
345
309
|
|
|
346
310
|
link = response["meta"]["has_more"] ? response["links"]["next"] : nil
|
|
347
311
|
end
|
|
@@ -351,14 +315,20 @@ module ZendeskAPI
|
|
|
351
315
|
|
|
352
316
|
private
|
|
353
317
|
|
|
354
|
-
def
|
|
355
|
-
|
|
356
|
-
|
|
318
|
+
def get_resources(path_query_link)
|
|
319
|
+
if intentional_obp_request?
|
|
320
|
+
warn "Offset Based Pagination will be deprecated soon"
|
|
321
|
+
elsif supports_cbp? && first_cbp_request?
|
|
322
|
+
# only set cbp options if it's the first request, otherwise the options would be already in place
|
|
323
|
+
set_cbp_options
|
|
324
|
+
end
|
|
325
|
+
@response = get_response(path_query_link)
|
|
357
326
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
327
|
+
# Keep pre-existing behaviour for search/export
|
|
328
|
+
if path_query_link == "search/export"
|
|
329
|
+
handle_search_export_response(@response.body)
|
|
330
|
+
else
|
|
331
|
+
handle_response(@response.body)
|
|
362
332
|
end
|
|
363
333
|
end
|
|
364
334
|
|
|
@@ -370,13 +340,7 @@ module ZendeskAPI
|
|
|
370
340
|
|
|
371
341
|
while (bang ? fetch! : fetch)
|
|
372
342
|
each do |resource|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
if block.arity >= 0
|
|
376
|
-
arguments = arguments.take(block.arity)
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
block.call(*arguments)
|
|
343
|
+
block.call(resource, @options["page"] || 1)
|
|
380
344
|
end
|
|
381
345
|
|
|
382
346
|
last_page? ? break : self.next
|
|
@@ -422,7 +386,7 @@ module ZendeskAPI
|
|
|
422
386
|
|
|
423
387
|
def get_response(path)
|
|
424
388
|
@error = nil
|
|
425
|
-
@
|
|
389
|
+
@client.connection.send(@verb || "get", path) do |req|
|
|
426
390
|
opts = @options.delete_if { |_, v| v.nil? }
|
|
427
391
|
|
|
428
392
|
req.params.merge!(:include => @includes.join(",")) if @includes.any?
|
|
@@ -435,36 +399,30 @@ module ZendeskAPI
|
|
|
435
399
|
end
|
|
436
400
|
end
|
|
437
401
|
|
|
438
|
-
def
|
|
439
|
-
|
|
440
|
-
raise ZendeskAPI::Error::NetworkError, @response.env
|
|
441
|
-
end
|
|
402
|
+
def handle_search_export_response(response_body)
|
|
403
|
+
assert_valid_response_body(response_body)
|
|
442
404
|
|
|
405
|
+
# Note this doesn't happen in #handle_response
|
|
443
406
|
response_body = get_next_page_data(response_body) if more_results?(response_body)
|
|
444
407
|
|
|
445
408
|
body = response_body.dup
|
|
446
409
|
results = body.delete(@resource_class.model_key) || body.delete("results")
|
|
447
410
|
|
|
448
|
-
|
|
449
|
-
raise ZendeskAPI::Error::ClientError, "Expected #{@resource_class.model_key} or 'results' in response keys: #{body.keys.inspect}"
|
|
450
|
-
end
|
|
411
|
+
assert_results(results, body)
|
|
451
412
|
|
|
452
413
|
@resources = results.map do |res|
|
|
453
414
|
wrap_resource(res)
|
|
454
415
|
end
|
|
455
416
|
end
|
|
456
417
|
|
|
418
|
+
# For both CBP and OBP
|
|
457
419
|
def handle_response(response_body)
|
|
458
|
-
|
|
459
|
-
raise ZendeskAPI::Error::NetworkError, @response.env
|
|
460
|
-
end
|
|
420
|
+
assert_valid_response_body(response_body)
|
|
461
421
|
|
|
462
422
|
body = response_body.dup
|
|
463
423
|
results = body.delete(@resource_class.model_key) || body.delete("results")
|
|
464
424
|
|
|
465
|
-
|
|
466
|
-
raise ZendeskAPI::Error::ClientError, "Expected #{@resource_class.model_key} or 'results' in response keys: #{body.keys.inspect}"
|
|
467
|
-
end
|
|
425
|
+
assert_results(results, body)
|
|
468
426
|
|
|
469
427
|
@resources = results.map do |res|
|
|
470
428
|
wrap_resource(res)
|
|
@@ -472,6 +430,8 @@ module ZendeskAPI
|
|
|
472
430
|
|
|
473
431
|
set_page_and_count(body)
|
|
474
432
|
set_includes(@resources, @includes, body)
|
|
433
|
+
|
|
434
|
+
@resources
|
|
475
435
|
end
|
|
476
436
|
|
|
477
437
|
# Simplified Associations#wrap_resource
|
|
@@ -501,9 +461,13 @@ module ZendeskAPI
|
|
|
501
461
|
to_a.public_send(name, *args, &block)
|
|
502
462
|
end
|
|
503
463
|
|
|
464
|
+
# If you call client.tickets.foo - and foo is not an attribute nor an association, it ends up here, as a new collection
|
|
504
465
|
def next_collection(name, *args, &block)
|
|
505
466
|
opts = args.last.is_a?(Hash) ? args.last : {}
|
|
506
|
-
opts.merge!(:collection_path
|
|
467
|
+
opts.merge!(collection_path: [*@collection_path, name], page: nil)
|
|
468
|
+
# why page: nil ?
|
|
469
|
+
# when you do client.tickets.fetch followed by client.tickets.foos => the request to /tickets/foos will
|
|
470
|
+
# have the options page set to whatever the last options were for the tickets collection
|
|
507
471
|
self.class.new(@client, @resource_class, @options.merge(opts))
|
|
508
472
|
end
|
|
509
473
|
|
|
@@ -514,5 +478,16 @@ module ZendeskAPI
|
|
|
514
478
|
def resource_methods
|
|
515
479
|
@resource_methods ||= @resource_class.singleton_methods(false).map(&:to_sym)
|
|
516
480
|
end
|
|
481
|
+
|
|
482
|
+
def assert_valid_response_body(response_body)
|
|
483
|
+
unless response_body.is_a?(Hash)
|
|
484
|
+
raise ZendeskAPI::Error::NetworkError, @response.env
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
def assert_results(results, body)
|
|
489
|
+
return if results
|
|
490
|
+
raise ZendeskAPI::Error::ClientError, "Expected #{@resource_class.model_key} or 'results' in response keys: #{body.keys.inspect}"
|
|
491
|
+
end
|
|
517
492
|
end
|
|
518
493
|
end
|
|
@@ -28,6 +28,9 @@ module ZendeskAPI
|
|
|
28
28
|
# @return [Symbol] Faraday adapter
|
|
29
29
|
attr_accessor :adapter
|
|
30
30
|
|
|
31
|
+
# @return [Proc] Faraday adapter proc
|
|
32
|
+
attr_accessor :adapter_proc
|
|
33
|
+
|
|
31
34
|
# @return [Boolean] Whether to allow non-HTTPS connections for development purposes.
|
|
32
35
|
attr_accessor :allow_http
|
|
33
36
|
|
data/lib/zendesk_api/error.rb
CHANGED
|
@@ -33,12 +33,7 @@ module ZendeskAPI
|
|
|
33
33
|
private
|
|
34
34
|
|
|
35
35
|
def generate_error_msg(response_body)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
[
|
|
39
|
-
response_body["description"],
|
|
40
|
-
response_body["message"]
|
|
41
|
-
].compact.join(" - ")
|
|
36
|
+
response_body.values_at("description", "message", "error", "errors").compact.join(" - ")
|
|
42
37
|
end
|
|
43
38
|
end
|
|
44
39
|
|
data/lib/zendesk_api/helpers.rb
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
module ZendeskAPI
|
|
2
2
|
# @private
|
|
3
3
|
module Helpers
|
|
4
|
+
def self.present?(value)
|
|
5
|
+
![nil, false, "", " ", [], {}].include?(value)
|
|
6
|
+
end
|
|
7
|
+
|
|
4
8
|
# From https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/modulize.rb
|
|
5
9
|
# Converts a string to module name representation.
|
|
6
10
|
#
|
|
@@ -5,11 +5,12 @@ module ZendeskAPI
|
|
|
5
5
|
module Response
|
|
6
6
|
# Faraday middleware to handle content-encoding = inflate
|
|
7
7
|
# @private
|
|
8
|
-
class Deflate < Faraday::
|
|
8
|
+
class Deflate < Faraday::Middleware
|
|
9
9
|
def on_complete(env)
|
|
10
|
-
if
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
return if env[:response_headers]['content-encoding'] != "deflate"
|
|
11
|
+
return if env.body.strip.empty?
|
|
12
|
+
|
|
13
|
+
env.body = Zlib::Inflate.inflate(env.body)
|
|
13
14
|
end
|
|
14
15
|
end
|
|
15
16
|
end
|
|
@@ -7,11 +7,12 @@ module ZendeskAPI
|
|
|
7
7
|
# @private
|
|
8
8
|
module Response
|
|
9
9
|
# Faraday middleware to handle content-encoding = gzip
|
|
10
|
-
class Gzip < Faraday::
|
|
10
|
+
class Gzip < Faraday::Middleware
|
|
11
11
|
def on_complete(env)
|
|
12
|
-
if
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
return if env[:response_headers]['content-encoding'] != "gzip"
|
|
13
|
+
return if env[:body].force_encoding(Encoding::BINARY).strip.empty?
|
|
14
|
+
|
|
15
|
+
env[:body] = Zlib::GzipReader.new(StringIO.new(env[:body])).read
|
|
15
16
|
end
|
|
16
17
|
end
|
|
17
18
|
end
|
|
@@ -6,7 +6,7 @@ module ZendeskAPI
|
|
|
6
6
|
module Response
|
|
7
7
|
# Parse ISO dates from response body
|
|
8
8
|
# @private
|
|
9
|
-
class ParseIsoDates < Faraday::
|
|
9
|
+
class ParseIsoDates < Faraday::Middleware
|
|
10
10
|
def call(env)
|
|
11
11
|
@app.call(env).on_complete do |env|
|
|
12
12
|
parse_dates!(env[:body])
|
|
@@ -3,9 +3,8 @@ module ZendeskAPI
|
|
|
3
3
|
module Middleware
|
|
4
4
|
# @private
|
|
5
5
|
module Response
|
|
6
|
-
class ParseJson < Faraday::
|
|
6
|
+
class ParseJson < Faraday::Middleware
|
|
7
7
|
CONTENT_TYPE = 'Content-Type'.freeze
|
|
8
|
-
dependency 'json'
|
|
9
8
|
|
|
10
9
|
def on_complete(env)
|
|
11
10
|
type = env[:response_headers][CONTENT_TYPE].to_s
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
module ZendeskAPI
|
|
2
|
+
class Collection
|
|
3
|
+
# Contains all methods related to pagination in an attempt to slim down collection.rb
|
|
4
|
+
module Pagination
|
|
5
|
+
DEFAULT_PAGE_SIZE = 100
|
|
6
|
+
def more_results?(response)
|
|
7
|
+
Helpers.present?(response["meta"]) && response["meta"]["has_more"]
|
|
8
|
+
end
|
|
9
|
+
alias has_more_results? more_results? # For backward compatibility with 1.33.0 and 1.34.0
|
|
10
|
+
|
|
11
|
+
# Changes the per_page option. Returns self, so it can be chained. No execution.
|
|
12
|
+
# @return [Collection] self
|
|
13
|
+
def per_page(count)
|
|
14
|
+
clear_cache if count
|
|
15
|
+
@options["per_page"] = count
|
|
16
|
+
self
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Changes the page option. Returns self, so it can be chained. No execution.
|
|
20
|
+
# @return [Collection] self
|
|
21
|
+
def page(number)
|
|
22
|
+
clear_cache if number
|
|
23
|
+
@options["page"] = number
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def first_page?
|
|
28
|
+
!@prev_page
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def last_page?
|
|
32
|
+
!@next_page || @next_page == @query
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def page_links(body)
|
|
38
|
+
if body["meta"] && body["links"]
|
|
39
|
+
[body["links"]["next"], body["links"]["prev"]]
|
|
40
|
+
else
|
|
41
|
+
[body["next_page"], body["previous_page"]]
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def cbp_response?(body)
|
|
46
|
+
!!(body["meta"] && body["links"])
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def set_cbp_options
|
|
50
|
+
@options_per_page_was = @options.delete("per_page")
|
|
51
|
+
# Default to CBP by using the page param as a map
|
|
52
|
+
@options.page = { size: (@options_per_page_was || DEFAULT_PAGE_SIZE) }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# CBP requests look like: `/resources?page[size]=100`
|
|
56
|
+
# OBP requests look like: `/resources?page=2`
|
|
57
|
+
def cbp_request?
|
|
58
|
+
@options["page"].is_a?(Hash)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def intentional_obp_request?
|
|
62
|
+
Helpers.present?(@options["page"]) && !cbp_request?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def supports_cbp?
|
|
66
|
+
@resource_class.cbp_path_regexes.any? { |supported_path_regex| path.match?(supported_path_regex) }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def first_cbp_request?
|
|
70
|
+
# @next_page will be nil when making the first cbp request
|
|
71
|
+
@next_page.nil?
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def set_page_and_count(body)
|
|
75
|
+
@count = (body["count"] || @resources.size).to_i
|
|
76
|
+
@next_page, @prev_page = page_links(body)
|
|
77
|
+
|
|
78
|
+
if cbp_response?(body)
|
|
79
|
+
set_cbp_response_options(body)
|
|
80
|
+
elsif @next_page =~ /page=(\d+)/
|
|
81
|
+
@options["page"] = Regexp.last_match(1).to_i - 1
|
|
82
|
+
elsif @prev_page =~ /page=(\d+)/
|
|
83
|
+
@options["page"] = Regexp.last_match(1).to_i + 1
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def set_cbp_response_options(body)
|
|
88
|
+
@options.page = {} unless cbp_request?
|
|
89
|
+
# the line above means an intentional CBP request where page[size] is passed on the query
|
|
90
|
+
# this is to cater for CBP responses where we don't specify page[size] but the endpoint
|
|
91
|
+
# responds CBP by default. i.e `client.trigger_categories.fetch`
|
|
92
|
+
@options.page.merge!(
|
|
93
|
+
before: body["meta"]["before_cursor"],
|
|
94
|
+
after: body["meta"]["after_cursor"]
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
data/lib/zendesk_api/resource.rb
CHANGED
|
@@ -152,6 +152,10 @@ module ZendeskAPI
|
|
|
152
152
|
def self.incremental_export(client, start_time)
|
|
153
153
|
ZendeskAPI::Collection.new(client, self, :path => "incremental/organizations?start_time=#{start_time.to_i}")
|
|
154
154
|
end
|
|
155
|
+
|
|
156
|
+
def self.cbp_path_regexes
|
|
157
|
+
[/organizations$/]
|
|
158
|
+
end
|
|
155
159
|
end
|
|
156
160
|
|
|
157
161
|
class Brand < Resource
|
|
@@ -180,6 +184,10 @@ module ZendeskAPI
|
|
|
180
184
|
|
|
181
185
|
has User
|
|
182
186
|
has Organization
|
|
187
|
+
|
|
188
|
+
def self.cbp_path_regexes
|
|
189
|
+
[%r{organizations/\d+/subscriptions$}]
|
|
190
|
+
end
|
|
183
191
|
end
|
|
184
192
|
|
|
185
193
|
class Category < Resource
|
|
@@ -228,6 +236,18 @@ module ZendeskAPI
|
|
|
228
236
|
has_many Vote
|
|
229
237
|
class Translation < Resource; end
|
|
230
238
|
has_many Translation
|
|
239
|
+
class Label < DataResource
|
|
240
|
+
include Read
|
|
241
|
+
include Create
|
|
242
|
+
include Destroy
|
|
243
|
+
|
|
244
|
+
def destroy!
|
|
245
|
+
super do |req|
|
|
246
|
+
req.path = path
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
has_many Label
|
|
231
251
|
end
|
|
232
252
|
|
|
233
253
|
class TopicSubscription < Resource
|
|
@@ -246,10 +266,10 @@ module ZendeskAPI
|
|
|
246
266
|
end
|
|
247
267
|
|
|
248
268
|
class Topic < Resource
|
|
249
|
-
has_many :subscriptions, :
|
|
250
|
-
has_many Tag, :
|
|
269
|
+
has_many :subscriptions, class: TopicSubscription, inline: true
|
|
270
|
+
has_many Tag, extend: Tag::Update, inline: :create
|
|
251
271
|
has_many Attachment
|
|
252
|
-
has_many :uploads, :
|
|
272
|
+
has_many :uploads, class: Attachment, inline: true
|
|
253
273
|
end
|
|
254
274
|
|
|
255
275
|
class Activity < Resource
|
|
@@ -306,7 +326,7 @@ module ZendeskAPI
|
|
|
306
326
|
class Comment < DataResource
|
|
307
327
|
include Save
|
|
308
328
|
|
|
309
|
-
has_many :uploads, :
|
|
329
|
+
has_many :uploads, class: Attachment, inline: true
|
|
310
330
|
has :author, :class => User
|
|
311
331
|
|
|
312
332
|
def save
|
|
@@ -348,7 +368,7 @@ module ZendeskAPI
|
|
|
348
368
|
class TicketEvent < DataResource
|
|
349
369
|
class Event < Data; end
|
|
350
370
|
|
|
351
|
-
has_many :child_events, :
|
|
371
|
+
has_many :child_events, class: Event
|
|
352
372
|
has Ticket
|
|
353
373
|
has :updater, :class => User
|
|
354
374
|
|
|
@@ -366,6 +386,10 @@ module ZendeskAPI
|
|
|
366
386
|
extend UpdateMany
|
|
367
387
|
extend DestroyMany
|
|
368
388
|
|
|
389
|
+
def self.cbp_path_regexes
|
|
390
|
+
[/tickets$/]
|
|
391
|
+
end
|
|
392
|
+
|
|
369
393
|
# Unlike other attributes, "comment" is not a property of the ticket,
|
|
370
394
|
# but is used as a "comment on save", so it should be kept unchanged,
|
|
371
395
|
# See https://github.com/zendesk/zendesk_api_client_rb/issues/321
|
|
@@ -389,8 +413,8 @@ module ZendeskAPI
|
|
|
389
413
|
class Comment < DataResource
|
|
390
414
|
include Save
|
|
391
415
|
|
|
392
|
-
has_many :uploads, :
|
|
393
|
-
has :author, :
|
|
416
|
+
has_many :uploads, class: Attachment, inline: true
|
|
417
|
+
has :author, class: User
|
|
394
418
|
|
|
395
419
|
def save
|
|
396
420
|
if new_record?
|
|
@@ -417,35 +441,35 @@ module ZendeskAPI
|
|
|
417
441
|
has :submitter, :class => User
|
|
418
442
|
has :assignee, :class => User
|
|
419
443
|
|
|
420
|
-
has_many :collaborators, :
|
|
444
|
+
has_many :collaborators, class: User, inline: true, extend: (Module.new do
|
|
421
445
|
def to_param
|
|
422
446
|
map(&:id)
|
|
423
447
|
end
|
|
424
448
|
end)
|
|
425
449
|
|
|
426
450
|
has_many Audit
|
|
427
|
-
has :metrics, :
|
|
451
|
+
has :metrics, class: TicketMetric
|
|
428
452
|
has Group
|
|
429
453
|
has Organization
|
|
430
454
|
has Brand
|
|
431
|
-
has :related, :
|
|
455
|
+
has :related, class: TicketRelated
|
|
432
456
|
|
|
433
|
-
has Comment, :
|
|
457
|
+
has Comment, inline: true
|
|
434
458
|
has_many Comment
|
|
435
459
|
|
|
436
|
-
has :last_comment, :
|
|
437
|
-
has_many :last_comments, :
|
|
460
|
+
has :last_comment, class: Comment, inline: true
|
|
461
|
+
has_many :last_comments, class: Comment, inline: true
|
|
438
462
|
|
|
439
|
-
has_many Tag, :
|
|
463
|
+
has_many Tag, extend: Tag::Update, inline: :create
|
|
440
464
|
|
|
441
|
-
has_many :incidents, :
|
|
465
|
+
has_many :incidents, class: Ticket
|
|
442
466
|
|
|
443
467
|
# Gets a incremental export of tickets from the start_time until now.
|
|
444
468
|
# @param [Client] client The {Client} object to be used
|
|
445
469
|
# @param [Integer] start_time The start_time parameter
|
|
446
470
|
# @return [Collection] Collection of {Ticket}
|
|
447
471
|
def self.incremental_export(client, start_time)
|
|
448
|
-
ZendeskAPI::Collection.new(client, self, :
|
|
472
|
+
ZendeskAPI::Collection.new(client, self, path: "incremental/tickets?start_time=#{start_time.to_i}")
|
|
449
473
|
end
|
|
450
474
|
|
|
451
475
|
# Imports a ticket through the imports/tickets endpoint using save!
|
|
@@ -454,7 +478,7 @@ module ZendeskAPI
|
|
|
454
478
|
# @return [Ticket] Created object or nil
|
|
455
479
|
def self.import!(client, attributes)
|
|
456
480
|
new(client, attributes).tap do |ticket|
|
|
457
|
-
ticket.save!(:
|
|
481
|
+
ticket.save!(path: "imports/tickets")
|
|
458
482
|
end
|
|
459
483
|
end
|
|
460
484
|
|
|
@@ -464,7 +488,7 @@ module ZendeskAPI
|
|
|
464
488
|
# @return [Ticket] Created object or nil
|
|
465
489
|
def self.import(client, attributes)
|
|
466
490
|
ticket = new(client, attributes)
|
|
467
|
-
return unless ticket.save(:
|
|
491
|
+
return unless ticket.save(path: "imports/tickets")
|
|
468
492
|
ticket
|
|
469
493
|
end
|
|
470
494
|
end
|
|
@@ -498,9 +522,9 @@ module ZendeskAPI
|
|
|
498
522
|
# @internal Optional columns
|
|
499
523
|
|
|
500
524
|
has Group
|
|
501
|
-
has :assignee, :
|
|
502
|
-
has :requester, :
|
|
503
|
-
has :submitter, :
|
|
525
|
+
has :assignee, class: User
|
|
526
|
+
has :requester, class: User
|
|
527
|
+
has :submitter, class: User
|
|
504
528
|
has Organization
|
|
505
529
|
|
|
506
530
|
def self.model_key
|
|
@@ -587,6 +611,10 @@ module ZendeskAPI
|
|
|
587
611
|
include Actions
|
|
588
612
|
|
|
589
613
|
has :execution, :class => RuleExecution
|
|
614
|
+
|
|
615
|
+
def self.cbp_path_regexes
|
|
616
|
+
[/triggers$/, %r{triggers/active$}]
|
|
617
|
+
end
|
|
590
618
|
end
|
|
591
619
|
|
|
592
620
|
class Automation < Rule
|
|
@@ -636,6 +664,18 @@ module ZendeskAPI
|
|
|
636
664
|
|
|
637
665
|
has User
|
|
638
666
|
has Group
|
|
667
|
+
|
|
668
|
+
def self.cbp_path_regexes
|
|
669
|
+
[%r{groups/\d+/memberships$}]
|
|
670
|
+
end
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
class Group < Resource
|
|
674
|
+
has_many :memberships, class: GroupMembership, path: "memberships"
|
|
675
|
+
|
|
676
|
+
def self.cbp_path_regexes
|
|
677
|
+
[/groups$/, %r{groups/assignable$}]
|
|
678
|
+
end
|
|
639
679
|
end
|
|
640
680
|
|
|
641
681
|
class User < Resource
|
data/lib/zendesk_api/search.rb
CHANGED
data/lib/zendesk_api/verbs.rb
CHANGED
|
@@ -44,14 +44,12 @@ module ZendeskAPI
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
define_method method do |*method_args|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
false
|
|
54
|
-
end
|
|
47
|
+
send("#{method}!", *method_args)
|
|
48
|
+
rescue ZendeskAPI::Error::RecordInvalid => e
|
|
49
|
+
@errors = e.errors
|
|
50
|
+
false
|
|
51
|
+
rescue ZendeskAPI::Error::ClientError
|
|
52
|
+
false
|
|
55
53
|
end
|
|
56
54
|
end
|
|
57
55
|
end
|
data/lib/zendesk_api/version.rb
CHANGED
data/lib/zendesk_api.rb
CHANGED
metadata
CHANGED
|
@@ -1,36 +1,44 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zendesk_api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Steven Davidovitz
|
|
8
8
|
- Michael Grosser
|
|
9
|
-
autorequire:
|
|
9
|
+
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2023-08-01 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: faraday
|
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
|
17
17
|
requirements:
|
|
18
|
-
- - "
|
|
19
|
-
- !ruby/object:Gem::Version
|
|
20
|
-
version: 0.9.0
|
|
21
|
-
- - "<"
|
|
18
|
+
- - ">"
|
|
22
19
|
- !ruby/object:Gem::Version
|
|
23
20
|
version: 2.0.0
|
|
24
21
|
type: :runtime
|
|
25
22
|
prerelease: false
|
|
26
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - ">"
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
version: 2.0.0
|
|
28
|
+
- !ruby/object:Gem::Dependency
|
|
29
|
+
name: faraday-multipart
|
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
|
27
31
|
requirements:
|
|
28
32
|
- - ">="
|
|
29
33
|
- !ruby/object:Gem::Version
|
|
30
|
-
version: 0
|
|
31
|
-
|
|
34
|
+
version: '0'
|
|
35
|
+
type: :runtime
|
|
36
|
+
prerelease: false
|
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - ">="
|
|
32
40
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
41
|
+
version: '0'
|
|
34
42
|
- !ruby/object:Gem::Dependency
|
|
35
43
|
name: hashie
|
|
36
44
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -128,6 +136,7 @@ files:
|
|
|
128
136
|
- lib/zendesk_api/middleware/response/parse_json.rb
|
|
129
137
|
- lib/zendesk_api/middleware/response/raise_error.rb
|
|
130
138
|
- lib/zendesk_api/middleware/response/sanitize_response.rb
|
|
139
|
+
- lib/zendesk_api/pagination.rb
|
|
131
140
|
- lib/zendesk_api/resource.rb
|
|
132
141
|
- lib/zendesk_api/resources.rb
|
|
133
142
|
- lib/zendesk_api/search.rb
|
|
@@ -144,11 +153,11 @@ licenses:
|
|
|
144
153
|
- Apache-2.0
|
|
145
154
|
metadata:
|
|
146
155
|
bug_tracker_uri: https://github.com/zendesk/zendesk_api_client_rb/issues
|
|
147
|
-
changelog_uri: https://github.com/zendesk/zendesk_api_client_rb/blob/
|
|
148
|
-
documentation_uri: https://www.rubydoc.info/gems/zendesk_api/
|
|
149
|
-
source_code_uri: https://github.com/zendesk/zendesk_api_client_rb/tree/
|
|
156
|
+
changelog_uri: https://github.com/zendesk/zendesk_api_client_rb/blob/v3.0.2/CHANGELOG.md
|
|
157
|
+
documentation_uri: https://www.rubydoc.info/gems/zendesk_api/3.0.2
|
|
158
|
+
source_code_uri: https://github.com/zendesk/zendesk_api_client_rb/tree/v3.0.2
|
|
150
159
|
wiki_uri: https://github.com/zendesk/zendesk_api_client_rb/wiki
|
|
151
|
-
post_install_message:
|
|
160
|
+
post_install_message:
|
|
152
161
|
rdoc_options: []
|
|
153
162
|
require_paths:
|
|
154
163
|
- lib
|
|
@@ -156,15 +165,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
156
165
|
requirements:
|
|
157
166
|
- - ">="
|
|
158
167
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: '2.
|
|
168
|
+
version: '2.7'
|
|
160
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
170
|
requirements:
|
|
162
171
|
- - ">="
|
|
163
172
|
- !ruby/object:Gem::Version
|
|
164
173
|
version: 1.3.6
|
|
165
174
|
requirements: []
|
|
166
|
-
rubygems_version: 3.0.3
|
|
167
|
-
signing_key:
|
|
175
|
+
rubygems_version: 3.0.3.1
|
|
176
|
+
signing_key:
|
|
168
177
|
specification_version: 4
|
|
169
178
|
summary: Zendesk REST API Client
|
|
170
179
|
test_files: []
|