PhoenixKit.Email.ProviderOptions (phoenix_kit v1.7.205)

Copy Markdown View Source

Per-provider send settings — the "Advanced" half of a SendProfile.

One source of truth for what each email provider actually accepts, shared by the Send Settings form (which renders fields_for/1) and by the delivery worker (which calls to_provider_options/2 to turn a profile's advanced map into Swoosh provider options).

Only options the underlying Swoosh adapter really reads are declared here. An option the adapter ignores is worse than a missing one: it looks configured and then silently does nothing — which is exactly what the old free-form "Advanced (JSON)" textarea did, since nothing ever read advanced at send time.

smtp declares no options on purpose: Swoosh.Adapters.SMTP takes all its knobs (relay, port, TLS) from the connection itself and reads no per-email provider_options at all. Rendering fields for it would be the same lie in a new shape.

Storage vs. wire format

advanced is a JSONB column, so it round-trips with string keys. Swoosh, meanwhile, matches provider options on atom keys — and for SES tags it pattern-matches %{name: name, value: value} strictly, so a string-keyed tag map would raise inside the adapter. cast/2 handles the storage side, to_provider_options/2 the wire side. Atoms come from the :option field of a literal spec below, never from user input, so there is no dynamic atom creation.

Summary

Functions

Normalizes raw form input into the map stored in advanced.

Returns the send settings a given provider supports, in display order.

Renders a stored value back into the text the form input shows.

Translates a profile's stored advanced map into Swoosh provider options.

Types

field()

@type field() :: %{
  key: String.t(),
  option: atom(),
  label: String.t(),
  type: :text | :number,
  cast: :string | :integer | :string_list | :name_value_list,
  placeholder: String.t(),
  help: String.t()
}

Functions

cast(provider_kind, raw)

@spec cast(String.t() | nil, map() | nil) :: map()

Normalizes raw form input into the map stored in advanced.

Keeps only keys the provider declares, so flipping a profile from SES to Brevo can't leave an orphan configuration_set_name behind to be sent to an adapter that has no idea what it is. Blank values are dropped rather than stored as "", so an untouched field stores nothing at all.

fields_for(arg1)

@spec fields_for(String.t() | nil) :: [field()]

Returns the send settings a given provider supports, in display order.

An unknown provider returns [] rather than raising: a profile whose integration was deleted, or one pointing at a provider some other module registered, must still render its common fields instead of 500ing.

to_input_value(field, advanced)

@spec to_input_value(field(), map() | nil) :: String.t()

Renders a stored value back into the text the form input shows.

The inverse of cast_value/2 for the list types, so editing a profile shows campaign=newsletter, env=prod rather than a raw JSON array.

to_provider_options(provider_kind, advanced)

@spec to_provider_options(String.t() | nil, map() | nil) :: map()

Translates a profile's stored advanced map into Swoosh provider options.

Returns a map keyed by the atoms Swoosh expects. Anything not declared by the provider is ignored — including leftovers written by the old raw-JSON textarea, which must never reach an adapter unvetted.