intercom 3.9.4 → 4.0.0
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 +5 -5
- data/README.md +235 -222
- data/Rakefile +1 -1
- data/changes.txt +6 -0
- data/lib/intercom/api_operations/archive.rb +2 -1
- data/lib/intercom/api_operations/delete.rb +16 -0
- data/lib/intercom/api_operations/find.rb +5 -2
- data/lib/intercom/api_operations/find_all.rb +4 -3
- data/lib/intercom/api_operations/list.rb +4 -1
- data/lib/intercom/api_operations/load.rb +4 -2
- data/lib/intercom/api_operations/nested_resource.rb +70 -0
- data/lib/intercom/api_operations/save.rb +5 -4
- data/lib/intercom/api_operations/scroll.rb +4 -5
- data/lib/intercom/api_operations/search.rb +3 -2
- data/lib/intercom/base_collection_proxy.rb +72 -0
- data/lib/intercom/client.rb +20 -25
- data/lib/intercom/client_collection_proxy.rb +17 -39
- data/lib/intercom/company.rb +8 -0
- data/lib/intercom/contact.rb +21 -3
- data/lib/intercom/conversation.rb +4 -0
- data/lib/intercom/data_attribute.rb +7 -0
- data/lib/intercom/deprecated_leads_collection_proxy.rb +22 -0
- data/lib/intercom/deprecated_resources.rb +13 -0
- data/lib/intercom/errors.rb +3 -0
- data/lib/intercom/extended_api_operations/segments.rb +3 -1
- data/lib/intercom/extended_api_operations/tags.rb +3 -1
- data/lib/intercom/lead.rb +21 -0
- data/lib/intercom/lib/typed_json_deserializer.rb +42 -37
- data/lib/intercom/note.rb +4 -0
- data/lib/intercom/request.rb +37 -33
- data/lib/intercom/scroll_collection_proxy.rb +33 -38
- data/lib/intercom/search_collection_proxy.rb +30 -65
- data/lib/intercom/service/base_service.rb +7 -0
- data/lib/intercom/service/company.rb +0 -12
- data/lib/intercom/service/contact.rb +21 -10
- data/lib/intercom/service/conversation.rb +12 -3
- data/lib/intercom/service/data_attribute.rb +20 -0
- data/lib/intercom/service/lead.rb +41 -0
- data/lib/intercom/service/note.rb +4 -8
- data/lib/intercom/service/subscription.rb +2 -2
- data/lib/intercom/service/tag.rb +9 -9
- data/lib/intercom/service/visitor.rb +17 -8
- data/lib/intercom/tag.rb +4 -0
- data/lib/intercom/traits/api_resource.rb +28 -17
- data/lib/intercom/user.rb +12 -3
- data/lib/intercom/utils.rb +13 -2
- data/lib/intercom/version.rb +1 -1
- data/lib/intercom/visitor.rb +0 -2
- data/lib/intercom.rb +27 -22
- data/spec/spec_helper.rb +738 -513
- data/spec/unit/intercom/admin_spec.rb +2 -2
- data/spec/unit/intercom/base_collection_proxy_spec.rb +30 -0
- data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
- data/spec/unit/intercom/client_spec.rb +28 -25
- data/spec/unit/intercom/company_spec.rb +13 -15
- data/spec/unit/intercom/contact_spec.rb +289 -33
- data/spec/unit/intercom/conversation_spec.rb +29 -7
- data/spec/unit/intercom/count_spec.rb +4 -4
- data/spec/unit/intercom/data_attribute_spec.rb +40 -0
- data/spec/unit/intercom/deprecated_leads_collection_proxy_spec.rb +17 -0
- data/spec/unit/intercom/event_spec.rb +9 -11
- data/spec/unit/intercom/job_spec.rb +24 -24
- data/spec/unit/intercom/lead_spec.rb +57 -0
- data/spec/unit/intercom/lib/flat_store_spec.rb +22 -20
- data/spec/unit/intercom/message_spec.rb +1 -1
- data/spec/unit/intercom/note_spec.rb +4 -10
- data/spec/unit/intercom/request_spec.rb +1 -1
- data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
- data/spec/unit/intercom/search_collection_proxy_spec.rb +32 -28
- data/spec/unit/intercom/segment_spec.rb +2 -2
- data/spec/unit/intercom/subscription_spec.rb +5 -6
- data/spec/unit/intercom/tag_spec.rb +22 -14
- data/spec/unit/intercom/team_spec.rb +2 -2
- data/spec/unit/intercom/traits/api_resource_spec.rb +53 -51
- data/spec/unit/intercom/user_spec.rb +224 -226
- data/spec/unit/intercom/visitor_spec.rb +49 -0
- data/spec/unit/intercom_spec.rb +5 -3
- metadata +22 -7
- data/lib/intercom/customer.rb +0 -10
- data/lib/intercom/service/customer.rb +0 -14
- data/spec/unit/intercom/visitors_spec.rb +0 -61
@@ -1,54 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'intercom/utils'
|
2
4
|
|
3
5
|
module Intercom
|
4
6
|
module Lib
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
# Responsibility: To decide whether we are deserializing a collection or an
|
8
|
+
# entity of a particular type and to dispatch deserialization
|
9
|
+
class TypedJsonDeserializer
|
10
|
+
attr_reader :json
|
11
|
+
|
12
|
+
def initialize(json, client)
|
13
|
+
@json = json
|
14
|
+
@client = client
|
15
|
+
end
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
17
|
+
def deserialize
|
18
|
+
if blank_object_type?(object_type)
|
19
|
+
raise DeserializationError, 'No type field was found to facilitate deserialization'
|
20
|
+
elsif list_object_type?(object_type)
|
21
|
+
deserialize_collection(json[object_entity_key])
|
22
|
+
else # singular object type
|
23
|
+
deserialize_object(json)
|
22
24
|
end
|
25
|
+
end
|
23
26
|
|
24
|
-
|
27
|
+
private
|
25
28
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
def blank_object_type?(object_type)
|
30
|
+
object_type.nil? || object_type == ''
|
31
|
+
end
|
29
32
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
def list_object_type?(object_type)
|
34
|
+
object_type.end_with?('.list')
|
35
|
+
end
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
collection_json.map { |item_json| TypedJsonDeserializer.new(item_json).deserialize }
|
37
|
-
end
|
37
|
+
def deserialize_collection(collection_json)
|
38
|
+
return [] if collection_json.nil?
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
entity_class.from_api(object_json)
|
42
|
-
end
|
40
|
+
collection_json.map { |item_json| TypedJsonDeserializer.new(item_json, @client).deserialize }
|
41
|
+
end
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
def deserialize_object(object_json)
|
44
|
+
entity_class = Utils.constantize_singular_resource_name(object_entity_key)
|
45
|
+
deserialized = entity_class.from_api(object_json)
|
46
|
+
deserialized.client = @client
|
47
|
+
deserialized
|
48
|
+
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
50
|
+
def object_type
|
51
|
+
@object_type ||= json['type']
|
52
|
+
end
|
51
53
|
|
54
|
+
def object_entity_key
|
55
|
+
@object_entity_key ||= Utils.entity_key_from_type(object_type)
|
52
56
|
end
|
57
|
+
end
|
53
58
|
end
|
54
59
|
end
|
data/lib/intercom/note.rb
CHANGED
data/lib/intercom/request.rb
CHANGED
@@ -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[
|
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
|
-
|
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,
|
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
|
-
|
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
|
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
|
86
|
+
raise Intercom::ServiceUnavailableError, 'Service Unavailable [request timed out]'
|
84
87
|
end
|
85
88
|
end
|
86
89
|
rescue Timeout::Error
|
87
|
-
raise Intercom::ServiceConnectionError
|
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
|
118
|
-
|
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:]]+/,
|
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,
|
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
|
147
|
-
method.
|
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
|
162
|
+
raise Intercom::ResourceNotFound, 'Resource Not Found'
|
159
163
|
elsif code == 401
|
160
|
-
raise Intercom::AuthenticationError
|
164
|
+
raise Intercom::AuthenticationError, 'Unauthorized'
|
161
165
|
elsif code == 403
|
162
|
-
raise Intercom::AuthenticationError
|
166
|
+
raise Intercom::AuthenticationError, 'Forbidden'
|
163
167
|
elsif code == 429
|
164
|
-
raise Intercom::RateLimitExceeded
|
168
|
+
raise Intercom::RateLimitExceeded, 'Rate Limit Exceeded'
|
165
169
|
elsif code == 500
|
166
|
-
raise Intercom::ServerError
|
170
|
+
raise Intercom::ServerError, 'Server Error'
|
167
171
|
elsif code == 502
|
168
|
-
raise Intercom::BadGatewayError
|
172
|
+
raise Intercom::BadGatewayError, 'Bad Gateway Error'
|
169
173
|
elsif code == 503
|
170
|
-
raise Intercom::ServiceUnavailableError
|
174
|
+
raise Intercom::ServiceUnavailableError, 'Service Unavailable'
|
171
175
|
elsif code == 504
|
172
|
-
raise Intercom::GatewayTimeoutError
|
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
|
-
:
|
184
|
-
:
|
185
|
-
:
|
186
|
-
:
|
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
|
201
|
+
when 'bad_request', 'missing_parameter', 'parameter_invalid', 'parameter_not_found'
|
198
202
|
raise Intercom::BadRequestError.new(error_details['message'], error_context)
|
199
|
-
when
|
203
|
+
when 'not_restorable'
|
200
204
|
raise Intercom::BlockedUserError.new(error_details['message'], error_context)
|
201
|
-
when
|
205
|
+
when 'not_found', 'company_not_found'
|
202
206
|
raise Intercom::ResourceNotFound.new(error_details['message'], error_context)
|
203
|
-
when
|
207
|
+
when 'admin_not_found'
|
204
208
|
raise Intercom::AdminNotFound.new(error_details['message'], error_context)
|
205
|
-
when
|
209
|
+
when 'rate_limit_exceeded'
|
206
210
|
raise Intercom::RateLimitExceeded.new(error_details['message'], error_context)
|
207
|
-
when
|
211
|
+
when 'custom_data_limit_reached'
|
208
212
|
raise Intercom::CDALimitReachedError.new(error_details['message'], error_context)
|
209
|
-
when
|
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
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require 'intercom/utils'
|
4
|
+
require 'intercom/base_collection_proxy'
|
5
5
|
|
6
|
-
|
6
|
+
module Intercom
|
7
|
+
class ScrollCollectionProxy < BaseCollectionProxy
|
8
|
+
attr_reader :scroll_url, :scroll_param, :records
|
7
9
|
|
8
|
-
def initialize(resource_name,
|
10
|
+
def initialize(resource_name, resource_class, details: {}, client:)
|
9
11
|
@resource_name = resource_name
|
10
|
-
@resource_class =
|
11
|
-
@scroll_url = (
|
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
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
raise Intercom::HttpError
|
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
29
|
top_level_entity_key = deserialize_response_hash(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,40 @@ module Intercom
|
|
35
37
|
def each(&block)
|
36
38
|
scroll_param = nil
|
37
39
|
loop do
|
38
|
-
if
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
raise Intercom::HttpError
|
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
|
+
|
44
47
|
response_hash[deserialize_response_hash(response_hash)].each do |object_json|
|
45
|
-
block.call Lib::TypedJsonDeserializer.new(object_json).deserialize
|
48
|
+
block.call Lib::TypedJsonDeserializer.new(object_json, @client).deserialize
|
46
49
|
end
|
47
50
|
scroll_param = extract_scroll_param(response_hash)
|
48
|
-
break
|
51
|
+
break unless records_present?(response_hash)
|
49
52
|
end
|
50
53
|
self
|
51
54
|
end
|
52
55
|
|
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
56
|
private
|
63
57
|
|
64
58
|
def deserialize_response_hash(response_hash)
|
65
59
|
top_level_type = response_hash.delete('type')
|
66
60
|
if resource_name == 'subscriptions'
|
67
|
-
|
61
|
+
'items'
|
68
62
|
else
|
69
|
-
|
63
|
+
Utils.entity_key_from_type(top_level_type)
|
70
64
|
end
|
71
65
|
end
|
72
66
|
|
73
67
|
def records_present?(response_hash)
|
74
|
-
|
68
|
+
!response_hash[@resource_name].empty?
|
75
69
|
end
|
76
70
|
|
77
71
|
def extract_scroll_param(response_hash)
|
78
72
|
return nil unless records_present?(response_hash)
|
73
|
+
|
79
74
|
response_hash['scroll_param']
|
80
75
|
end
|
81
76
|
end
|
@@ -1,82 +1,47 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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: @
|
16
|
+
query: @params[:query]
|
59
17
|
}
|
60
|
-
if
|
18
|
+
if sort_field || sort_order
|
61
19
|
payload[:sort] = {}
|
62
|
-
|
63
|
-
|
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
|
23
|
+
if per_page || starting_after
|
70
24
|
payload[:pagination] = {}
|
71
|
-
|
72
|
-
|
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
|
-
|
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
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'intercom/client_collection_proxy'
|
2
4
|
|
3
5
|
module Intercom
|
@@ -17,8 +19,13 @@ module Intercom
|
|
17
19
|
Intercom::ClientCollectionProxy
|
18
20
|
end
|
19
21
|
|
22
|
+
def collection_name
|
23
|
+
@collection_name ||= Utils.resource_class_to_collection_name(collection_class)
|
24
|
+
end
|
25
|
+
|
20
26
|
def from_api(api_response)
|
21
27
|
object = collection_class.new
|
28
|
+
object.client = @client
|
22
29
|
object.from_response(api_response)
|
23
30
|
object
|
24
31
|
end
|
@@ -23,18 +23,6 @@ module Intercom
|
|
23
23
|
def collection_class
|
24
24
|
Intercom::Company
|
25
25
|
end
|
26
|
-
|
27
|
-
def users_by_intercom_company_id(id)
|
28
|
-
get_users(url: "/companies/#{id}/users")
|
29
|
-
end
|
30
|
-
|
31
|
-
def users_by_company_id(id)
|
32
|
-
get_users(url: "/companies", params: { company_id: id, type: "user" })
|
33
|
-
end
|
34
|
-
|
35
|
-
private def get_users(url:, params: {})
|
36
|
-
ClientCollectionProxy.new("users", finder_details: { url: url, params: params }, client: @client)
|
37
|
-
end
|
38
26
|
end
|
39
27
|
end
|
40
28
|
end
|
@@ -2,12 +2,9 @@ require 'intercom/service/base_service'
|
|
2
2
|
require 'intercom/api_operations/load'
|
3
3
|
require 'intercom/api_operations/list'
|
4
4
|
require 'intercom/api_operations/find'
|
5
|
-
require 'intercom/api_operations/find_all'
|
6
5
|
require 'intercom/api_operations/save'
|
7
|
-
require 'intercom/api_operations/
|
8
|
-
require 'intercom/api_operations/
|
9
|
-
require 'intercom/api_operations/archive'
|
10
|
-
require 'intercom/api_operations/request_hard_delete'
|
6
|
+
require 'intercom/api_operations/delete'
|
7
|
+
require 'intercom/api_operations/search'
|
11
8
|
|
12
9
|
module Intercom
|
13
10
|
module Service
|
@@ -15,16 +12,30 @@ module Intercom
|
|
15
12
|
include ApiOperations::Load
|
16
13
|
include ApiOperations::List
|
17
14
|
include ApiOperations::Find
|
18
|
-
include ApiOperations::FindAll
|
19
15
|
include ApiOperations::Save
|
20
|
-
include ApiOperations::
|
21
|
-
include ApiOperations::
|
22
|
-
include ApiOperations::Archive
|
23
|
-
include ApiOperations::RequestHardDelete
|
16
|
+
include ApiOperations::Delete
|
17
|
+
include ApiOperations::Search
|
24
18
|
|
25
19
|
def collection_class
|
26
20
|
Intercom::Contact
|
27
21
|
end
|
22
|
+
|
23
|
+
def collection_proxy_class
|
24
|
+
Intercom::BaseCollectionProxy
|
25
|
+
end
|
26
|
+
|
27
|
+
def merge(lead, user)
|
28
|
+
raise_invalid_merge_error unless lead.role == 'lead' && user.role == 'user'
|
29
|
+
|
30
|
+
response = @client.post('/contacts/merge', from: lead.id, into: user.id)
|
31
|
+
raise Intercom::HttpError, 'Http Error - No response entity returned' unless response
|
32
|
+
|
33
|
+
user.from_response(response)
|
34
|
+
end
|
35
|
+
|
36
|
+
private def raise_invalid_merge_error
|
37
|
+
raise Intercom::InvalidMergeError, 'Merging can only be performed on a lead into a user'
|
38
|
+
end
|
28
39
|
end
|
29
40
|
end
|
30
41
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'intercom/service/base_service'
|
2
4
|
require 'intercom/api_operations/find_all'
|
3
5
|
require 'intercom/api_operations/find'
|
@@ -13,6 +15,7 @@ module Intercom
|
|
13
15
|
include ApiOperations::Find
|
14
16
|
include ApiOperations::Load
|
15
17
|
include ApiOperations::Save
|
18
|
+
include ApiOperations::Search
|
16
19
|
|
17
20
|
def collection_class
|
18
21
|
Intercom::Conversation
|
@@ -25,7 +28,7 @@ module Intercom
|
|
25
28
|
def reply(reply_data)
|
26
29
|
id = reply_data.delete(:id)
|
27
30
|
collection_name = Utils.resource_class_to_collection_name(collection_class)
|
28
|
-
response = @client.post("/#{collection_name}/#{id}/reply", reply_data.merge(:
|
31
|
+
response = @client.post("/#{collection_name}/#{id}/reply", reply_data.merge(conversation_id: id))
|
29
32
|
collection_class.new.from_response(response)
|
30
33
|
end
|
31
34
|
|
@@ -44,14 +47,20 @@ module Intercom
|
|
44
47
|
end
|
45
48
|
|
46
49
|
def snooze(reply_data)
|
47
|
-
|
50
|
+
reply_data.fetch(:snoozed_until) { raise 'snoozed_until field is required' }
|
48
51
|
reply reply_data.merge(message_type: 'snoozed', type: 'admin')
|
49
52
|
end
|
50
53
|
|
51
54
|
def assign(reply_data)
|
52
|
-
assignee_id = reply_data.fetch(:assignee_id) {
|
55
|
+
assignee_id = reply_data.fetch(:assignee_id) { raise 'assignee_id is required' }
|
53
56
|
reply reply_data.merge(message_type: 'assignment', assignee_id: assignee_id, type: 'admin')
|
54
57
|
end
|
58
|
+
|
59
|
+
def run_assignment_rules(id)
|
60
|
+
collection_name = Utils.resource_class_to_collection_name(collection_class)
|
61
|
+
response = @client.post("/#{collection_name}/#{id}/run_assignment_rules")
|
62
|
+
collection_class.new.from_response(response)
|
63
|
+
end
|
55
64
|
end
|
56
65
|
end
|
57
66
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'intercom/service/base_service'
|
2
|
+
require 'intercom/api_operations/load'
|
3
|
+
require 'intercom/api_operations/list'
|
4
|
+
require 'intercom/api_operations/find_all'
|
5
|
+
require 'intercom/api_operations/save'
|
6
|
+
|
7
|
+
module Intercom
|
8
|
+
module Service
|
9
|
+
class DataAttribute < BaseService
|
10
|
+
include ApiOperations::Load
|
11
|
+
include ApiOperations::List
|
12
|
+
include ApiOperations::FindAll
|
13
|
+
include ApiOperations::Save
|
14
|
+
|
15
|
+
def collection_class
|
16
|
+
Intercom::DataAttribute
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|