Module: Hooksmith::Rails::WebhooksController

Extended by:
ActiveSupport::Concern
Defined in:
lib/hooksmith/rails/webhooks_controller.rb

Overview

A concern for Rails controllers that handle webhooks.

This concern provides standardized webhook handling with:

  • Automatic request verification (if configured)
  • Consistent response codes (200 for success, 400 for bad request, 500 for errors)
  • Error logging and instrumentation
  • Skip CSRF protection for webhook endpoints

Examples:

Basic usage

class WebhooksController < ApplicationController
  include Hooksmith::Rails::WebhooksController

  def stripe
    handle_webhook(provider: 'stripe', event: params[:type], payload: params.to_unsafe_h)
  end
end

With custom error handling

class WebhooksController < ApplicationController
  include Hooksmith::Rails::WebhooksController

  def stripe
    handle_webhook(provider: 'stripe', event: params[:type], payload: params.to_unsafe_h) do |result|
      # Custom success handling
      render json: { processed: true, result: result }
    end
  rescue Hooksmith::VerificationError => e
    render json: { error: 'Invalid signature' }, status: :unauthorized
  end
end

Async processing with ActiveJob

class WebhooksController < ApplicationController
  include Hooksmith::Rails::WebhooksController

  def stripe
    handle_webhook_async(provider: 'stripe', event: params[:type], payload: params.to_unsafe_h)
  end
end

Instance Method Summary collapse

Instance Method Details

#handle_webhook(provider:, event:, payload:) {|result| ... } ⇒ void

This method returns an undefined value.

Handles a webhook synchronously.

Parameters:

  • provider (String, Symbol)

    the webhook provider

  • event (String, Symbol)

    the event type

  • payload (Hash)

    the webhook payload

Yields:

  • (result)

    optional block for custom success handling

Yield Parameters:

  • result (Object)

    the result from the processor



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/hooksmith/rails/webhooks_controller.rb', line 61

def handle_webhook(provider:, event:, payload:)
  result = Hooksmith::Dispatcher.new(provider:, event:, payload:).run!

  if block_given?
    yield(result)
  else
    head :ok
  end
rescue Hooksmith::MultipleProcessorsError => e
  Hooksmith.logger.error("Webhook error: #{e.message}")
  head :internal_server_error
rescue StandardError => e
  Hooksmith.logger.error("Webhook processing failed: #{e.message}")
  head :internal_server_error
end

#handle_webhook_async(provider:, event:, payload:, queue: :default) ⇒ void

This method returns an undefined value.

Handles a webhook asynchronously using ActiveJob.

Requires Hooksmith::Jobs::DispatcherJob to be available.

Parameters:

  • provider (String, Symbol)

    the webhook provider

  • event (String, Symbol)

    the event type

  • payload (Hash)

    the webhook payload

  • queue (Symbol, String) (defaults to: :default)

    the queue to use (default: :default)



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/hooksmith/rails/webhooks_controller.rb', line 86

def handle_webhook_async(provider:, event:, payload:, queue: :default)
  unless defined?(Hooksmith::Jobs::DispatcherJob)
    raise 'Hooksmith::Jobs::DispatcherJob is not available. Ensure ActiveJob is loaded.'
  end

  Hooksmith::Jobs::DispatcherJob.set(queue:).perform_later(
    provider: provider.to_s,
    event: event.to_s,
    payload: payload.as_json
  )

  head :ok
end