Class: HypertrackV3::Engine::WebhookParser
- Inherits:
-
Object
- Object
- HypertrackV3::Engine::WebhookParser
- Defined in:
- lib/hypertrack_v3.rb
Defined Under Namespace
Classes: LogHook
Constant Summary collapse
- @@client =
nil
- @@hooks =
Sets up default hooks
{ location: ->(*args) { LogHook.('Location', *args) }, device_status: ->(*args) { LogHook.('DeviceStatus', *args) }, battery: ->(*args) { LogHook.('Battery', *args) }, trip: ->(*args) { LogHook.('Trip', *args) }, }
Class Method Summary collapse
- .call(env) ⇒ Object
- .client ⇒ Object
- .dispatch(request) ⇒ Object
- .parse_request(env) ⇒ Object
- .register_hook(name, callable) ⇒ Object
- .register_with_hypertrack(request) ⇒ Object
- .serve(code, params = {}) ⇒ Object
Class Method Details
.call(env) ⇒ Object
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/hypertrack_v3.rb', line 222 def self.call(env) request = parse_request(env) case request.headers['x_amz_sns_message_type'] when 'SubscriptionConfirmation' self.register_with_hypertrack request when 'Notification' self.dispatch request else HypertrackV3.log_error( "invalid message-type header", { message_type: request.header['x_amz_sns_messate_type'], }.to_json ) self.serve(400, {error: "invalid message-type header"}) end end |
.client ⇒ Object
137 138 139 140 141 142 143 |
# File 'lib/hypertrack_v3.rb', line 137 def self.client @@client ||= Faraday.new do |conn| conn.use Faraday::Response::Logger, HypertrackV3.logger, bodies: true conn.use :instrumentation conn.adapter Faraday.default_adapter end end |
.dispatch(request) ⇒ Object
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/hypertrack_v3.rb', line 168 def self.dispatch(request) if (cached = Rails.cache.fetch('/hypertrack_v3/subscription_arn')) != request.headers['x_amz_sns_subscription_arn'] HypertrackV3.log_error( "invalid subscription-arn header", { subscription_arn: { request: request.header, cache: cached, } }.to_json ) return self.serve(400, {error: "invalid subscription-arn header"}) end if (cached = Rails.cache.fetch("/hypertrack_v3/#{request.headers['x_amz_sns_message_id']}")).present? HypertrackV3.log_error( "Message Id already seen", { sns_message_id: { request: request.headers['x_amz_sns_message_id'], cache: cached, } } ) return self.serve(400) end Rails.cache.write( "/hypertrack_v3/#{request.headers['x_amz_sns_message_id']}", true, expires_in: 1.hour ) begin data = JSON.parse(request.body, object_class: OpenStruct) rescue JSON::ParserError => err HypertrackV3.log_exception(err) end res = true data.each do |datum| if @@hooks.include? datum.type.to_sym res &= @@hooks[datum.type.to_sym].(datum.device_id, datum.data, datum.created_at, datum.recorded_at) else res = false end end self.serve(res ? 200 : 400) end |
.parse_request(env) ⇒ Object
241 242 243 244 245 246 247 248 |
# File 'lib/hypertrack_v3.rb', line 241 def self.parse_request(env) OpenStruct.new({ headers: env.select {|k,v| k.to_s.start_with? 'HTTP_'} .collect {|key, val| [key.to_s.sub(/^HTTP_/, '').downcase, val]}.to_h, params: env['rack.request.query_hash'], body: env['rack.input']&.read }) end |
.register_hook(name, callable) ⇒ Object
216 217 218 219 220 |
# File 'lib/hypertrack_v3.rb', line 216 def self.register_hook(name, callable) raise RegisterHookError("Invalid name argument: #{name}") unless @@hooks.keys.include? name.to_sym raise RegisterHookError("Invalid callable argument: #{callable}") unless callable.respond_to? :call @@hooks[name.to_sym] = callable end |
.register_with_hypertrack(request) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/hypertrack_v3.rb', line 155 def self.register_with_hypertrack(request) register_data = JSON.parse(request.body) resp = self.client.get register_data["SubscribeURL"] data = Nokogiri::XML(resp.body) data.remove_namespaces! token = data.at_xpath('//SubscriptionArn')&.content return self.serve(400, {error: 'SubscriptionArn not found'}) if token.empty? Rails.cache.write('/hypertrack_v3/subscription_arn', token, expires_in: 100.years) self.serve(200) end |
.serve(code, params = {}) ⇒ Object
250 251 252 253 254 255 256 |
# File 'lib/hypertrack_v3.rb', line 250 def self.serve(code, params={}) [ code, {"Content-Type" => "application/json; charset=utf-8"}, [params.to_json] ] end |