AshDispatch.WebhookHandlers.Resend (AshDispatch v0.5.1)

View Source

Handles webhooks from Resend for email delivery events.

All events are tracked with dedicated timestamp fields for easy querying:

Delivery Lifecycle Events

  • email.sent → sent_at
  • email.delivered → delivered_at
  • email.delivery_delayed → delivery_delayed_at
  • email.failed → failed_at

Engagement Events

  • email.opened → opened_at
  • email.clicked → clicked_at

Bounce/Complaint Events

  • email.bounced → bounced_at
  • email.complained → complained_at

Other Events

  • email.received, email.scheduled → stored in provider_response only

All events also store full webhook payload in provider_response for debugging.

See: https://resend.com/docs/api-reference/webhooks

Usage

From a Phoenix controller:

defmodule MyAppWeb.ResendWebhookController do
  use MyAppWeb, :controller
  alias AshDispatch.WebhookHandlers.Resend

  def handle(conn, params) do
    case Resend.process_webhook(params) do
      {:ok, _receipt} ->
        json(conn, %{status: "ok"})

      {:error, :not_found} ->
        json(conn, %{status: "ok", message: "receipt not found"})

      {:error, reason} ->
        json(conn, %{status: "error", message: inspect(reason)})
    end
  end
end

Summary

Functions

Process a Resend webhook event.

Functions

process_webhook(params)

Process a Resend webhook event.

Parameters

  • params - Webhook payload from Resend containing:
    • type - Event type (e.g., "email.opened")
    • created_at - ISO 8601 timestamp
    • data - Event-specific data including email_id

Returns

  • {:ok, receipt} - Successfully processed webhook
  • {:error, :not_found} - Delivery receipt not found for email_id
  • {:error, :missing_email_id} - Webhook missing email_id field
  • {:error, :invalid_format} - Webhook payload invalid
  • {:error, reason} - Other error