zendesk_api 1.37.0 → 3.0.5
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 +19 -10
- data/lib/zendesk_api/resources.rb +118 -22
- 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: 8ecc2ccbe7be3ec6da2b36fdcd7b75004fcecd91a26de63d0bb561dcddff86cc
|
4
|
+
data.tar.gz: c4b7a7d6baa3246d2835251d03d2a7c0fd69961fd2ca3575a7486f3a7adf06f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9183c973ac61c198dd69d975c5bc9eb27cc424b47e50027d32c2a462f651b08681925b00fd4686d248b615a80445c34b59273861a164917ea6738b54d04c1a4b
|
7
|
+
data.tar.gz: 980637e5be8ba003774a6fe5fe53dc2a4003ba6e58b933d21aaba66cb9c66eb0dd3f706ac6b2e69740f1c22cfe2a3d4c7301a7cfd313c0753ef3cff7cbc2683b
|
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 "?page[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 "?page[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
@@ -39,6 +39,14 @@ module ZendeskAPI
|
|
39
39
|
def namespace(namespace)
|
40
40
|
@namespace = namespace
|
41
41
|
end
|
42
|
+
|
43
|
+
def new_from_response(client, response, includes = nil)
|
44
|
+
new(client).tap do |resource|
|
45
|
+
resource.handle_response(response)
|
46
|
+
resource.set_includes(resource, includes, response.body) if includes
|
47
|
+
resource.attributes.clear_changes
|
48
|
+
end
|
49
|
+
end
|
42
50
|
end
|
43
51
|
|
44
52
|
# @return [Hash] The resource's attributes
|
@@ -123,19 +131,16 @@ module ZendeskAPI
|
|
123
131
|
|
124
132
|
# Compares resources by class and id. If id is nil, then by object_id
|
125
133
|
def ==(other)
|
134
|
+
return false unless other
|
135
|
+
|
126
136
|
return true if other.object_id == object_id
|
127
137
|
|
128
|
-
|
129
|
-
warn "Trying to compare #{other.class} to a Resource from #{caller.first}"
|
130
|
-
end
|
138
|
+
return other.id && (other.id == id) if other.is_a?(Data)
|
131
139
|
|
132
|
-
if other.is_a?(
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
else
|
137
|
-
false
|
138
|
-
end
|
140
|
+
return id == other if other.is_a?(Integer)
|
141
|
+
|
142
|
+
warn "Trying to compare #{other.class} to a Resource
|
143
|
+
from #{caller.first}"
|
139
144
|
end
|
140
145
|
alias :eql :==
|
141
146
|
|
@@ -163,6 +168,10 @@ module ZendeskAPI
|
|
163
168
|
class DataResource < Data
|
164
169
|
attr_accessor :error, :error_message
|
165
170
|
extend Verbs
|
171
|
+
|
172
|
+
def self.cbp_path_regexes
|
173
|
+
[]
|
174
|
+
end
|
166
175
|
end
|
167
176
|
|
168
177
|
# Represents a resource that can only GET
|
@@ -24,6 +24,10 @@ module ZendeskAPI
|
|
24
24
|
|
25
25
|
class Topic < Resource
|
26
26
|
class << self
|
27
|
+
def cbp_path_regexes
|
28
|
+
[%r{^community/topics$}]
|
29
|
+
end
|
30
|
+
|
27
31
|
def resource_path
|
28
32
|
"community/topics"
|
29
33
|
end
|
@@ -83,6 +87,10 @@ module ZendeskAPI
|
|
83
87
|
def attributes_for_save
|
84
88
|
{ self.class.resource_name => [id] }
|
85
89
|
end
|
90
|
+
|
91
|
+
def self.cbp_path_regexes
|
92
|
+
[/^tags$/]
|
93
|
+
end
|
86
94
|
end
|
87
95
|
|
88
96
|
class Attachment < ReadResource
|
@@ -152,9 +160,17 @@ module ZendeskAPI
|
|
152
160
|
def self.incremental_export(client, start_time)
|
153
161
|
ZendeskAPI::Collection.new(client, self, :path => "incremental/organizations?start_time=#{start_time.to_i}")
|
154
162
|
end
|
163
|
+
|
164
|
+
def self.cbp_path_regexes
|
165
|
+
[/^organizations$/]
|
166
|
+
end
|
155
167
|
end
|
156
168
|
|
157
169
|
class Brand < Resource
|
170
|
+
def self.cbp_path_regexes
|
171
|
+
[/^brands$/]
|
172
|
+
end
|
173
|
+
|
158
174
|
def destroy!
|
159
175
|
self.active = false
|
160
176
|
save!
|
@@ -180,6 +196,10 @@ module ZendeskAPI
|
|
180
196
|
|
181
197
|
has User
|
182
198
|
has Organization
|
199
|
+
|
200
|
+
def self.cbp_path_regexes
|
201
|
+
[%r{^organizations/\d+/subscriptions$}]
|
202
|
+
end
|
183
203
|
end
|
184
204
|
|
185
205
|
class Category < Resource
|
@@ -228,6 +248,18 @@ module ZendeskAPI
|
|
228
248
|
has_many Vote
|
229
249
|
class Translation < Resource; end
|
230
250
|
has_many Translation
|
251
|
+
class Label < DataResource
|
252
|
+
include Read
|
253
|
+
include Create
|
254
|
+
include Destroy
|
255
|
+
|
256
|
+
def destroy!
|
257
|
+
super do |req|
|
258
|
+
req.path = path
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
has_many Label
|
231
263
|
end
|
232
264
|
|
233
265
|
class TopicSubscription < Resource
|
@@ -246,15 +278,19 @@ module ZendeskAPI
|
|
246
278
|
end
|
247
279
|
|
248
280
|
class Topic < Resource
|
249
|
-
has_many :subscriptions, :
|
250
|
-
has_many Tag, :
|
281
|
+
has_many :subscriptions, class: TopicSubscription, inline: true
|
282
|
+
has_many Tag, extend: Tag::Update, inline: :create
|
251
283
|
has_many Attachment
|
252
|
-
has_many :uploads, :
|
284
|
+
has_many :uploads, class: Attachment, inline: true
|
253
285
|
end
|
254
286
|
|
255
287
|
class Activity < Resource
|
256
288
|
has User
|
257
289
|
has :actor, :class => User
|
290
|
+
|
291
|
+
def self.cbp_path_regexes
|
292
|
+
[/^activities$/]
|
293
|
+
end
|
258
294
|
end
|
259
295
|
|
260
296
|
class Setting < UpdateResource
|
@@ -306,7 +342,7 @@ module ZendeskAPI
|
|
306
342
|
class Comment < DataResource
|
307
343
|
include Save
|
308
344
|
|
309
|
-
has_many :uploads, :
|
345
|
+
has_many :uploads, class: Attachment, inline: true
|
310
346
|
has :author, :class => User
|
311
347
|
|
312
348
|
def save
|
@@ -337,10 +373,18 @@ module ZendeskAPI
|
|
337
373
|
namespace 'portal'
|
338
374
|
end
|
339
375
|
|
340
|
-
class TicketField < Resource
|
376
|
+
class TicketField < Resource
|
377
|
+
def self.cbp_path_regexes
|
378
|
+
[/^ticket_fields$/]
|
379
|
+
end
|
380
|
+
end
|
341
381
|
|
342
382
|
class TicketMetric < DataResource
|
343
383
|
include Read
|
384
|
+
|
385
|
+
def self.cbp_path_regexes
|
386
|
+
[/^ticket_metrics$/]
|
387
|
+
end
|
344
388
|
end
|
345
389
|
|
346
390
|
class TicketRelated < DataResource; end
|
@@ -348,7 +392,7 @@ module ZendeskAPI
|
|
348
392
|
class TicketEvent < DataResource
|
349
393
|
class Event < Data; end
|
350
394
|
|
351
|
-
has_many :child_events, :
|
395
|
+
has_many :child_events, class: Event
|
352
396
|
has Ticket
|
353
397
|
has :updater, :class => User
|
354
398
|
|
@@ -366,6 +410,10 @@ module ZendeskAPI
|
|
366
410
|
extend UpdateMany
|
367
411
|
extend DestroyMany
|
368
412
|
|
413
|
+
def self.cbp_path_regexes
|
414
|
+
[/^tickets$/, %r{organizations/\d+/tickets}]
|
415
|
+
end
|
416
|
+
|
369
417
|
# Unlike other attributes, "comment" is not a property of the ticket,
|
370
418
|
# but is used as a "comment on save", so it should be kept unchanged,
|
371
419
|
# See https://github.com/zendesk/zendesk_api_client_rb/issues/321
|
@@ -384,13 +432,17 @@ module ZendeskAPI
|
|
384
432
|
has :author, :class => User
|
385
433
|
|
386
434
|
has_many Event
|
435
|
+
|
436
|
+
def self.cbp_path_regexes
|
437
|
+
[%r{^tickets/\d+/audits$}]
|
438
|
+
end
|
387
439
|
end
|
388
440
|
|
389
441
|
class Comment < DataResource
|
390
442
|
include Save
|
391
443
|
|
392
|
-
has_many :uploads, :
|
393
|
-
has :author, :
|
444
|
+
has_many :uploads, class: Attachment, inline: true
|
445
|
+
has :author, class: User
|
394
446
|
|
395
447
|
def save
|
396
448
|
if new_record?
|
@@ -417,35 +469,35 @@ module ZendeskAPI
|
|
417
469
|
has :submitter, :class => User
|
418
470
|
has :assignee, :class => User
|
419
471
|
|
420
|
-
has_many :collaborators, :
|
472
|
+
has_many :collaborators, class: User, inline: true, extend: (Module.new do
|
421
473
|
def to_param
|
422
474
|
map(&:id)
|
423
475
|
end
|
424
476
|
end)
|
425
477
|
|
426
478
|
has_many Audit
|
427
|
-
has :metrics, :
|
479
|
+
has :metrics, class: TicketMetric
|
428
480
|
has Group
|
429
481
|
has Organization
|
430
482
|
has Brand
|
431
|
-
has :related, :
|
483
|
+
has :related, class: TicketRelated
|
432
484
|
|
433
|
-
has Comment, :
|
485
|
+
has Comment, inline: true
|
434
486
|
has_many Comment
|
435
487
|
|
436
|
-
has :last_comment, :
|
437
|
-
has_many :last_comments, :
|
488
|
+
has :last_comment, class: Comment, inline: true
|
489
|
+
has_many :last_comments, class: Comment, inline: true
|
438
490
|
|
439
|
-
has_many Tag, :
|
491
|
+
has_many Tag, extend: Tag::Update, inline: :create
|
440
492
|
|
441
|
-
has_many :incidents, :
|
493
|
+
has_many :incidents, class: Ticket
|
442
494
|
|
443
495
|
# Gets a incremental export of tickets from the start_time until now.
|
444
496
|
# @param [Client] client The {Client} object to be used
|
445
497
|
# @param [Integer] start_time The start_time parameter
|
446
498
|
# @return [Collection] Collection of {Ticket}
|
447
499
|
def self.incremental_export(client, start_time)
|
448
|
-
ZendeskAPI::Collection.new(client, self, :
|
500
|
+
ZendeskAPI::Collection.new(client, self, path: "incremental/tickets?start_time=#{start_time.to_i}")
|
449
501
|
end
|
450
502
|
|
451
503
|
# Imports a ticket through the imports/tickets endpoint using save!
|
@@ -454,7 +506,7 @@ module ZendeskAPI
|
|
454
506
|
# @return [Ticket] Created object or nil
|
455
507
|
def self.import!(client, attributes)
|
456
508
|
new(client, attributes).tap do |ticket|
|
457
|
-
ticket.save!(:
|
509
|
+
ticket.save!(path: "imports/tickets")
|
458
510
|
end
|
459
511
|
end
|
460
512
|
|
@@ -464,7 +516,7 @@ module ZendeskAPI
|
|
464
516
|
# @return [Ticket] Created object or nil
|
465
517
|
def self.import(client, attributes)
|
466
518
|
ticket = new(client, attributes)
|
467
|
-
return unless ticket.save(:
|
519
|
+
return unless ticket.save(path: "imports/tickets")
|
468
520
|
ticket
|
469
521
|
end
|
470
522
|
end
|
@@ -474,6 +526,10 @@ module ZendeskAPI
|
|
474
526
|
|
475
527
|
# Recovers this suspended ticket to an actual ticket
|
476
528
|
put :recover
|
529
|
+
|
530
|
+
def self.cbp_path_regexes
|
531
|
+
[/^suspended_tickets$/]
|
532
|
+
end
|
477
533
|
end
|
478
534
|
|
479
535
|
class DeletedTicket < ReadResource
|
@@ -483,6 +539,10 @@ module ZendeskAPI
|
|
483
539
|
# Restores this previously deleted ticket to an actual ticket
|
484
540
|
put :restore
|
485
541
|
put :restore_many
|
542
|
+
|
543
|
+
def self.cbp_path_regexes
|
544
|
+
[/^deleted_tickets$/]
|
545
|
+
end
|
486
546
|
end
|
487
547
|
|
488
548
|
class UserViewRow < DataResource
|
@@ -498,9 +558,9 @@ module ZendeskAPI
|
|
498
558
|
# @internal Optional columns
|
499
559
|
|
500
560
|
has Group
|
501
|
-
has :assignee, :
|
502
|
-
has :requester, :
|
503
|
-
has :submitter, :
|
561
|
+
has :assignee, class: User
|
562
|
+
has :requester, class: User
|
563
|
+
has :submitter, class: User
|
504
564
|
has Organization
|
505
565
|
|
506
566
|
def self.model_key
|
@@ -580,6 +640,10 @@ module ZendeskAPI
|
|
580
640
|
def self.preview(client, options = {})
|
581
641
|
Collection.new(client, ViewRow, options.merge(:path => "views/preview", :verb => :post))
|
582
642
|
end
|
643
|
+
|
644
|
+
def self.cbp_path_regexes
|
645
|
+
[/^views$/]
|
646
|
+
end
|
583
647
|
end
|
584
648
|
|
585
649
|
class Trigger < Rule
|
@@ -587,6 +651,10 @@ module ZendeskAPI
|
|
587
651
|
include Actions
|
588
652
|
|
589
653
|
has :execution, :class => RuleExecution
|
654
|
+
|
655
|
+
def self.cbp_path_regexes
|
656
|
+
[/^triggers$/, %r{^triggers/active$}]
|
657
|
+
end
|
590
658
|
end
|
591
659
|
|
592
660
|
class Automation < Rule
|
@@ -594,6 +662,10 @@ module ZendeskAPI
|
|
594
662
|
include Actions
|
595
663
|
|
596
664
|
has :execution, :class => RuleExecution
|
665
|
+
|
666
|
+
def self.cbp_path_regexes
|
667
|
+
[/^automations$/]
|
668
|
+
end
|
597
669
|
end
|
598
670
|
|
599
671
|
class Macro < Rule
|
@@ -601,6 +673,10 @@ module ZendeskAPI
|
|
601
673
|
|
602
674
|
has :execution, :class => RuleExecution
|
603
675
|
|
676
|
+
def self.cbp_path_regexes
|
677
|
+
[/^macros$/]
|
678
|
+
end
|
679
|
+
|
604
680
|
# Returns the update to a ticket that happens when a macro will be applied.
|
605
681
|
# @param [Ticket] ticket Optional {Ticket} to apply this macro to.
|
606
682
|
# @raise [Faraday::ClientError] Raised for any non-200 response.
|
@@ -636,6 +712,18 @@ module ZendeskAPI
|
|
636
712
|
|
637
713
|
has User
|
638
714
|
has Group
|
715
|
+
|
716
|
+
def self.cbp_path_regexes
|
717
|
+
[%r{^groups/\d+/memberships$}]
|
718
|
+
end
|
719
|
+
end
|
720
|
+
|
721
|
+
class Group < Resource
|
722
|
+
has_many :memberships, class: GroupMembership, path: "memberships"
|
723
|
+
|
724
|
+
def self.cbp_path_regexes
|
725
|
+
[/^groups$/, %r{^groups/assignable$}]
|
726
|
+
end
|
639
727
|
end
|
640
728
|
|
641
729
|
class User < Resource
|
@@ -660,6 +748,10 @@ module ZendeskAPI
|
|
660
748
|
put :request_verification
|
661
749
|
end
|
662
750
|
|
751
|
+
def self.cbp_path_regexes
|
752
|
+
[/^users$/, %r{^organizations/\d+/users$}]
|
753
|
+
end
|
754
|
+
|
663
755
|
any :password
|
664
756
|
|
665
757
|
# Set a user's password
|
@@ -777,6 +869,10 @@ module ZendeskAPI
|
|
777
869
|
def self.singular_resource_name
|
778
870
|
"client"
|
779
871
|
end
|
872
|
+
|
873
|
+
def self.cbp_path_regexes
|
874
|
+
[%r{^oauth/clients$}]
|
875
|
+
end
|
780
876
|
end
|
781
877
|
|
782
878
|
class OauthToken < ReadResource
|
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.5
|
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-09-06 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.5/CHANGELOG.md
|
157
|
+
documentation_uri: https://www.rubydoc.info/gems/zendesk_api/3.0.5
|
158
|
+
source_code_uri: https://github.com/zendesk/zendesk_api_client_rb/tree/v3.0.5
|
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: []
|