Class: Webhukhs::ReceiveWebhooksController

Inherits:
ActionController::API
  • Object
show all
Defined in:
lib/webhukhs/controllers/receive_webhooks_controller.rb

Overview

Receives incoming webhook HTTP requests and dispatches handlers.

Defined Under Namespace

Classes: HandlerInactive, UnknownHandler

Instance Method Summary collapse

Instance Method Details

#createvoid

This method returns an undefined value.

Persists and schedules processing for an incoming webhook request.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/webhukhs/controllers/receive_webhooks_controller.rb', line 17

def create
  Rails.error.set_context(**Webhukhs.configuration.error_context)
  handler = lookup_handler(service_id)
  raise HandlerInactive unless handler.active?
  handler.handle(request)
  render(json: {ok: true, error: nil})
rescue UnknownHandler => e
  Rails.error.report(e, severity: :error)
  render_error_with_status("No handler found for #{service_id.inspect}", status: :not_found)
rescue HandlerInactive => e
  Rails.error.report(e, severity: :error)
  render_error_with_status("Webhook handler #{service_id.inspect} is inactive", status: :service_unavailable)
rescue => e
  raise unless handler
  raise if handler.expose_errors_to_sender?
  Rails.error.report(e, severity: :error)
  render_error_with_status("Internal error (#{e})")
end

#lookup_handler(service_id_str) ⇒ Webhukhs::BaseHandler

Resolves a handler class from configuration for a service id.

Parameters:

  • service_id_str (String)

    service identifier from request path

Returns:

Raises:

  • (UnknownHandler)

    when no active handler is configured for service id



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/webhukhs/controllers/receive_webhooks_controller.rb', line 58

def lookup_handler(service_id_str)
  active_handlers = Webhukhs.configuration.active_handlers.with_indifferent_access
  # The config can specify a mapping of:
  # {"service-1" => MyHandler }
  # or
  # {"service-2" => "MyOtherHandler"}
  # We need to support both, because `MyHandler` is not loaded yet when Rails initializers run.
  # Zeitwerk takes over after the initializers. So we can't really use a module in the init cycle just yet.
  # We can, however, use the module name - and resolve it lazily, later.
  handler_class_or_class_name = active_handlers.fetch(service_id_str)
  handler_class = handler_class_or_class_name.respond_to?(:constantize) ? handler_class_or_class_name.constantize : handler_class_or_class_name
  handler_class.new
rescue KeyError
  raise UnknownHandler
end

#render_error_with_status(message_str, status: nil) ⇒ void

This method returns an undefined value.

Renders standardized error response payload.

Parameters:

  • message_str (String)

    human-readable error message

  • status (Symbol) (defaults to: nil)

    HTTP response status



48
49
50
51
# File 'lib/webhukhs/controllers/receive_webhooks_controller.rb', line 48

def render_error_with_status(message_str, status: nil)
  json = {ok: false, error: message_str}
  render(json: json, status: status)
end

#service_idString

Extracts webhook service identifier from route parameters.

Returns:

  • (String)


39
40
41
# File 'lib/webhukhs/controllers/receive_webhooks_controller.rb', line 39

def service_id
  params.require(:service_id)
end