Mailglass.Webhook.Router (Mailglass v0.1.0)

Copy Markdown View Source

Router macro for mounting Mailglass webhook endpoints in an adopter Phoenix router.

Mirrors the Phoenix.LiveDashboard.Router + Oban.Web.Router idiom: the macro is invoked inside an adopter-owned scope block with adopter-owned pipe_through (CONTEXT D-06). Mailglass does NOT provide its own router — adopters keep full control over the surrounding pipeline (CORS, IP allowlist, rate-limit, endpoint selection).

Usage

defmodule MyAppWeb.Router do
  use Phoenix.Router
  import Mailglass.Webhook.Router

  pipeline :mailglass_webhooks do
    plug :accepts, ["json"]
    # NO :browser, :fetch_session, :protect_from_forgery — webhooks
    # do not carry a session or participate in CSRF.
  end

  scope "/", MyAppWeb do
    pipe_through :mailglass_webhooks
    mailglass_webhook_routes "/webhooks"
  end
end

Generates two post routes by default (CONTEXT D-07 — provider-per-path discipline):

Options

  • :providers — list of provider atoms. v0.1 validated set: [:postmark, :sendgrid] (default both). Unknown providers raise ArgumentError at compile time — invalid config fails at router-mount, not at request time (D-07).
  • :as — route helper prefix. Default :mailglass_webhook per CONTEXT D-08 (shared vocabulary lock with the Phase 5 admin mount). Each generated route's helper is :"#{as}_#{provider}".

The provider list is locked at v0.1 per PROJECT D-10 — Mailgun/SES/Resend land at v0.5. Additions to @valid_providers are minor-version API extensions (additive); they do not break adopters already passing the default.

Endpoint wiring (separate from this macro)

The macro only generates routes. Adopters MUST also configure Plug.Parsers in their endpoint with Mailglass's Mailglass.Webhook.CachingBodyReader:

plug Plug.Parsers,
  parsers: [:json],
  pass: ["*/*"],
  json_decoder: Jason,
  body_reader: {Mailglass.Webhook.CachingBodyReader, :read_body, []},
  length: 10_000_000   # 10 MB cap; SendGrid batches up to 128 events
                       # fit comfortably under 8 MB with 2 MB headroom

Without the CachingBodyReader wiring, Mailglass.Webhook.Plug raises %Mailglass.ConfigError{type: :webhook_caching_body_reader_missing} at request time — the 500 is the diagnostic.

Summary

Functions

mailglass_webhook_routes(path, opts \\ [])

(macro)

Generate provider-per-path POST routes for Mailglass.Webhook.Plug.

Must be invoked inside a Phoenix.Router scope block. See the module doc for full usage and endpoint-wiring requirements.

Options

  • :providers — defaults to [:postmark, :sendgrid]
  • :as — defaults to :mailglass_webhook

Raises ArgumentError at compile time if :providers contains an unknown provider atom — fails at router-mount time, not request time.