intercom 3.9.5 → 4.1.3

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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +406 -236
  3. data/Rakefile +1 -1
  4. data/changes.txt +32 -0
  5. data/lib/intercom/api_operations/archive.rb +2 -1
  6. data/lib/intercom/api_operations/delete.rb +16 -0
  7. data/lib/intercom/api_operations/find.rb +5 -2
  8. data/lib/intercom/api_operations/find_all.rb +4 -3
  9. data/lib/intercom/api_operations/list.rb +4 -1
  10. data/lib/intercom/api_operations/load.rb +4 -2
  11. data/lib/intercom/api_operations/nested_resource.rb +70 -0
  12. data/lib/intercom/api_operations/save.rb +6 -4
  13. data/lib/intercom/api_operations/scroll.rb +4 -5
  14. data/lib/intercom/api_operations/search.rb +3 -2
  15. data/lib/intercom/article.rb +7 -0
  16. data/lib/intercom/base_collection_proxy.rb +73 -0
  17. data/lib/intercom/client.rb +36 -25
  18. data/lib/intercom/client_collection_proxy.rb +17 -39
  19. data/lib/intercom/collection.rb +7 -0
  20. data/lib/intercom/company.rb +8 -0
  21. data/lib/intercom/contact.rb +22 -3
  22. data/lib/intercom/conversation.rb +5 -0
  23. data/lib/intercom/data_attribute.rb +7 -0
  24. data/lib/intercom/deprecated_leads_collection_proxy.rb +22 -0
  25. data/lib/intercom/deprecated_resources.rb +13 -0
  26. data/lib/intercom/errors.rb +3 -0
  27. data/lib/intercom/extended_api_operations/segments.rb +3 -1
  28. data/lib/intercom/extended_api_operations/tags.rb +3 -1
  29. data/lib/intercom/lead.rb +21 -0
  30. data/lib/intercom/lib/dynamic_accessors.rb +9 -10
  31. data/lib/intercom/lib/typed_json_deserializer.rb +42 -37
  32. data/lib/intercom/note.rb +4 -0
  33. data/lib/intercom/request.rb +37 -33
  34. data/lib/intercom/scroll_collection_proxy.rb +38 -42
  35. data/lib/intercom/search_collection_proxy.rb +30 -65
  36. data/lib/intercom/section.rb +23 -0
  37. data/lib/intercom/segment.rb +4 -0
  38. data/lib/intercom/service/article.rb +20 -0
  39. data/lib/intercom/service/base_service.rb +7 -0
  40. data/lib/intercom/service/collection.rb +24 -0
  41. data/lib/intercom/service/company.rb +2 -12
  42. data/lib/intercom/service/contact.rb +31 -10
  43. data/lib/intercom/service/conversation.rb +12 -3
  44. data/lib/intercom/service/data_attribute.rb +20 -0
  45. data/lib/intercom/service/lead.rb +41 -0
  46. data/lib/intercom/service/note.rb +4 -8
  47. data/lib/intercom/service/section.rb +7 -0
  48. data/lib/intercom/service/subscription.rb +2 -2
  49. data/lib/intercom/service/tag.rb +9 -9
  50. data/lib/intercom/service/visitor.rb +17 -8
  51. data/lib/intercom/tag.rb +4 -0
  52. data/lib/intercom/traits/api_resource.rb +44 -18
  53. data/lib/intercom/traits/dirty_tracking.rb +8 -1
  54. data/lib/intercom/user.rb +12 -3
  55. data/lib/intercom/utils.rb +13 -2
  56. data/lib/intercom/version.rb +1 -1
  57. data/lib/intercom/visitor.rb +0 -2
  58. data/lib/intercom.rb +33 -22
  59. data/spec/spec_helper.rb +843 -520
  60. data/spec/unit/intercom/admin_spec.rb +2 -2
  61. data/spec/unit/intercom/article_spec.rb +40 -0
  62. data/spec/unit/intercom/base_collection_proxy_spec.rb +47 -0
  63. data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
  64. data/spec/unit/intercom/client_spec.rb +25 -26
  65. data/spec/unit/intercom/collection_spec.rb +32 -0
  66. data/spec/unit/intercom/company_spec.rb +18 -14
  67. data/spec/unit/intercom/contact_spec.rb +385 -33
  68. data/spec/unit/intercom/conversation_spec.rb +55 -7
  69. data/spec/unit/intercom/count_spec.rb +4 -4
  70. data/spec/unit/intercom/data_attribute_spec.rb +40 -0
  71. data/spec/unit/intercom/deprecated_leads_collection_proxy_spec.rb +17 -0
  72. data/spec/unit/intercom/event_spec.rb +9 -11
  73. data/spec/unit/intercom/job_spec.rb +24 -24
  74. data/spec/unit/intercom/lead_spec.rb +57 -0
  75. data/spec/unit/intercom/lib/flat_store_spec.rb +22 -20
  76. data/spec/unit/intercom/message_spec.rb +1 -1
  77. data/spec/unit/intercom/note_spec.rb +4 -10
  78. data/spec/unit/intercom/request_spec.rb +1 -1
  79. data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
  80. data/spec/unit/intercom/search_collection_proxy_spec.rb +32 -28
  81. data/spec/unit/intercom/section_spec.rb +32 -0
  82. data/spec/unit/intercom/segment_spec.rb +2 -2
  83. data/spec/unit/intercom/subscription_spec.rb +5 -6
  84. data/spec/unit/intercom/tag_spec.rb +22 -14
  85. data/spec/unit/intercom/team_spec.rb +2 -2
  86. data/spec/unit/intercom/traits/api_resource_spec.rb +107 -52
  87. data/spec/unit/intercom/user_spec.rb +224 -226
  88. data/spec/unit/intercom/visitor_spec.rb +49 -0
  89. data/spec/unit/intercom_spec.rb +5 -3
  90. metadata +34 -8
  91. data/lib/intercom/customer.rb +0 -10
  92. data/lib/intercom/service/customer.rb +0 -14
  93. data/spec/unit/intercom/visitors_spec.rb +0 -61
data/Rakefile CHANGED
@@ -18,4 +18,4 @@ Rake::TestTask.new("spec:integration") do |spec|
18
18
  end
19
19
 
20
20
  task :spec => "spec:unit"
21
- task :default => :spec
21
+ task :default => :spec
data/changes.txt CHANGED
@@ -1,3 +1,35 @@
1
+ 4.1.2
2
+ - Adding support for company delete.
3
+ - Adding support for archiving/unarchiving contacts.
4
+ - Adding support for listing contact segments.
5
+ - Fixed issue with scroll collection proxy.
6
+ - Fixed issue with running assignment rules on a conversation.
7
+
8
+ 4.1.1
9
+ - Fixed bug with deprecated lead resource.
10
+
11
+ 4.1.0
12
+ - Added support for new Articles API.
13
+ - Added support for new Collections API.
14
+ - Added support for new Sections API.
15
+ - Added support to equate two resources.
16
+ - Fixed issue for dirty tracking nested typed objects.
17
+
18
+ 4.0.1
19
+ - Fixed bug with nested resources.
20
+ - Support for add/remove contact on conversation object.
21
+
22
+ 4.0.0
23
+ New version to support API version 2.0.
24
+ - Added support for new Contacts API.
25
+ - Added support for Conversation Search and for Conversation model changes.
26
+ - New DataAttribute class to support the Data Attributes. See README for details on usage.
27
+ - New method to run assignment rules on a conversation: `intercom.conversations.run_assignment_rules(<convo_id>)`.
28
+ - See Migration guide for breaking changes: https://github.com/intercom/intercom-ruby/wiki/Migration-guide-for-v4
29
+
30
+ 3.9.5
31
+ Add Unstable version support
32
+
1
33
  3.9.4
2
34
  Add handling for Gateway Timeouts
3
35
 
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'intercom/utils'
2
4
 
3
5
  module Intercom
4
6
  module ApiOperations
5
7
  module Archive
6
8
  def archive(object)
7
- collection_name = Utils.resource_class_to_collection_name(collection_class)
8
9
  @client.delete("/#{collection_name}/#{object.id}", {})
9
10
  object
10
11
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'intercom/utils'
4
+
5
+ module Intercom
6
+ module ApiOperations
7
+ module Delete
8
+ def delete(object)
9
+ @client.delete("/#{collection_name}/#{object.id}", {})
10
+ object
11
+ end
12
+
13
+ alias_method 'archive', 'delete'
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'intercom/utils'
2
4
 
3
5
  module Intercom
@@ -5,14 +7,15 @@ module Intercom
5
7
  module Find
6
8
  def find(params)
7
9
  raise BadRequestError, "#{self}#find takes a hash as its parameter but you supplied #{params.inspect}" unless params.is_a? Hash
8
- collection_name = Utils.resource_class_to_collection_name(collection_class)
10
+
9
11
  if params[:id]
10
12
  id = params.delete(:id)
11
13
  response = @client.get("/#{collection_name}/#{id}", params)
12
14
  else
13
15
  response = @client.get("/#{collection_name}", params)
14
16
  end
15
- raise Intercom::HttpError.new('Http Error - No response entity returned') unless response
17
+ raise Intercom::HttpError, 'Http Error - No response entity returned' unless response
18
+
16
19
  from_api(response)
17
20
  end
18
21
  end
@@ -1,13 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'intercom/client_collection_proxy'
2
4
  require 'intercom/utils'
3
5
 
4
6
  module Intercom
5
7
  module ApiOperations
6
8
  module FindAll
7
-
8
9
  def find_all(params)
9
10
  raise BadRequestError, "#find takes a hash as its parameter but you supplied #{params.inspect}" unless params.is_a? Hash
10
- collection_name = Utils.resource_class_to_collection_name(collection_class)
11
+
11
12
  finder_details = {}
12
13
  if params[:id] && !type_switched_finder?(params)
13
14
  finder_details[:url] = "/#{collection_name}/#{params[:id]}"
@@ -16,7 +17,7 @@ module Intercom
16
17
  finder_details[:url] = "/#{collection_name}"
17
18
  finder_details[:params] = params
18
19
  end
19
- collection_proxy_class.new(collection_name, finder_details: finder_details, client: @client)
20
+ collection_proxy_class.new(collection_name, collection_class, details: finder_details, client: @client)
20
21
  end
21
22
 
22
23
  private
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'intercom/client_collection_proxy'
4
+ require 'intercom/base_collection_proxy'
2
5
  require 'intercom/utils'
3
6
 
4
7
  module Intercom
5
8
  module ApiOperations
6
9
  module List
7
10
  def all
8
- ClientCollectionProxy.new(Utils.resource_class_to_collection_name(collection_class), client: @client)
11
+ collection_proxy_class.new(collection_name, collection_class, client: @client)
9
12
  end
10
13
  end
11
14
  end
@@ -1,16 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'intercom/utils'
2
4
 
3
5
  module Intercom
4
6
  module ApiOperations
5
7
  module Load
6
8
  def load(object)
7
- collection_name = Utils.resource_class_to_collection_name(collection_class)
8
9
  if object.id
9
10
  response = @client.get("/#{collection_name}/#{object.id}", {})
10
11
  else
11
12
  raise "Cannot load #{collection_class} as it does not have a valid id."
12
13
  end
13
- raise Intercom::HttpError.new('Http Error - No response entity returned') unless response
14
+ raise Intercom::HttpError, 'Http Error - No response entity returned' unless response
15
+
14
16
  object.from_response(response)
15
17
  end
16
18
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Intercom
4
+ module ApiOperations
5
+ module NestedResource
6
+ module ClassMethods
7
+ def nested_resource_methods(resource,
8
+ path: nil,
9
+ operations: nil,
10
+ resource_plural: nil)
11
+ resource_plural ||= Utils.pluralize(resource.to_s)
12
+ path ||= resource_plural
13
+ raise ArgumentError, 'operations array required' if operations.nil?
14
+
15
+ resource_url_method = :"#{resource_plural}_url"
16
+
17
+ resource_name = Utils.resource_class_to_collection_name(self)
18
+
19
+ define_method(resource_url_method.to_sym) do |id, nested_id = nil|
20
+ url = "/#{resource_name}/#{id}/#{path}"
21
+ url += "/#{nested_id}" unless nested_id.nil?
22
+ url
23
+ end
24
+
25
+ operations.each do |operation|
26
+ case operation
27
+ when :create
28
+ define_method(:"create_#{resource}") do |params|
29
+ url = send(resource_url_method, self.id)
30
+ response = client.post(url, params)
31
+ raise_no_response_error unless response
32
+ self.class.from_api(response)
33
+ end
34
+ when :add
35
+ define_method(:"add_#{resource}") do |params|
36
+ url = send(resource_url_method, self.id)
37
+ response = client.post(url, params)
38
+ raise_no_response_error unless response
39
+ self.class.from_api(response)
40
+ end
41
+ when :delete
42
+ define_method(:"remove_#{resource}") do |params|
43
+ url = send(resource_url_method, self.id, params[:id])
44
+ response = client.delete(url, params)
45
+ raise_no_response_error unless response
46
+ self.class.from_api(response)
47
+ end
48
+ when :list
49
+ define_method(resource_plural.to_sym) do
50
+ url = send(resource_url_method, self.id)
51
+ resource_class = Utils.constantize_resource_name(resource.to_s)
52
+ resource_class.collection_proxy_class.new(resource_plural, resource_class, details: { url: url }, client: client)
53
+ end
54
+ else
55
+ raise ArgumentError, "Unknown operation: #{operation.inspect}"
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ def self.included(base)
62
+ base.extend(ClassMethods)
63
+ end
64
+
65
+ private def raise_no_response_error
66
+ raise Intercom::HttpError, 'Http Error - No response entity returned'
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'intercom/utils'
2
4
  require 'ext/sliceable_hash'
3
5
 
@@ -8,8 +10,8 @@ module Intercom
8
10
  private_constant :PARAMS_NOT_PROVIDED
9
11
 
10
12
  def create(params = PARAMS_NOT_PROVIDED)
11
- if collection_class.ancestors.include?(Intercom::Contact) && params == PARAMS_NOT_PROVIDED
12
- params = Hash.new
13
+ if collection_class.ancestors.include?(Intercom::Lead) && params == PARAMS_NOT_PROVIDED
14
+ params = {}
13
15
  elsif params == PARAMS_NOT_PROVIDED
14
16
  raise ArgumentError, '.create requires 1 parameter'
15
17
  end
@@ -20,17 +22,17 @@ module Intercom
20
22
  end
21
23
 
22
24
  def save(object)
23
- collection_name = Utils.resource_class_to_collection_name(collection_class)
24
25
  if id_present?(object) && !posted_updates?(object)
25
26
  response = @client.put("/#{collection_name}/#{object.id}", object.to_submittable_hash)
26
27
  else
27
28
  response = @client.post("/#{collection_name}", object.to_submittable_hash.merge(identity_hash(object)))
28
29
  end
30
+ object.client = @client
29
31
  object.from_response(response) if response # may be nil we received back a 202
30
32
  end
31
33
 
32
34
  def identity_hash(object)
33
- object.respond_to?(:identity_vars) ? SliceableHash.new(object.to_hash).slice(*(object.identity_vars.map(&:to_s))) : {}
35
+ object.respond_to?(:identity_vars) ? SliceableHash.new(object.to_hash).slice(*object.identity_vars.map(&:to_s)) : {}
34
36
  end
35
37
 
36
38
  private
@@ -1,17 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'intercom/scroll_collection_proxy'
2
4
  require 'intercom/utils'
3
5
 
4
6
  module Intercom
5
7
  module ApiOperations
6
8
  module Scroll
7
-
8
- def scroll()
9
- collection_name = Utils.resource_class_to_collection_name(collection_class)
9
+ def scroll
10
10
  finder_details = {}
11
11
  finder_details[:url] = "/#{collection_name}"
12
- ScrollCollectionProxy.new(collection_name, finder_details: finder_details, client: @client)
12
+ ScrollCollectionProxy.new(collection_name, collection_class, details: finder_details, client: @client)
13
13
  end
14
-
15
14
  end
16
15
  end
17
16
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'intercom/search_collection_proxy'
2
4
  require 'intercom/utils'
3
5
 
@@ -5,12 +7,11 @@ module Intercom
5
7
  module ApiOperations
6
8
  module Search
7
9
  def search(params)
8
- collection_name = Utils.resource_class_to_collection_name(collection_class)
9
10
  search_details = {
10
11
  url: "/#{collection_name}/search",
11
12
  params: params
12
13
  }
13
- SearchCollectionProxy.new(collection_name, search_details: search_details, client: @client)
14
+ SearchCollectionProxy.new(collection_name, collection_class, details: search_details, client: @client)
14
15
  end
15
16
  end
16
17
  end
@@ -0,0 +1,7 @@
1
+ require 'intercom/traits/api_resource'
2
+
3
+ module Intercom
4
+ class Article
5
+ include Traits::ApiResource
6
+ end
7
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'intercom/utils'
4
+
5
+ module Intercom
6
+ class BaseCollectionProxy
7
+ attr_reader :resource_name, :url, :resource_class
8
+
9
+ def initialize(resource_name, resource_class, details: {}, client:, method: 'get')
10
+ @resource_name = resource_name
11
+ @resource_class = resource_class
12
+ @url = (details[:url] || "/#{@resource_name}")
13
+ @params = (details[:params] || {})
14
+ @client = client
15
+ @method = method
16
+ end
17
+
18
+ def each(&block)
19
+ loop do
20
+ response_hash = @client.public_send(@method, @url, payload)
21
+ raise Intercom::HttpError, 'Http Error - No response entity returned' unless response_hash
22
+
23
+ deserialize_response_hash(response_hash, block)
24
+ break unless has_next_link?(response_hash)
25
+ end
26
+ self
27
+ end
28
+
29
+ def [](target_index)
30
+ each_with_index do |item, index|
31
+ return item if index == target_index
32
+ end
33
+ nil
34
+ end
35
+
36
+ include Enumerable
37
+
38
+ private
39
+
40
+ def deserialize_response_hash(response_hash, block)
41
+ top_level_type = response_hash.delete('type')
42
+ top_level_entity_key = if resource_name == 'subscriptions'
43
+ 'items'
44
+ else
45
+ Utils.entity_key_from_type(top_level_type)
46
+ end
47
+ response_hash[top_level_entity_key].each do |object_json|
48
+ block.call Lib::TypedJsonDeserializer.new(object_json, @client).deserialize
49
+ end
50
+ end
51
+
52
+ def has_next_link?(response_hash)
53
+ paging_info = response_hash.delete('pages')
54
+ return false unless paging_info
55
+
56
+ paging_next = paging_info['next']
57
+ if paging_next
58
+ @params[:starting_after] = paging_next['starting_after']
59
+ return true
60
+ else
61
+ @params[:starting_after] = nil
62
+ return false
63
+ end
64
+ end
65
+
66
+ def payload
67
+ payload = {}
68
+ payload[:per_page] = @params[:per_page] if @params[:per_page]
69
+ payload[:starting_after] = @params[:starting_after] if @params[:starting_after]
70
+ payload
71
+ end
72
+ end
73
+ end
@@ -1,38 +1,35 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Intercom
2
4
  class MisconfiguredClientError < StandardError; end
3
5
  class Client
4
6
  include Options
5
- attr_reader :base_url, :rate_limit_details, :username_part, :password_part, :handle_rate_limit, :timeouts, :api_version
7
+ include DeprecatedResources
8
+ attr_reader :base_url, :rate_limit_details, :token, :handle_rate_limit, :timeouts, :api_version
6
9
 
7
10
  class << self
8
11
  def set_base_url(base_url)
9
- return Proc.new do |o|
12
+ proc do |o|
10
13
  old_url = o.base_url
11
14
  o.send(:base_url=, base_url)
12
- Proc.new { |obj| set_base_url(old_url).call(o) }
15
+ proc { |_obj| set_base_url(old_url).call(o) }
13
16
  end
14
17
  end
15
18
 
16
19
  def set_timeouts(open_timeout: nil, read_timeout: nil)
17
- return Proc.new do |o|
20
+ proc do |o|
18
21
  old_timeouts = o.timeouts
19
22
  timeouts = {}
20
23
  timeouts[:open_timeout] = open_timeout if open_timeout
21
24
  timeouts[:read_timeout] = read_timeout if read_timeout
22
25
  o.send(:timeouts=, timeouts)
23
- Proc.new { |obj| set_timeouts(old_timeouts).call(o) }
26
+ proc { |_obj| set_timeouts(old_timeouts).call(o) }
24
27
  end
25
28
  end
26
29
  end
27
30
 
28
- def initialize(app_id: 'my_app_id', api_key: 'my_api_key', token: nil, base_url:'https://api.intercom.io', handle_rate_limit: false, api_version: nil)
29
- if token
30
- @username_part = token
31
- @password_part = ""
32
- else
33
- @username_part = app_id
34
- @password_part = api_key
35
- end
31
+ def initialize(token: nil, base_url: 'https://api.intercom.io', handle_rate_limit: false, api_version: nil)
32
+ @token = token
36
33
  validate_credentials!
37
34
 
38
35
  @api_version = api_version
@@ -51,6 +48,10 @@ module Intercom
51
48
  Intercom::Service::Admin.new(self)
52
49
  end
53
50
 
51
+ def articles
52
+ Intercom::Service::Article.new(self)
53
+ end
54
+
54
55
  def companies
55
56
  Intercom::Service::Company.new(self)
56
57
  end
@@ -67,10 +68,6 @@ module Intercom
67
68
  Intercom::Service::Counts.new(self)
68
69
  end
69
70
 
70
- def customers
71
- Intercom::Service::Customer.new(self)
72
- end
73
-
74
71
  def events
75
72
  Intercom::Service::Event.new(self)
76
73
  end
@@ -91,6 +88,10 @@ module Intercom
91
88
  Intercom::Service::Segment.new(self)
92
89
  end
93
90
 
91
+ def sections
92
+ Intercom::Service::Section.new(self)
93
+ end
94
+
94
95
  def tags
95
96
  Intercom::Service::Tag.new(self)
96
97
  end
@@ -103,6 +104,10 @@ module Intercom
103
104
  Intercom::Service::User.new(self)
104
105
  end
105
106
 
107
+ def leads
108
+ Intercom::Service::Lead.new(self)
109
+ end
110
+
106
111
  def visitors
107
112
  Intercom::Service::Visitor.new(self)
108
113
  end
@@ -111,6 +116,14 @@ module Intercom
111
116
  Intercom::Service::Job.new(self)
112
117
  end
113
118
 
119
+ def data_attributes
120
+ Intercom::Service::DataAttribute.new(self)
121
+ end
122
+
123
+ def collections
124
+ Intercom::Service::Collection.new(self)
125
+ end
126
+
114
127
  def get(path, params)
115
128
  execute_request Intercom::Request.get(path, params)
116
129
  end
@@ -130,25 +143,23 @@ module Intercom
130
143
  private
131
144
 
132
145
  def validate_credentials!
133
- error = MisconfiguredClientError.new("app_id and api_key must not be nil")
134
- fail error if @username_part.nil?
146
+ error = MisconfiguredClientError.new('an access token must be provided')
147
+ raise error if @token.nil?
135
148
  end
136
149
 
137
150
  def validate_api_version!
138
- error = MisconfiguredClientError.new("api_version must be either nil or a valid API version")
139
- fail error if (@api_version && @api_version != 'Unstable' && Gem::Version.new(@api_version) < Gem::Version.new('1.0'))
151
+ error = MisconfiguredClientError.new('api_version must be either nil or a valid API version')
152
+ raise error if @api_version && @api_version != 'Unstable' && Gem::Version.new(@api_version) < Gem::Version.new('1.0')
140
153
  end
141
154
 
142
155
  def execute_request(request)
143
156
  request.handle_rate_limit = handle_rate_limit
144
- request.execute(@base_url, username: @username_part, secret: @password_part, api_version: @api_version, **timeouts)
157
+ request.execute(@base_url, token: @token, api_version: @api_version, **timeouts)
145
158
  ensure
146
159
  @rate_limit_details = request.rate_limit_details
147
160
  end
148
161
 
149
- def base_url=(new_url)
150
- @base_url = new_url
151
- end
162
+ attr_writer :base_url
152
163
 
153
164
  def timeouts=(timeouts)
154
165
  @timeouts = @timeouts.merge(timeouts)
@@ -1,71 +1,49 @@
1
- require "intercom/utils"
1
+ # frozen_string_literal: true
2
2
 
3
- module Intercom
4
- class ClientCollectionProxy
5
-
6
- attr_reader :resource_name, :finder_url, :resource_class
7
-
8
- def initialize(resource_name, finder_details: {}, client:)
9
- @resource_name = resource_name
10
- @resource_class = Utils.constantize_resource_name(resource_name)
11
- @finder_url = (finder_details[:url] || "/#{@resource_name}")
12
- @finder_params = (finder_details[:params] || {})
13
- @client = client
14
- end
3
+ require 'intercom/utils'
4
+ require 'intercom/base_collection_proxy'
15
5
 
6
+ module Intercom
7
+ class ClientCollectionProxy < BaseCollectionProxy
16
8
  def each(&block)
17
9
  next_page = nil
18
10
  current_page = nil
19
11
  loop do
20
- if next_page
21
- response_hash = @client.get(next_page, {})
22
- else
23
- response_hash = @client.get(@finder_url, @finder_params)
24
- end
25
- raise Intercom::HttpError.new('Http Error - No response entity returned') unless response_hash
12
+ response_hash = fetch(next_page)
13
+ raise Intercom::HttpError, 'Http Error - No response entity returned' unless response_hash
14
+
26
15
  current_page = extract_current_page(response_hash)
27
16
  deserialize_response_hash(response_hash, block)
28
17
  next_page = extract_next_link(response_hash)
29
- break if next_page.nil? or (@finder_params[:page] and (current_page >= @finder_params[:page]))
18
+ break if next_page.nil? || (@params[:page] && (current_page >= @params[:page]))
30
19
  end
31
20
  self
32
21
  end
33
22
 
34
- def [](target_index)
35
- self.each_with_index do |item, index|
36
- return item if index == target_index
23
+ def fetch(next_page)
24
+ if next_page
25
+ @client.get(next_page, {})
26
+ else
27
+ @client.get(@url, @params)
37
28
  end
38
- nil
39
29
  end
40
30
 
41
- include Enumerable
42
-
43
31
  private
44
32
 
45
- def deserialize_response_hash(response_hash, block)
46
- top_level_type = response_hash.delete('type')
47
- if resource_name == 'subscriptions'
48
- top_level_entity_key = 'items'
49
- else
50
- top_level_entity_key = Utils.entity_key_from_type(top_level_type)
51
- end
52
- response_hash[top_level_entity_key].each do |object_json|
53
- block.call Lib::TypedJsonDeserializer.new(object_json).deserialize
54
- end
55
- end
56
-
57
33
  def paging_info_present?(response_hash)
58
34
  !!(response_hash['pages'] && response_hash['pages']['type'])
59
35
  end
60
36
 
61
37
  def extract_next_link(response_hash)
62
38
  return nil unless paging_info_present?(response_hash)
39
+
63
40
  paging_info = response_hash.delete('pages')
64
- paging_info["next"]
41
+ paging_info['next']
65
42
  end
66
43
 
67
44
  def extract_current_page(response_hash)
68
45
  return nil unless paging_info_present?(response_hash)
46
+
69
47
  response_hash['pages']['page']
70
48
  end
71
49
  end
@@ -0,0 +1,7 @@
1
+ require 'intercom/traits/api_resource'
2
+
3
+ module Intercom
4
+ class Collection
5
+ include Traits::ApiResource
6
+ end
7
+ end
@@ -1,10 +1,18 @@
1
1
  require 'intercom/traits/incrementable_attributes'
2
2
  require 'intercom/traits/api_resource'
3
+ require 'intercom/api_operations/nested_resource'
3
4
 
4
5
  module Intercom
5
6
  class Company
6
7
  include Traits::IncrementableAttributes
7
8
  include Traits::ApiResource
9
+ include ApiOperations::NestedResource
10
+
11
+ nested_resource_methods :contact, operations: %i[list]
12
+
13
+ def self.collection_proxy_class
14
+ Intercom::ClientCollectionProxy
15
+ end
8
16
 
9
17
  def identity_vars ; [:id, :company_id] ; end
10
18
  def flat_store_attributes ; [:custom_attributes] ; end