The bounce service: tells senders about failed and delayed delivery.
Notifications are built with Sovite.DSN and queued like any other
message, from the null sender (MAIL FROM:<>). The rules:
- Failed recipients are reported to the sender in one notification per delivery attempt.
- Delay warnings (
queue.delay_warning) are sent once per message. - Nothing is ever sent to the null sender (RFC 5321 §6.1, RFC 3834):
a failed notification is a double bounce. It is reported to
bounce.double_bounce_recipientwhen set, otherwise only logged. A failed double-bounce report is only logged, so notifications can never loop.
Summary
Types
Options: :hostname, :directory (the spool), :max_lifetime
(milliseconds, for "will retry until"), :double_bounce_recipient
(or nil), and optionally :expand, a function that turns the
notification's recipient into the addresses to queue it for (aliases).
Where the original message is, as returned by Sovite.Queue.Spool.load/2.
Functions
Reports recipients (address and Sovite.Queue.Record.details()
pairs) of the message in entry.
Types
@type opts() :: %{ :hostname => String.t(), :directory => Path.t(), :max_lifetime => pos_integer(), :double_bounce_recipient => String.t() | nil, optional(:expand) => (String.t() -> [String.t(), ...]) }
Options: :hostname, :directory (the spool), :max_lifetime
(milliseconds, for "will retry until"), :double_bounce_recipient
(or nil), and optionally :expand, a function that turns the
notification's recipient into the addresses to queue it for (aliases).
@type source() :: %{ path: Path.t(), message_offset: non_neg_integer(), message_size: non_neg_integer() }
Where the original message is, as returned by Sovite.Queue.Spool.load/2.
Functions
@spec notify( :failure | :delay, Sovite.Queue.Entry.t(), source(), [{String.t(), map()}], opts() ) :: {:ok, String.t() | nil} | {:error, term()}
Reports recipients (address and Sovite.Queue.Record.details()
pairs) of the message in entry.
Returns {:ok, queue_id} for the queued notification, {:ok, nil} when
the rules say not to send one, or {:error, reason} if it could not be
queued; the caller should then try again later.