Unified email provider behaviour.
Covers interception (pre/post send hooks), DB templates, AWS config, and provider detection. The emails package implements this fully. The DefaultProvider is a no-op that passes emails through unchanged.
Summary
Callbacks
Offers the provider the chance to take delivery over — i.e. queue the message instead of sending it on this process.
Callbacks
@callback aws_configured?() :: boolean()
@callback get_aws_access_key() :: String.t()
@callback get_aws_region() :: String.t()
@callback get_aws_secret_key() :: String.t()
@callback handle_after_send(Swoosh.Email.t(), {:ok, any()} | {:error, any()}) :: :ok
@callback intercept_before_send( Swoosh.Email.t(), keyword() ) :: Swoosh.Email.t()
@callback maybe_enqueue( Swoosh.Email.t(), keyword() ) :: :continue | {:queued, term()}
Offers the provider the chance to take delivery over — i.e. queue the message instead of sending it on this process.
Called by PhoenixKit.Mailer right after intercept_before_send/2, on both
the integration and the static-mailer path, so a queue covers every outgoing
message and not just the ones a caller routed through the package. Returning
{:queued, ref} means "accepted, do not send now" and ref is echoed back to
the caller as {:ok, %{id: ref, queued: true}}; :continue means send
normally.
Optional: it is skipped when the provider does not export it, so a package built against an older core still satisfies this behaviour.
The message handed here is the intercepted one, so whatever
intercept_before_send/2 recorded or stamped on it is already in place and
should be carried through the queue.
Sending the queued message back out
The worker passes already_intercepted: true, which suppresses the second
interception — interception is not required to be idempotent, so core does
not run it twice and hope — and implies skip_queue: true, so the send is
not offered straight back to the queue it came from. Passing skip_queue: true as well is harmless and still the clearer thing to write.
Against a core that predates already_intercepted the opt is simply
unknown, the interceptor runs again on the way out, and a provider that
creates a tracking row per interception has to recognise its own message
(its tracking header is already on the email by then) or it will log the
same send twice.
@callback send_test_tracking_email(String.t(), String.t() | nil) :: {:ok, Swoosh.Email.t()} | {:error, any()}
@callback track_usage(map()) :: :ok
Functions
@spec current() :: module()
Returns the configured email provider module, defaulting to DefaultProvider.