Class: Hooksmith::Dispatcher

Inherits:
Object
  • Object
show all
Defined in:
lib/hooksmith/dispatcher.rb

Overview

Dispatcher routes incoming webhook payloads to the appropriate processor.

Examples:

Dispatch a webhook event:

Hooksmith::Dispatcher.new(provider: :stripe, event: :charge_succeeded, payload: payload).run!

Instance Method Summary collapse

Constructor Details

#initialize(provider:, event:, payload:) ⇒ Dispatcher

Initializes a new Dispatcher.



15
16
17
18
19
# File 'lib/hooksmith/dispatcher.rb', line 15

def initialize(provider:, event:, payload:)
  @provider = provider.to_sym
  @event    = event.to_sym
  @payload  = payload
end

Instance Method Details

#run!Object

Runs the dispatcher.

Instantiates each processor registered for the given provider and event, then selects the ones that can handle the payload using the can_handle? method.

  • If no processors qualify, logs a warning.

  • If more than one qualifies, raises MultipleProcessorsError.

  • Otherwise, processes the event with the single matching processor.

Raises:



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/hooksmith/dispatcher.rb', line 30

def run!
  # Optionally record the incoming event before processing.
  Hooksmith::EventRecorder.record!(provider: @provider, event: @event, payload: @payload, timing: :before)

  # Fetch all processors registered for this provider and event.
  entries = Hooksmith.configuration.processors_for(@provider, @event)

  # Instantiate each processor and filter by condition.
  matching_processors = entries.map do |entry|
    processor = Object.const_get(entry[:processor]).new(@payload)
    processor if processor.can_handle?(@payload)
  end.compact

  if matching_processors.empty?
    Hooksmith.logger.warn("No processor registered for #{@provider} event #{@event} could handle the payload")
    return
  end

  # If more than one processor qualifies, raise an error.
  raise MultipleProcessorsError.new(@provider, @event, @payload) if matching_processors.size > 1

  # Exactly one matching processor.
  result = matching_processors.first.process!

  # Optionally record the event after successful processing.
  Hooksmith::EventRecorder.record!(provider: @provider, event: @event, payload: @payload, timing: :after)

  result
rescue StandardError => e
  Hooksmith.logger.error("Error processing #{@provider} event #{@event}: #{e.message}")
  raise e
end