Delivery records, appended to a queue file after the message by
Sovite.Queue.Spool.append/3.
A queue file is never rewritten. Instead, each delivery attempt appends
what happened, and Sovite.Queue.Entry replays the records to get the
message's current state:
{:recipient, address, status, details}- the outcome of a delivery attempt for one recipient.:deliveredand:failedare final;:deferredwill be retried.{:notified, addresses}- the sender was told about these failed recipients (or, for a null sender, it was decided not to tell anyone).{:retry, attempts, next_attempt}- the message was deferred afterattemptsattempts, untilnext_attempt.:warned- a delay warning was sent.
Summary
Types
@type details() :: %{ :status => String.t(), :reply => String.t() | nil, :remote => String.t() | nil, :smtp => boolean(), :at => DateTime.t(), optional(:action) => :delivered | :relayed | nil, optional(:report) => boolean() }
Details of a recipient outcome. status is the enhanced status code,
reply the remote server's reply or a local diagnostic, remote the
server that gave it ("mx.example.com[192.0.2.25]"), and smtp whether
reply came from a remote SMTP server.
For a delivered recipient, action is what a success notification
(DSN, RFC 3461) would report: :delivered to a mailbox, or :relayed
to a server that does not send notifications. Without it (a server
that does, or a discarded message), Sovite sends none. report asks
for a "relayed" notification even without NOTIFY=SUCCESS, as
DELIVERBY does (RFC 2852 §4.1.4.1).
@type status() :: :delivered | :failed | :deferred
@type t() :: {:recipient, String.t(), status(), details()} | {:notified, [String.t()]} | {:retry, pos_integer(), DateTime.t()} | :warned