zendesk_api 1.31.0 → 1.35.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5effe63f9bf20a2f1609678307075c1469cb10bf73ddf992bac282fe0373643e
4
- data.tar.gz: 528b5448a9add09ae4f14dac496dff8753ea6ea80e991f5610d021ec70fa27de
3
+ metadata.gz: 1cb0a6ce03a083efc37a6f742e90e58955a411ce76c3bfffb78ad5fc61f336b6
4
+ data.tar.gz: 10d25156b4961da61e2c1b7276ef5a8e4a17664c93d4a24e8f466ec9dc2e85b1
5
5
  SHA512:
6
- metadata.gz: e8897e7999a22d4c0785696fcfd59310035eb4f654cbbbfbde1b0f4be72defe5a106bf4489c1bef71b4638cfc8d04f0d6866503f47c928c4c9ed7275aa14b77a
7
- data.tar.gz: 1a8c38c9297aa2220b9d46909be86bcc2de2572bc11b43a4fa56a4f7ff7bed1516af0eda2a0040fb3e4d8ad8b50c3a8929b420e5dcd7b833c1f4893f44eeb0f1
6
+ metadata.gz: da965fc1a9d28cb7edafdb82a56a1e73b64930f7706ac32bc9980ee3da415e540362f036c8dd6101b7615ce3781e4cc9e5645780bd83c504c714c60879450dcc
7
+ data.tar.gz: edbee03ff02ea28e78f88c9e1766d0cccbd0d59b068ae103f80d9c83f10cf734707e96a3341710131f93ffc346066f04a0e3d0200cc9def631cb984285086679
@@ -19,13 +19,8 @@ module ZendeskAPI
19
19
  nil
20
20
  end
21
21
 
22
- # 1.9+ changed default to search ancestors, added flag to disable behavior.
23
22
  def module_defines_class?(mod, klass_as_string)
24
- if RUBY_VERSION < '1.9'
25
- mod.const_defined?(klass_as_string)
26
- else
27
- mod.const_defined?(klass_as_string, false)
28
- end
23
+ mod.const_defined?(klass_as_string, false)
29
24
  end
30
25
  end
31
26
 
@@ -58,7 +53,6 @@ module ZendeskAPI
58
53
 
59
54
  namespace = @options[:class].to_s.split("::")
60
55
  namespace[-1] = @options[:class].resource_path
61
-
62
56
  # Remove components without path information
63
57
  ignorable_namespace_strings.each { |ns| namespace.delete(ns) }
64
58
  has_parent = namespace.size > 1 || (options[:with_parent] && @options.parent)
@@ -181,7 +181,7 @@ module ZendeskAPI
181
181
  builder.use ZendeskAPI::Middleware::Request::EncodeJson
182
182
 
183
183
  # Should always be first in the stack
184
- builder.use ZendeskAPI::Middleware::Request::Retry, :logger => config.logger if config.retry
184
+ builder.use ZendeskAPI::Middleware::Request::Retry, :logger => config.logger, :retry_codes => config.retry_codes, :retry_on_exception => config.retry_on_exception if config.retry
185
185
  if config.raise_error_when_rate_limited
186
186
  builder.use ZendeskAPI::Middleware::Request::RaiseRateLimited, :logger => config.logger
187
187
  end
@@ -198,7 +198,7 @@ module ZendeskAPI
198
198
  end
199
199
 
200
200
  def check_url
201
- if !config.allow_http && config.url !~ /^https/
201
+ if !config.allow_http && !config.url.start_with?('https://')
202
202
  raise ArgumentError, "zendesk_api is ssl only; url must begin with https://"
203
203
  end
204
204
  end
@@ -1,5 +1,6 @@
1
1
  require 'zendesk_api/resource'
2
2
  require 'zendesk_api/resources'
3
+ require 'zendesk_api/search'
3
4
 
4
5
  module ZendeskAPI
5
6
  # Represents a collection of resources. Lazily loaded, resources aren't
@@ -28,7 +29,7 @@ module ZendeskAPI
28
29
  # @param [String] resource The resource being collected.
29
30
  # @param [Hash] options Any additional options to be passed in.
30
31
  def initialize(client, resource, options = {})
31
- @client, @resource_class, @resource = client, resource, resource.resource_name
32
+ @client, @resource_class, @resource = client, resource, resource.resource_path
32
33
  @options = SilentMash.new(options)
33
34
 
34
35
  set_association_from_options
@@ -47,7 +48,7 @@ module ZendeskAPI
47
48
  end
48
49
 
49
50
  # Methods that take a Hash argument
50
- methods = %w{create find update update_many destroy}
51
+ methods = %w{create find update update_many destroy create_or_update}
51
52
  methods += methods.map { |method| method + "!" }
52
53
  methods.each do |deferrable|
53
54
  # Passes arguments and the proper path to the resource class method.
@@ -185,9 +186,15 @@ module ZendeskAPI
185
186
  elsif association && association.options.parent && association.options.parent.new_record?
186
187
  return (@resources = [])
187
188
  end
189
+ path_query_link = (@query || path)
188
190
 
189
- @response = get_response(@query || path)
190
- handle_response(@response.body)
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
191
198
 
192
199
  @resources
193
200
  end
@@ -248,7 +255,7 @@ module ZendeskAPI
248
255
  if @options["page"]
249
256
  clear_cache
250
257
  @options["page"] += 1
251
- elsif @query = @next_page
258
+ elsif (@query = @next_page)
252
259
  fetch(true)
253
260
  else
254
261
  clear_cache
@@ -264,7 +271,7 @@ module ZendeskAPI
264
271
  if @options["page"] && @options["page"] > 1
265
272
  clear_cache
266
273
  @options["page"] -= 1
267
- elsif @query = @prev_page
274
+ elsif (@query = @prev_page)
268
275
  fetch(true)
269
276
  else
270
277
  clear_cache
@@ -313,12 +320,35 @@ module ZendeskAPI
313
320
  end
314
321
  end
315
322
 
316
- alias :to_str :to_s
323
+ alias to_str to_s
317
324
 
318
325
  def to_param
319
326
  map(&:to_param)
320
327
  end
321
328
 
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
+ def get_next_page_data(original_response_body)
339
+ link = original_response_body["links"]["next"]
340
+
341
+ while link
342
+ response = get_response_body(link)
343
+
344
+ original_response_body["results"] = original_response_body["results"] + response["results"]
345
+
346
+ link = response["meta"]["has_more"] ? response["links"]["next"] : nil
347
+ end
348
+
349
+ original_response_body
350
+ end
351
+
322
352
  private
323
353
 
324
354
  def set_page_and_count(body)
@@ -372,8 +402,6 @@ module ZendeskAPI
372
402
  result
373
403
  end
374
404
 
375
- ## Initialize
376
-
377
405
  def join_special_params
378
406
  # some params use comma-joined strings instead of query-based arrays for multiple values
379
407
  @options.each do |k, v|
@@ -389,7 +417,6 @@ module ZendeskAPI
389
417
  association_options = { :path => @options.delete(:path) }
390
418
  association_options[:path] ||= @collection_path.join("/") if @collection_path
391
419
  @association = @options.delete(:association) || Association.new(association_options.merge(:class => @resource_class))
392
-
393
420
  @collection_path ||= [@resource]
394
421
  end
395
422
 
@@ -410,6 +437,25 @@ module ZendeskAPI
410
437
  end
411
438
  end
412
439
 
440
+ def handle_cursor_response(response_body)
441
+ unless response_body.is_a?(Hash)
442
+ raise ZendeskAPI::Error::NetworkError, @response.env
443
+ end
444
+
445
+ response_body = get_next_page_data(response_body) if more_results?(response_body)
446
+
447
+ body = response_body.dup
448
+ results = body.delete(@resource_class.model_key) || body.delete("results")
449
+
450
+ unless results
451
+ raise ZendeskAPI::Error::ClientError, "Expected #{@resource_class.model_key} or 'results' in response keys: #{body.keys.inspect}"
452
+ end
453
+
454
+ @resources = results.map do |res|
455
+ wrap_resource(res)
456
+ end
457
+ end
458
+
413
459
  def handle_response(response_body)
414
460
  unless response_body.is_a?(Hash)
415
461
  raise ZendeskAPI::Error::NetworkError, @response.env
@@ -45,6 +45,12 @@ module ZendeskAPI
45
45
  # @return [Boolean] Whether to use resource_cache or not
46
46
  attr_accessor :use_resource_cache
47
47
 
48
+ # specify the server error codes in which you want a retry to be attempted
49
+ attr_accessor :retry_codes
50
+
51
+ # specify if you want a (network layer) exception to elicit a retry
52
+ attr_accessor :retry_on_exception
53
+
48
54
  def initialize
49
55
  @client_options = {}
50
56
  @use_resource_cache = true
@@ -20,7 +20,7 @@ module ZendeskAPI
20
20
  super
21
21
 
22
22
  if response[:body].is_a?(Hash)
23
- @errors = response[:body]["details"] || response[:body]["description"]
23
+ @errors = response[:body]["details"] || generate_error_msg(response[:body])
24
24
  end
25
25
 
26
26
  @errors ||= {}
@@ -29,6 +29,17 @@ module ZendeskAPI
29
29
  def to_s
30
30
  "#{self.class.name}: #{@errors}"
31
31
  end
32
+
33
+ private
34
+
35
+ def generate_error_msg(response_body)
36
+ return unless response_body["description"] || response_body["message"]
37
+
38
+ [
39
+ response_body["description"],
40
+ response_body["message"]
41
+ ].compact.join(" - ")
42
+ end
32
43
  end
33
44
 
34
45
  class NetworkError < ClientError; end
@@ -2,6 +2,19 @@ module ZendeskAPI
2
2
  # @private
3
3
  module Helpers
4
4
  # From https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/modulize.rb
5
+ # Converts a string to module name representation.
6
+ #
7
+ # This is essentially #camelcase, but it also converts
8
+ # '/' to '::' which is useful for converting paths to
9
+ # namespaces.
10
+ #
11
+ # Examples
12
+ #
13
+ # "method_name".modulize #=> "MethodName"
14
+ # "method/name".modulize #=> "Method::Name"
15
+ #
16
+ # @param string [string] input, `module/class_name`
17
+ # @return [string] a string that can become a class, `Module::ClassName`
5
18
  def self.modulize_string(string)
6
19
  # gsub('__','/'). # why was this ever here?
7
20
  string.gsub(/__(.?)/) { "::#{$1.upcase}" }.
@@ -11,6 +24,14 @@ module ZendeskAPI
11
24
  end
12
25
 
13
26
  # From https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/snakecase.rb
27
+ # Underscore a string such that camelcase, dashes and spaces are
28
+ # replaced by underscores. This is the reverse of {#camelcase},
29
+ # albeit not an exact inverse.
30
+ #
31
+ # "SnakeCase".snakecase #=> "snake_case"
32
+ # "Snake-Case".snakecase #=> "snake_case"
33
+ # "Snake Case".snakecase #=> "snake_case"
34
+ # "Snake - Case".snakecase #=> "snake_case"
14
35
  def self.snakecase_string(string)
15
36
  # gsub(/::/, '/').
16
37
  string.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
@@ -1,5 +1,4 @@
1
1
  require "faraday/middleware"
2
-
3
2
  module ZendeskAPI
4
3
  module Middleware
5
4
  # @private
@@ -8,19 +7,37 @@ module ZendeskAPI
8
7
  # @private
9
8
  class Retry < Faraday::Middleware
10
9
  DEFAULT_RETRY_AFTER = 10
11
- ERROR_CODES = [429, 503]
10
+ DEFAULT_ERROR_CODES = [429, 503]
12
11
 
13
12
  def initialize(app, options = {})
14
13
  super(app)
15
14
  @logger = options[:logger]
15
+ @error_codes = options.key?(:retry_codes) && options[:retry_codes] ? options[:retry_codes] : DEFAULT_ERROR_CODES
16
+ @retry_on_exception = options.key?(:retry_on_exception) && options[:retry_on_exception] ? options[:retry_on_exception] : false
16
17
  end
17
18
 
18
19
  def call(env)
19
20
  original_env = env.dup
20
- response = @app.call(env)
21
+ exception_happened = false
22
+ if @retry_on_exception
23
+ begin
24
+ response = @app.call(env)
25
+ rescue StandardError => e
26
+ exception_happened = true
27
+ end
28
+ else
29
+ response = @app.call(env)
30
+ end
31
+
32
+ if exception_happened || @error_codes.include?(response.env[:status])
33
+
34
+ if exception_happened
35
+ seconds_left = DEFAULT_RETRY_AFTER.to_i
36
+ @logger.warn "An exception happened, waiting #{seconds_left} seconds... #{e}" if @logger
37
+ else
38
+ seconds_left = (response.env[:response_headers][:retry_after] || DEFAULT_RETRY_AFTER).to_i
39
+ end
21
40
 
22
- if ERROR_CODES.include?(response.env[:status])
23
- seconds_left = (response.env[:response_headers][:retry_after] || DEFAULT_RETRY_AFTER).to_i
24
41
  @logger.warn "You have been rate limited. Retrying in #{seconds_left} seconds..." if @logger
25
42
 
26
43
  seconds_left.times do |i|
@@ -6,7 +6,7 @@ require 'zendesk_api/associations'
6
6
  require 'zendesk_api/verbs'
7
7
 
8
8
  module ZendeskAPI
9
- # Represents a resource that only holds data.
9
+ # Represents an abstract resource that only holds data.
10
10
  class Data
11
11
  include Associations
12
12
 
@@ -54,6 +54,7 @@ module ZendeskAPI
54
54
  # @param [Hash] attributes The optional attributes that describe the resource
55
55
  def initialize(client, attributes = {})
56
56
  raise "Expected a Hash for attributes, got #{attributes.inspect}" unless attributes.is_a?(Hash)
57
+
57
58
  @association = attributes.delete(:association) || Association.new(:class => self.class)
58
59
  @global_params = attributes.delete(:global) || {}
59
60
  @client = client
@@ -177,7 +178,7 @@ module ZendeskAPI
177
178
  include Destroy
178
179
  end
179
180
 
180
- # Represents a resource that can CRUD (create, read, update, delete).
181
+ # Represents an abstract resource that can CRUD (create, read, update, delete).
181
182
  class Resource < DataResource
182
183
  include Read
183
184
  include Create
@@ -5,7 +5,6 @@ module ZendeskAPI
5
5
  class User < Resource; end
6
6
  class UserRelated < DataResource; end
7
7
  class Category < Resource; end
8
- class OrganizationMembership < ReadResource; end
9
8
  class OrganizationSubscription < ReadResource; end
10
9
 
11
10
  # @internal Begin actual Resource definitions
@@ -126,6 +125,10 @@ module ZendeskAPI
126
125
 
127
126
  class OrganizationRelated < DataResource; end
128
127
 
128
+ class OrganizationMembership < ReadResource
129
+ extend CreateOrUpdate
130
+ end
131
+
129
132
  class Organization < Resource
130
133
  extend CreateMany
131
134
  extend CreateOrUpdate
@@ -274,44 +277,6 @@ module ZendeskAPI
274
277
  has Group
275
278
  end
276
279
 
277
- class Search
278
- class Result < Data; end
279
-
280
- # Creates a search collection
281
- def self.search(client, options = {})
282
- unless (%w{query external_id} & options.keys.map(&:to_s)).any?
283
- warn "you have not specified a query for this search"
284
- end
285
-
286
- ZendeskAPI::Collection.new(client, self, options)
287
- end
288
-
289
- # Quack like a Resource
290
- # Creates the correct resource class from the result_type passed in
291
- def self.new(client, attributes)
292
- result_type = attributes["result_type"]
293
-
294
- if result_type
295
- result_type = ZendeskAPI::Helpers.modulize_string(result_type)
296
- klass = ZendeskAPI.const_get(result_type) rescue nil
297
- end
298
-
299
- (klass || Result).new(client, attributes)
300
- end
301
-
302
- class << self
303
- def resource_name
304
- "search"
305
- end
306
-
307
- alias :resource_path :resource_name
308
-
309
- def model_key
310
- "results"
311
- end
312
- end
313
- end
314
-
315
280
  class Request < Resource
316
281
  class Comment < DataResource
317
282
  include Save
@@ -793,6 +758,11 @@ module ZendeskAPI
793
758
 
794
759
  class Target < Resource; end
795
760
 
761
+ class Invocation < Resource; end
762
+ class Webhook < Resource
763
+ has_many Invocation
764
+ end
765
+
796
766
  module Voice
797
767
  include DataNamespace
798
768
 
@@ -0,0 +1,51 @@
1
+ # `zendesk_api` gem root
2
+ module ZendeskAPI
3
+ # A rich factory that returns a class for your searches
4
+ class Search
5
+ # Creates a search collection
6
+ def self.search(client, options = {})
7
+ if (options.keys.map(&:to_s) & %w[query external_id]).empty?
8
+ warn "you have not specified a query for this search"
9
+ end
10
+
11
+ ZendeskAPI::Collection.new(client, self, options)
12
+ end
13
+
14
+ # Quack like a Resource
15
+ # Creates the correct resource class from `attributes[:result_type]`
16
+ def self.new(client, attributes)
17
+ present_result_type = (attributes[:result_type] || attributes["result_type"]).to_s
18
+ result_type = ZendeskAPI::Helpers.modulize_string(present_result_type)
19
+ klass = begin
20
+ ZendeskAPI.const_get(result_type)
21
+ rescue NameError
22
+ Result
23
+ end
24
+
25
+ (klass || Result).new(client, attributes)
26
+ end
27
+
28
+ class Result < Data; end
29
+
30
+ class << self
31
+ def resource_name
32
+ "search"
33
+ end
34
+ alias resource_path resource_name
35
+
36
+ def model_key
37
+ "results"
38
+ end
39
+ end
40
+ end
41
+
42
+ # This will use cursor pagination by default
43
+ class SearchExport < Search
44
+ class << self
45
+ def resource_name
46
+ "search/export"
47
+ end
48
+ alias resource_path resource_name
49
+ end
50
+ end
51
+ end
@@ -1,3 +1,3 @@
1
1
  module ZendeskAPI
2
- VERSION = "1.31.0"
2
+ VERSION = "1.35.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zendesk_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.31.0
4
+ version: 1.35.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Davidovitz
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-07-13 00:00:00.000000000 Z
12
+ date: 2022-01-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -40,7 +40,7 @@ dependencies:
40
40
  version: 3.5.2
41
41
  - - "<"
42
42
  - !ruby/object:Gem::Version
43
- version: 5.0.0
43
+ version: 6.0.0
44
44
  type: :runtime
45
45
  prerelease: false
46
46
  version_requirements: !ruby/object:Gem::Requirement
@@ -50,7 +50,7 @@ dependencies:
50
50
  version: 3.5.2
51
51
  - - "<"
52
52
  - !ruby/object:Gem::Version
53
- version: 5.0.0
53
+ version: 6.0.0
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: inflection
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -130,6 +130,7 @@ files:
130
130
  - lib/zendesk_api/middleware/response/sanitize_response.rb
131
131
  - lib/zendesk_api/resource.rb
132
132
  - lib/zendesk_api/resources.rb
133
+ - lib/zendesk_api/search.rb
133
134
  - lib/zendesk_api/sideloading.rb
134
135
  - lib/zendesk_api/silent_mash.rb
135
136
  - lib/zendesk_api/track_changes.rb
@@ -143,9 +144,9 @@ licenses:
143
144
  - Apache-2.0
144
145
  metadata:
145
146
  bug_tracker_uri: https://github.com/zendesk/zendesk_api_client_rb/issues
146
- changelog_uri: https://github.com/zendesk/zendesk_api_client_rb/blob/v1.31.0/CHANGELOG.md
147
- documentation_uri: https://www.rubydoc.info/gems/zendesk_api/1.31.0
148
- source_code_uri: https://github.com/zendesk/zendesk_api_client_rb/tree/v1.31.0
147
+ changelog_uri: https://github.com/zendesk/zendesk_api_client_rb/blob/v1.35.0/CHANGELOG.md
148
+ documentation_uri: https://www.rubydoc.info/gems/zendesk_api/1.35.0
149
+ source_code_uri: https://github.com/zendesk/zendesk_api_client_rb/tree/v1.35.0
149
150
  wiki_uri: https://github.com/zendesk/zendesk_api_client_rb/wiki
150
151
  post_install_message:
151
152
  rdoc_options: []