Mailglass.Adapters.Swoosh (Mailglass v1.0.0)

Copy Markdown View Source

Adapter bridging to any Swoosh.Adapter (TRANS-03).

Adopters configure their Swoosh adapter once and mailglass wraps it — they keep existing Postmark/SendGrid/Mailgun/SES/Resend/SMTP config. mailglass adds error normalization into %Mailglass.SendError{} and telemetry instrumentation via Mailglass.Telemetry.dispatch_span/2.

Pure: no DB, no PubSub, no Process.put. Caller's process owns the HTTP request via Swoosh's :api_client (adopter-supplied, typically Finch). LIB-06 satisfied.

Configuration

config :mailglass,
  adapter: {Mailglass.Adapters.Swoosh,
            swoosh_adapter: {Swoosh.Adapters.Postmark,
                             api_key: System.fetch_env!("POSTMARK_API_KEY")}}

The :swoosh_adapter opt carries either a module (for Swoosh adapters with no config) or a {module, opts} tuple.

Error mapping (v0.1)

Swoosh shapeMapped SendError :typeContext fields
{:api_error, status, body}:adapter_failureprovider_status, body_preview (200 bytes), provider_module
Other {:error, reason} atoms:adapter_failurereason_class, provider_module
Malformed responses:adapter_failurereason_class: :malformed

PII policy: body_preview is a 200-byte head of the provider's response body — may contain provider-emitted error strings (never user-supplied content). The 8 forbidden keys (:to, :from, :body, :html_body, :subject, :headers, :recipient, :email) NEVER appear in error context. Phase 6 LINT-02 NoPiiInTelemetryMeta enforces.

What this module does NOT do

  • Does not call Swoosh.Mailer.deliver/1 — forbidden by LINT-01. Calls Swoosh.Adapter.deliver/2 (the behaviour callback) directly.
  • Is not a GenServer — pure function, stateless.
  • Does not touch mailglass_events, mailglass_deliveries, or Phoenix.PubSub. Side-effect-free by design (LIB-06).