33
44module Intercom
55 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
2110
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
2514
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
2918
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
3322
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
3729
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
4133
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
4739 end
4840
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
5145 end
5246
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
6448
6549 def execute ( target_base_url = nil , username :, secret : nil , read_timeout : 90 , open_timeout : 30 , api_version : nil )
6650 retries = 3
@@ -72,10 +56,16 @@ def execute(target_base_url=nil, username:, secret: nil, read_timeout: 90, open_
7256 client ( base_uri , read_timeout : read_timeout , open_timeout : open_timeout ) . start do |http |
7357 begin
7458 response = http . request ( net_http_method )
59+
7560 set_rate_limit_details ( response )
76- decoded_body = decode_body ( response )
77- parsed_body = parse_body ( decoded_body , response )
7861 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+
7969 parsed_body
8070 rescue Intercom ::RateLimitExceeded => e
8171 if @handle_rate_limit
@@ -98,55 +88,91 @@ def execute(target_base_url=nil, username:, secret: nil, read_timeout: 90, open_
9888 end
9989 end
10090
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
10494
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' )
112105 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
116109 end
117110
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 )
119136 rate_limit_details = { }
120137 rate_limit_details [ :limit ] = response [ 'X-RateLimit-Limit' ] . to_i if response [ 'X-RateLimit-Limit' ]
121138 rate_limit_details [ :remaining ] = response [ 'X-RateLimit-Remaining' ] . to_i if response [ 'X-RateLimit-Remaining' ]
122139 rate_limit_details [ :reset_at ] = Time . at ( response [ 'X-RateLimit-Reset' ] . to_i ) if response [ 'X-RateLimit-Reset' ]
123140 @rate_limit_details = rate_limit_details
124141 end
125142
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' )
129145 end
130146
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
133159 raise Intercom ::ResourceNotFound . new ( 'Resource Not Found' )
134- elsif res . code . to_i . eql? ( 401 )
160+ elsif code == 401
135161 raise Intercom ::AuthenticationError . new ( 'Unauthorized' )
136- elsif res . code . to_i . eql? ( 403 )
162+ elsif code == 403
137163 raise Intercom ::AuthenticationError . new ( 'Forbidden' )
138- elsif res . code . to_i . eql? ( 429 )
164+ elsif code == 429
139165 raise Intercom ::RateLimitExceeded . new ( 'Rate Limit Exceeded' )
140- elsif res . code . to_i . eql? ( 500 )
166+ elsif code == 500
141167 raise Intercom ::ServerError . new ( 'Server Error' )
142- elsif res . code . to_i . eql? ( 502 )
168+ elsif code == 502
143169 raise Intercom ::BadGatewayError . new ( 'Bad Gateway Error' )
144- elsif res . code . to_i . eql? ( 503 )
170+ elsif code == 503
145171 raise Intercom ::ServiceUnavailableError . new ( 'Service Unavailable' )
146172 end
147173 end
148174
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 )
150176 # Currently, we don't support multiple errors
151177 error_details = error_list_details [ 'errors' ] . first
152178 error_code = error_details [ 'type' ] || error_details [ 'code' ]
@@ -198,18 +224,12 @@ def raise_application_errors_on_failure(error_list_details, http_code)
198224 end
199225 end
200226
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 )
202228 "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."
203229 end
204230
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 )
206232 "An unexpected error occured. It occurred with the message: #{ error_details [ 'message' ] } and http_code: '#{ parsed_http_code } '. Please contact Intercom with these details."
207233 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
214234 end
215235end
0 commit comments