3
3
4
4
module Intercom
5
5
class Request
6
- attr_accessor :path , :net_http_method , :rate_limit_details , :handle_rate_limit
7
-
8
- def initialize ( path , net_http_method )
9
- self . path = path
10
- self . net_http_method = net_http_method
11
- self . handle_rate_limit = false
12
- end
13
-
14
- def set_common_headers ( method , base_uri )
15
- method . add_field ( 'AcceptEncoding' , 'gzip, deflate' )
16
- end
17
-
18
- def set_basic_auth ( method , username , secret )
19
- method . basic_auth ( CGI . unescape ( username ) , CGI . unescape ( secret ) )
20
- end
6
+ class << self
7
+ def get ( path , params )
8
+ new ( path , Net ::HTTP ::Get . new ( append_query_string_to_url ( path , params ) , default_headers ) )
9
+ end
21
10
22
- def set_api_version ( method , api_version )
23
- method . add_field ( 'Intercom-Version' , api_version )
24
- end
11
+ def post ( path , form_data )
12
+ new ( path , method_with_body ( Net :: HTTP :: Post , path , form_data ) )
13
+ end
25
14
26
- def self . get ( path , params )
27
- new ( path , Net ::HTTP ::Get . new ( append_query_string_to_url ( path , params ) , default_headers ) )
28
- end
15
+ def delete ( path , params )
16
+ new ( path , method_with_body ( Net ::HTTP ::Delete , path , params ) )
17
+ end
29
18
30
- def self . post ( path , form_data )
31
- new ( path , method_with_body ( Net ::HTTP ::Post , path , form_data ) )
32
- end
19
+ def put ( path , form_data )
20
+ new ( path , method_with_body ( Net ::HTTP ::Put , path , form_data ) )
21
+ end
33
22
34
- def self . delete ( path , params )
35
- new ( path , method_with_body ( Net ::HTTP ::Delete , path , params ) )
36
- end
23
+ private def method_with_body ( http_method , path , params )
24
+ request = http_method . send ( :new , path , default_headers )
25
+ request . body = params . to_json
26
+ request [ "Content-Type" ] = "application/json"
27
+ request
28
+ end
37
29
38
- def self . put ( path , form_data )
39
- new ( path , method_with_body ( Net :: HTTP :: Put , path , form_data ) )
40
- end
30
+ private def default_headers
31
+ { 'Accept-Encoding' => 'gzip, deflate' , 'Accept' => 'application/vnd.intercom.3+json' , 'User-Agent' => "Intercom-Ruby/ #{ Intercom :: VERSION } " }
32
+ end
41
33
42
- def self . method_with_body ( http_method , path , params )
43
- request = http_method . send ( :new , path , default_headers )
44
- request . body = params . to_json
45
- request [ "Content-Type" ] = "application/json "
46
- request
34
+ private def append_query_string_to_url ( url , params )
35
+ return url if params . empty?
36
+ query_string = params . map { | k , v | " #{ k . to_s } = #{ CGI :: escape ( v . to_s ) } " } . join ( '&' )
37
+ url + "? #{ query_string } "
38
+ end
47
39
end
48
40
49
- def self . default_headers
50
- { 'Accept-Encoding' => 'gzip, deflate' , 'Accept' => 'application/vnd.intercom.3+json' , 'User-Agent' => "Intercom-Ruby/#{ Intercom ::VERSION } " }
41
+ def initialize ( path , net_http_method )
42
+ self . path = path
43
+ self . net_http_method = net_http_method
44
+ self . handle_rate_limit = false
51
45
end
52
46
53
- def client ( uri , read_timeout :, open_timeout :)
54
- net = Net ::HTTP . new ( uri . host , uri . port )
55
- if uri . is_a? ( URI ::HTTPS )
56
- net . use_ssl = true
57
- net . verify_mode = OpenSSL ::SSL ::VERIFY_PEER
58
- net . ca_file = File . join ( File . dirname ( __FILE__ ) , '../data/cacert.pem' )
59
- end
60
- net . read_timeout = read_timeout
61
- net . open_timeout = open_timeout
62
- net
63
- end
47
+ attr_accessor :handle_rate_limit
64
48
65
49
def execute ( target_base_url = nil , username :, secret : nil , read_timeout : 90 , open_timeout : 30 , api_version : nil )
66
50
retries = 3
@@ -72,10 +56,16 @@ def execute(target_base_url=nil, username:, secret: nil, read_timeout: 90, open_
72
56
client ( base_uri , read_timeout : read_timeout , open_timeout : open_timeout ) . start do |http |
73
57
begin
74
58
response = http . request ( net_http_method )
59
+
75
60
set_rate_limit_details ( response )
76
- decoded_body = decode_body ( response )
77
- parsed_body = parse_body ( decoded_body , response )
78
61
raise_errors_on_failure ( response )
62
+
63
+ parsed_body = extract_response_body ( response )
64
+
65
+ return nil if parsed_body . nil?
66
+
67
+ raise_application_errors_on_failure ( parsed_body , response . code . to_i ) if parsed_body [ 'type' ] == 'error.list'
68
+
79
69
parsed_body
80
70
rescue Intercom ::RateLimitExceeded => e
81
71
if @handle_rate_limit
@@ -98,55 +88,91 @@ def execute(target_base_url=nil, username:, secret: nil, read_timeout: 90, open_
98
88
end
99
89
end
100
90
101
- def decode_body ( response )
102
- decode ( response [ 'content-encoding' ] , response . body )
103
- end
91
+ attr_accessor :path ,
92
+ :net_http_method ,
93
+ :rate_limit_details
104
94
105
- def parse_body ( decoded_body , response )
106
- parsed_body = nil
107
- return parsed_body if decoded_body . nil? || decoded_body . strip . empty?
108
- begin
109
- parsed_body = JSON . parse ( decoded_body )
110
- rescue JSON ::ParserError => _
111
- raise_errors_on_failure ( response )
95
+ private :path ,
96
+ :net_http_method ,
97
+ :rate_limit_details
98
+
99
+ private def client ( uri , read_timeout :, open_timeout :)
100
+ net = Net ::HTTP . new ( uri . host , uri . port )
101
+ if uri . is_a? ( URI ::HTTPS )
102
+ net . use_ssl = true
103
+ net . verify_mode = OpenSSL ::SSL ::VERIFY_PEER
104
+ net . ca_file = File . join ( File . dirname ( __FILE__ ) , '../data/cacert.pem' )
112
105
end
113
- raise_errors_on_failure ( response ) if parsed_body . nil?
114
- raise_application_errors_on_failure ( parsed_body , response . code . to_i ) if parsed_body [ 'type' ] == 'error.list'
115
- parsed_body
106
+ net . read_timeout = read_timeout
107
+ net . open_timeout = open_timeout
108
+ net
116
109
end
117
110
118
- def set_rate_limit_details ( response )
111
+ private def extract_response_body ( response )
112
+ decoded_body = decode ( response [ 'content-encoding' ] , response . body )
113
+
114
+ json_parse_response ( decoded_body , response . code )
115
+ end
116
+
117
+ private def decode ( content_encoding , body )
118
+ return body if ( !body ) || body . empty? || content_encoding != 'gzip'
119
+ Zlib ::GzipReader . new ( StringIO . new ( body ) ) . read . force_encoding ( "utf-8" )
120
+ end
121
+
122
+ private def json_parse_response ( str , code )
123
+ return nil if str . to_s . empty?
124
+
125
+ JSON . parse ( str )
126
+ rescue JSON ::ParserError
127
+ msg = <<~MSG . gsub ( /[[:space:]]+/ , " " ) . strip # #squish from ActiveSuppor
128
+ Expected a JSON response body. Instead got '#{ str } '
129
+ with status code '#{ code } '.
130
+ MSG
131
+
132
+ raise UnexpectedResponseError , msg
133
+ end
134
+
135
+ private def set_rate_limit_details ( response )
119
136
rate_limit_details = { }
120
137
rate_limit_details [ :limit ] = response [ 'X-RateLimit-Limit' ] . to_i if response [ 'X-RateLimit-Limit' ]
121
138
rate_limit_details [ :remaining ] = response [ 'X-RateLimit-Remaining' ] . to_i if response [ 'X-RateLimit-Remaining' ]
122
139
rate_limit_details [ :reset_at ] = Time . at ( response [ 'X-RateLimit-Reset' ] . to_i ) if response [ 'X-RateLimit-Reset' ]
123
140
@rate_limit_details = rate_limit_details
124
141
end
125
142
126
- def decode ( content_encoding , body )
127
- return body if ( !body ) || body . empty? || content_encoding != 'gzip'
128
- Zlib ::GzipReader . new ( StringIO . new ( body ) ) . read . force_encoding ( "utf-8" )
143
+ private def set_common_headers ( method , base_uri )
144
+ method . add_field ( 'AcceptEncoding' , 'gzip, deflate' )
129
145
end
130
146
131
- def raise_errors_on_failure ( res )
132
- if res . code . to_i . eql? ( 404 )
147
+ private def set_basic_auth ( method , username , secret )
148
+ method . basic_auth ( CGI . unescape ( username ) , CGI . unescape ( secret ) )
149
+ end
150
+
151
+ private def set_api_version ( method , api_version )
152
+ method . add_field ( 'Intercom-Version' , api_version )
153
+ end
154
+
155
+ private def raise_errors_on_failure ( res )
156
+ code = res . code . to_i
157
+
158
+ if code == 404
133
159
raise Intercom ::ResourceNotFound . new ( 'Resource Not Found' )
134
- elsif res . code . to_i . eql? ( 401 )
160
+ elsif code == 401
135
161
raise Intercom ::AuthenticationError . new ( 'Unauthorized' )
136
- elsif res . code . to_i . eql? ( 403 )
162
+ elsif code == 403
137
163
raise Intercom ::AuthenticationError . new ( 'Forbidden' )
138
- elsif res . code . to_i . eql? ( 429 )
164
+ elsif code == 429
139
165
raise Intercom ::RateLimitExceeded . new ( 'Rate Limit Exceeded' )
140
- elsif res . code . to_i . eql? ( 500 )
166
+ elsif code == 500
141
167
raise Intercom ::ServerError . new ( 'Server Error' )
142
- elsif res . code . to_i . eql? ( 502 )
168
+ elsif code == 502
143
169
raise Intercom ::BadGatewayError . new ( 'Bad Gateway Error' )
144
- elsif res . code . to_i . eql? ( 503 )
170
+ elsif code == 503
145
171
raise Intercom ::ServiceUnavailableError . new ( 'Service Unavailable' )
146
172
end
147
173
end
148
174
149
- def raise_application_errors_on_failure ( error_list_details , http_code )
175
+ private def raise_application_errors_on_failure ( error_list_details , http_code )
150
176
# Currently, we don't support multiple errors
151
177
error_details = error_list_details [ 'errors' ] . first
152
178
error_code = error_details [ 'type' ] || error_details [ 'code' ]
@@ -198,18 +224,12 @@ def raise_application_errors_on_failure(error_list_details, http_code)
198
224
end
199
225
end
200
226
201
- def message_for_unexpected_error_with_type ( error_details , parsed_http_code )
227
+ private def message_for_unexpected_error_with_type ( error_details , parsed_http_code )
202
228
"The error of type '#{ error_details [ 'type' ] } ' is not recognized. It occurred with the message: #{ error_details [ 'message' ] } and http_code: '#{ parsed_http_code } '. Please contact Intercom with these details."
203
229
end
204
230
205
- def message_for_unexpected_error_without_type ( error_details , parsed_http_code )
231
+ private def message_for_unexpected_error_without_type ( error_details , parsed_http_code )
206
232
"An unexpected error occured. It occurred with the message: #{ error_details [ 'message' ] } and http_code: '#{ parsed_http_code } '. Please contact Intercom with these details."
207
233
end
208
-
209
- def self . append_query_string_to_url ( url , params )
210
- return url if params . empty?
211
- query_string = params . map { |k , v | "#{ k . to_s } =#{ CGI ::escape ( v . to_s ) } " } . join ( '&' )
212
- url + "?#{ query_string } "
213
- end
214
234
end
215
235
end
0 commit comments