intercom 3.9.5 → 4.1.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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +355 -222
  3. data/Rakefile +1 -1
  4. data/changes.txt +25 -0
  5. data/lib/intercom.rb +33 -22
  6. data/lib/intercom/api_operations/archive.rb +2 -1
  7. data/lib/intercom/api_operations/delete.rb +16 -0
  8. data/lib/intercom/api_operations/find.rb +5 -2
  9. data/lib/intercom/api_operations/find_all.rb +4 -3
  10. data/lib/intercom/api_operations/list.rb +4 -1
  11. data/lib/intercom/api_operations/load.rb +4 -2
  12. data/lib/intercom/api_operations/nested_resource.rb +70 -0
  13. data/lib/intercom/api_operations/save.rb +6 -4
  14. data/lib/intercom/api_operations/scroll.rb +4 -5
  15. data/lib/intercom/api_operations/search.rb +3 -2
  16. data/lib/intercom/article.rb +7 -0
  17. data/lib/intercom/base_collection_proxy.rb +72 -0
  18. data/lib/intercom/client.rb +36 -25
  19. data/lib/intercom/client_collection_proxy.rb +17 -39
  20. data/lib/intercom/collection.rb +7 -0
  21. data/lib/intercom/company.rb +8 -0
  22. data/lib/intercom/contact.rb +22 -3
  23. data/lib/intercom/conversation.rb +5 -0
  24. data/lib/intercom/data_attribute.rb +7 -0
  25. data/lib/intercom/deprecated_leads_collection_proxy.rb +22 -0
  26. data/lib/intercom/deprecated_resources.rb +13 -0
  27. data/lib/intercom/errors.rb +3 -0
  28. data/lib/intercom/extended_api_operations/segments.rb +3 -1
  29. data/lib/intercom/extended_api_operations/tags.rb +3 -1
  30. data/lib/intercom/lead.rb +21 -0
  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/spec/spec_helper.rb +843 -520
  59. data/spec/unit/intercom/admin_spec.rb +2 -2
  60. data/spec/unit/intercom/article_spec.rb +40 -0
  61. data/spec/unit/intercom/base_collection_proxy_spec.rb +30 -0
  62. data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
  63. data/spec/unit/intercom/client_spec.rb +25 -26
  64. data/spec/unit/intercom/collection_spec.rb +32 -0
  65. data/spec/unit/intercom/company_spec.rb +18 -14
  66. data/spec/unit/intercom/contact_spec.rb +363 -33
  67. data/spec/unit/intercom/conversation_spec.rb +55 -7
  68. data/spec/unit/intercom/count_spec.rb +4 -4
  69. data/spec/unit/intercom/data_attribute_spec.rb +40 -0
  70. data/spec/unit/intercom/deprecated_leads_collection_proxy_spec.rb +17 -0
  71. data/spec/unit/intercom/event_spec.rb +9 -11
  72. data/spec/unit/intercom/job_spec.rb +24 -24
  73. data/spec/unit/intercom/lead_spec.rb +57 -0
  74. data/spec/unit/intercom/lib/flat_store_spec.rb +22 -20
  75. data/spec/unit/intercom/message_spec.rb +1 -1
  76. data/spec/unit/intercom/note_spec.rb +4 -10
  77. data/spec/unit/intercom/request_spec.rb +1 -1
  78. data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
  79. data/spec/unit/intercom/search_collection_proxy_spec.rb +32 -28
  80. data/spec/unit/intercom/section_spec.rb +32 -0
  81. data/spec/unit/intercom/segment_spec.rb +2 -2
  82. data/spec/unit/intercom/subscription_spec.rb +5 -6
  83. data/spec/unit/intercom/tag_spec.rb +22 -14
  84. data/spec/unit/intercom/team_spec.rb +2 -2
  85. data/spec/unit/intercom/traits/api_resource_spec.rb +107 -52
  86. data/spec/unit/intercom/user_spec.rb +224 -226
  87. data/spec/unit/intercom/visitor_spec.rb +49 -0
  88. data/spec/unit/intercom_spec.rb +5 -3
  89. metadata +37 -11
  90. data/lib/intercom/customer.rb +0 -10
  91. data/lib/intercom/service/customer.rb +0 -14
  92. data/spec/unit/intercom/visitors_spec.rb +0 -61
@@ -4,5 +4,9 @@ require 'intercom/traits/api_resource'
4
4
  module Intercom
5
5
  class Note
6
6
  include Traits::ApiResource
7
+
8
+ def self.collection_proxy_class
9
+ Intercom::BaseCollectionProxy
10
+ end
7
11
  end
8
12
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cgi'
2
4
  require 'net/https'
3
5
 
@@ -23,17 +25,18 @@ module Intercom
23
25
  private def method_with_body(http_method, path, params)
24
26
  request = http_method.send(:new, path, default_headers)
25
27
  request.body = params.to_json
26
- request["Content-Type"] = "application/json"
28
+ request['Content-Type'] = 'application/json'
27
29
  request
28
30
  end
29
31
 
30
32
  private def default_headers
31
- {'Accept-Encoding' => 'gzip, deflate', 'Accept' => 'application/vnd.intercom.3+json', 'User-Agent' => "Intercom-Ruby/#{Intercom::VERSION}"}
33
+ { 'Accept-Encoding' => 'gzip, deflate', 'Accept' => 'application/vnd.intercom.3+json', 'User-Agent' => "Intercom-Ruby/#{Intercom::VERSION}" }
32
34
  end
33
35
 
34
36
  private def append_query_string_to_url(url, params)
35
37
  return url if params.empty?
36
- query_string = params.map { |k, v| "#{k.to_s}=#{CGI::escape(v.to_s)}" }.join('&')
38
+
39
+ query_string = params.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&')
37
40
  url + "?#{query_string}"
38
41
  end
39
42
  end
@@ -46,11 +49,11 @@ module Intercom
46
49
 
47
50
  attr_accessor :handle_rate_limit
48
51
 
49
- def execute(target_base_url=nil, username:, secret: nil, read_timeout: 90, open_timeout: 30, api_version: nil)
52
+ def execute(target_base_url = nil, token:, read_timeout: 90, open_timeout: 30, api_version: nil)
50
53
  retries = 3
51
54
  base_uri = URI.parse(target_base_url)
52
55
  set_common_headers(net_http_method, base_uri)
53
- set_basic_auth(net_http_method, username, secret)
56
+ set_auth_header(net_http_method, token)
54
57
  set_api_version(net_http_method, api_version) if api_version
55
58
  begin
56
59
  client(base_uri, read_timeout: read_timeout, open_timeout: open_timeout).start do |http|
@@ -71,7 +74,7 @@ module Intercom
71
74
  if @handle_rate_limit
72
75
  seconds_to_retry = (@rate_limit_details[:reset_at] - Time.now.utc).ceil
73
76
  if (retries -= 1) < 0
74
- raise Intercom::RateLimitExceeded.new('Rate limit retries exceeded. Please examine current API Usage.')
77
+ raise Intercom::RateLimitExceeded, 'Rate limit retries exceeded. Please examine current API Usage.'
75
78
  else
76
79
  sleep seconds_to_retry unless seconds_to_retry < 0
77
80
  retry
@@ -80,11 +83,11 @@ module Intercom
80
83
  raise e
81
84
  end
82
85
  rescue Timeout::Error
83
- raise Intercom::ServiceUnavailableError.new('Service Unavailable [request timed out]')
86
+ raise Intercom::ServiceUnavailableError, 'Service Unavailable [request timed out]'
84
87
  end
85
88
  end
86
89
  rescue Timeout::Error
87
- raise Intercom::ServiceConnectionError.new('Failed to connect to service [connection attempt timed out]')
90
+ raise Intercom::ServiceConnectionError, 'Failed to connect to service [connection attempt timed out]'
88
91
  end
89
92
  end
90
93
 
@@ -114,8 +117,9 @@ module Intercom
114
117
  end
115
118
 
116
119
  private def decode(content_encoding, body)
117
- return body if (!body) || body.empty? || content_encoding != 'gzip'
118
- Zlib::GzipReader.new(StringIO.new(body)).read.force_encoding("utf-8")
120
+ return body if !body || body.empty? || content_encoding != 'gzip'
121
+
122
+ Zlib::GzipReader.new(StringIO.new(body)).read.force_encoding('utf-8')
119
123
  end
120
124
 
121
125
  private def json_parse_response(str, code)
@@ -123,7 +127,7 @@ module Intercom
123
127
 
124
128
  JSON.parse(str)
125
129
  rescue JSON::ParserError
126
- msg = <<~MSG.gsub(/[[:space:]]+/, " ").strip # #squish from ActiveSuppor
130
+ msg = <<~MSG.gsub(/[[:space:]]+/, ' ').strip # #squish from ActiveSuppor
127
131
  Expected a JSON response body. Instead got '#{str}'
128
132
  with status code '#{code}'.
129
133
  MSG
@@ -139,12 +143,12 @@ module Intercom
139
143
  @rate_limit_details = rate_limit_details
140
144
  end
141
145
 
142
- private def set_common_headers(method, base_uri)
146
+ private def set_common_headers(method, _base_uri)
143
147
  method.add_field('AcceptEncoding', 'gzip, deflate')
144
148
  end
145
149
 
146
- private def set_basic_auth(method, username, secret)
147
- method.basic_auth(CGI.unescape(username), CGI.unescape(secret))
150
+ private def set_auth_header(method, token)
151
+ method.add_field('Authorization', "Bearer #{token}")
148
152
  end
149
153
 
150
154
  private def set_api_version(method, api_version)
@@ -155,21 +159,21 @@ module Intercom
155
159
  code = res.code.to_i
156
160
 
157
161
  if code == 404
158
- raise Intercom::ResourceNotFound.new('Resource Not Found')
162
+ raise Intercom::ResourceNotFound, 'Resource Not Found'
159
163
  elsif code == 401
160
- raise Intercom::AuthenticationError.new('Unauthorized')
164
+ raise Intercom::AuthenticationError, 'Unauthorized'
161
165
  elsif code == 403
162
- raise Intercom::AuthenticationError.new('Forbidden')
166
+ raise Intercom::AuthenticationError, 'Forbidden'
163
167
  elsif code == 429
164
- raise Intercom::RateLimitExceeded.new('Rate Limit Exceeded')
168
+ raise Intercom::RateLimitExceeded, 'Rate Limit Exceeded'
165
169
  elsif code == 500
166
- raise Intercom::ServerError.new('Server Error')
170
+ raise Intercom::ServerError, 'Server Error'
167
171
  elsif code == 502
168
- raise Intercom::BadGatewayError.new('Bad Gateway Error')
172
+ raise Intercom::BadGatewayError, 'Bad Gateway Error'
169
173
  elsif code == 503
170
- raise Intercom::ServiceUnavailableError.new('Service Unavailable')
174
+ raise Intercom::ServiceUnavailableError, 'Service Unavailable'
171
175
  elsif code == 504
172
- raise Intercom::GatewayTimeoutError.new('Gateway Timeout')
176
+ raise Intercom::GatewayTimeoutError, 'Gateway Timeout'
173
177
  end
174
178
  end
175
179
 
@@ -180,10 +184,10 @@ module Intercom
180
184
  error_field = error_details['field']
181
185
  parsed_http_code = (http_code > 0 ? http_code : nil)
182
186
  error_context = {
183
- :http_code => parsed_http_code,
184
- :application_error_code => error_code,
185
- :field => error_field,
186
- :request_id => error_list_details['request_id']
187
+ http_code: parsed_http_code,
188
+ application_error_code: error_code,
189
+ field: error_field,
190
+ request_id: error_list_details['request_id']
187
191
  }
188
192
  case error_code
189
193
  when 'unauthorized', 'forbidden', 'token_not_found'
@@ -194,19 +198,19 @@ module Intercom
194
198
  raise Intercom::TokenRevokedError.new(error_details['message'], error_context)
195
199
  when 'token_unauthorized'
196
200
  raise Intercom::TokenUnauthorizedError.new(error_details['message'], error_context)
197
- when "bad_request", "missing_parameter", 'parameter_invalid', 'parameter_not_found'
201
+ when 'bad_request', 'missing_parameter', 'parameter_invalid', 'parameter_not_found'
198
202
  raise Intercom::BadRequestError.new(error_details['message'], error_context)
199
- when "not_restorable"
203
+ when 'not_restorable'
200
204
  raise Intercom::BlockedUserError.new(error_details['message'], error_context)
201
- when "not_found", "company_not_found"
205
+ when 'not_found', 'company_not_found'
202
206
  raise Intercom::ResourceNotFound.new(error_details['message'], error_context)
203
- when "admin_not_found"
207
+ when 'admin_not_found'
204
208
  raise Intercom::AdminNotFound.new(error_details['message'], error_context)
205
- when "rate_limit_exceeded"
209
+ when 'rate_limit_exceeded'
206
210
  raise Intercom::RateLimitExceeded.new(error_details['message'], error_context)
207
- when "custom_data_limit_reached"
211
+ when 'custom_data_limit_reached'
208
212
  raise Intercom::CDALimitReachedError.new(error_details['message'], error_context)
209
- when "invalid_document"
213
+ when 'invalid_document'
210
214
  raise Intercom::InvalidDocumentError.new(error_details['message'], error_context)
211
215
  when 'service_unavailable'
212
216
  raise Intercom::ServiceUnavailableError.new(error_details['message'], error_context)
@@ -1,32 +1,34 @@
1
- require "intercom/utils"
1
+ # frozen_string_literal: true
2
2
 
3
- module Intercom
4
- class ScrollCollectionProxy
3
+ require 'intercom/utils'
4
+ require 'intercom/base_collection_proxy'
5
5
 
6
- attr_reader :resource_name, :scroll_url, :resource_class, :scroll_param, :records
6
+ module Intercom
7
+ class ScrollCollectionProxy < BaseCollectionProxy
8
+ attr_reader :scroll_url, :scroll_param, :records
7
9
 
8
- def initialize(resource_name, finder_details: {}, client:)
10
+ def initialize(resource_name, resource_class, details: {}, client:)
9
11
  @resource_name = resource_name
10
- @resource_class = Utils.constantize_resource_name(resource_name)
11
- @scroll_url = (finder_details[:url] || "/#{@resource_name}") + '/scroll'
12
+ @resource_class = resource_class
13
+ @scroll_url = (details[:url] || "/#{@resource_name}") + '/scroll'
12
14
  @client = client
13
-
14
15
  end
15
16
 
16
- def next(scroll_parameter=nil)
17
+ def next(scroll_parameter = nil)
17
18
  @records = []
18
- if not scroll_parameter
19
- #First time so do initial get without scroll_param
20
- response_hash = @client.get(@scroll_url, '')
21
- else
22
- #Not first call so use get next page
23
- response_hash = @client.get(@scroll_url, scroll_param: scroll_parameter)
24
- end
25
- raise Intercom::HttpError.new('Http Error - No response entity returned') unless response_hash
19
+ response_hash = if !scroll_parameter
20
+ # First time so do initial get without scroll_param
21
+ @client.get(@scroll_url, '')
22
+ else
23
+ # Not first call so use get next page
24
+ @client.get(@scroll_url, scroll_param: scroll_parameter)
25
+ end
26
+ raise Intercom::HttpError, 'Http Error - No response entity returned' unless response_hash
27
+
26
28
  @scroll_param = extract_scroll_param(response_hash)
27
- top_level_entity_key = deserialize_response_hash(response_hash)
29
+ top_level_entity_key = entity_key_from_response(response_hash)
28
30
  response_hash[top_level_entity_key] = response_hash[top_level_entity_key].map do |object_json|
29
- Lib::TypedJsonDeserializer.new(object_json).deserialize
31
+ Lib::TypedJsonDeserializer.new(object_json, @client).deserialize
30
32
  end
31
33
  @records = response_hash[@resource_name]
32
34
  self
@@ -35,47 +37,41 @@ module Intercom
35
37
  def each(&block)
36
38
  scroll_param = nil
37
39
  loop do
38
- if not scroll_param
39
- response_hash = @client.get(@scroll_url, '')
40
- else
41
- response_hash = @client.get(@scroll_url, scroll_param: scroll_param)
42
- end
43
- raise Intercom::HttpError.new('Http Error - No response entity returned') unless response_hash
44
- response_hash[deserialize_response_hash(response_hash)].each do |object_json|
45
- block.call Lib::TypedJsonDeserializer.new(object_json).deserialize
40
+ response_hash = if !scroll_param
41
+ @client.get(@scroll_url, '')
42
+ else
43
+ @client.get(@scroll_url, scroll_param: scroll_param)
44
+ end
45
+ raise Intercom::HttpError, 'Http Error - No response entity returned' unless response_hash
46
+
47
+ top_level_entity_key = entity_key_from_response(response_hash)
48
+ response_hash[top_level_entity_key].each do |object_json|
49
+ block.call Lib::TypedJsonDeserializer.new(object_json, @client).deserialize
46
50
  end
47
51
  scroll_param = extract_scroll_param(response_hash)
48
- break if not records_present?(response_hash)
52
+ break unless records_present?(response_hash)
49
53
  end
50
54
  self
51
55
  end
52
56
 
53
- def [](target_index)
54
- self.each_with_index do |item, index|
55
- return item if index == target_index
56
- end
57
- nil
58
- end
59
-
60
- include Enumerable
61
-
62
57
  private
63
58
 
64
- def deserialize_response_hash(response_hash)
65
- top_level_type = response_hash.delete('type')
59
+ def entity_key_from_response(response_hash)
60
+ top_level_type = response_hash['type']
66
61
  if resource_name == 'subscriptions'
67
- top_level_entity_key = 'items'
62
+ 'items'
68
63
  else
69
- top_level_entity_key = Utils.entity_key_from_type(top_level_type)
64
+ Utils.entity_key_from_type(top_level_type)
70
65
  end
71
66
  end
72
67
 
73
68
  def records_present?(response_hash)
74
- (response_hash[@resource_name].length > 0)
69
+ !response_hash[entity_key_from_response(response_hash)].empty?
75
70
  end
76
71
 
77
72
  def extract_scroll_param(response_hash)
78
73
  return nil unless records_present?(response_hash)
74
+
79
75
  response_hash['scroll_param']
80
76
  end
81
77
  end
@@ -1,82 +1,47 @@
1
- require "intercom/utils"
1
+ # frozen_string_literal: true
2
2
 
3
- module Intercom
4
- class SearchCollectionProxy
5
-
6
- attr_reader :resource_name, :resource_class
7
-
8
- def initialize(resource_name, search_details: {}, client:)
9
- @resource_name = resource_name
10
- @resource_class = Utils.constantize_resource_name(resource_name)
11
- @search_url = search_details[:url]
12
- @search_params = search_details[:params]
13
- @client = client
14
- end
15
-
16
- def each(&block)
17
- loop do
18
- response_hash = @client.post(@search_url, payload)
19
- raise Intercom::HttpError.new('Http Error - No response entity returned') unless response_hash
20
- deserialize_response_hash(response_hash, block)
21
- break unless has_next_link?(response_hash)
22
- end
23
- self
24
- end
3
+ require 'intercom/utils'
4
+ require 'intercom/base_collection_proxy'
25
5
 
26
- def [](target_index)
27
- self.each_with_index do |item, index|
28
- return item if index == target_index
29
- end
30
- nil
6
+ module Intercom
7
+ class SearchCollectionProxy < BaseCollectionProxy
8
+ def initialize(resource_name, resource_class, details: {}, client:)
9
+ super(resource_name, resource_class, details: details, client: client, method: 'post')
31
10
  end
32
11
 
33
- include Enumerable
34
-
35
12
  private
36
13
 
37
- def deserialize_response_hash(response_hash, block)
38
- top_level_type = response_hash.delete('type')
39
- top_level_entity_key = Utils.entity_key_from_type(top_level_type)
40
- response_hash[top_level_entity_key].each do |object_json|
41
- block.call Lib::TypedJsonDeserializer.new(object_json).deserialize
42
- end
43
- end
44
-
45
- def has_next_link?(response_hash)
46
- paging_info = response_hash.delete('pages')
47
- paging_next = paging_info["next"]
48
- if paging_next
49
- @search_params[:starting_after] = paging_next["starting_after"]
50
- return true
51
- else
52
- return false
53
- end
54
- end
55
-
56
14
  def payload
57
15
  payload = {
58
- query: @search_params[:query]
16
+ query: @params[:query]
59
17
  }
60
- if @search_params[:sort_field] || @search_params[:sort_order]
18
+ if sort_field || sort_order
61
19
  payload[:sort] = {}
62
- if @search_params[:sort_field]
63
- payload[:sort][:field] = @search_params[:sort_field]
64
- end
65
- if @search_params[:sort_order]
66
- payload[:sort][:order] = @search_params[:sort_order]
67
- end
20
+ payload[:sort][:field] = sort_field if sort_field
21
+ payload[:sort][:order] = sort_order if sort_order
68
22
  end
69
- if @search_params[:per_page] || @search_params[:starting_after]
23
+ if per_page || starting_after
70
24
  payload[:pagination] = {}
71
- if @search_params[:per_page]
72
- payload[:pagination][:per_page] = @search_params[:per_page]
73
- end
74
- if @search_params[:starting_after]
75
- payload[:pagination][:starting_after] = @search_params[:starting_after]
76
- end
25
+ payload[:pagination][:per_page] = per_page if per_page
26
+ payload[:pagination][:starting_after] = starting_after if starting_after
77
27
  end
78
- return payload
28
+ payload
29
+ end
30
+
31
+ def sort_field
32
+ @params[:sort_field]
79
33
  end
80
34
 
35
+ def sort_order
36
+ @params[:sort_order]
37
+ end
38
+
39
+ def per_page
40
+ @params[:per_page]
41
+ end
42
+
43
+ def starting_after
44
+ @params[:starting_after]
45
+ end
81
46
  end
82
47
  end
@@ -0,0 +1,23 @@
1
+ require 'intercom/api_operations/list'
2
+ require 'intercom/api_operations/find'
3
+ require 'intercom/api_operations/save'
4
+ require 'intercom/api_operations/delete'
5
+
6
+ module Intercom
7
+ module Service
8
+ class Section < BaseService
9
+ include ApiOperations::List
10
+ include ApiOperations::Find
11
+ include ApiOperations::Save
12
+ include ApiOperations::Delete
13
+
14
+ def collection_class
15
+ Intercom::Section
16
+ end
17
+
18
+ def collection_name
19
+ 'help_center/sections'
20
+ end
21
+ end
22
+ end
23
+ end
@@ -3,5 +3,9 @@ require 'intercom/traits/api_resource'
3
3
  module Intercom
4
4
  class Segment
5
5
  include Traits::ApiResource
6
+
7
+ def self.collection_proxy_class
8
+ Intercom::BaseCollectionProxy
9
+ end
6
10
  end
7
11
  end
@@ -0,0 +1,20 @@
1
+ require 'intercom/service/base_service'
2
+ require 'intercom/api_operations/find'
3
+ require 'intercom/api_operations/list'
4
+ require 'intercom/api_operations/delete'
5
+ require 'intercom/api_operations/save'
6
+
7
+ module Intercom
8
+ module Service
9
+ class Article < BaseService
10
+ include ApiOperations::Find
11
+ include ApiOperations::List
12
+ include ApiOperations::Delete
13
+ include ApiOperations::Save
14
+
15
+ def collection_class
16
+ Intercom::Article
17
+ end
18
+ end
19
+ end
20
+ end