Inbound email for Phoenix: emails to your app, kept, read and given to your code.
defmodule MyApp.Mailboxes do
use Letterbox.Routing
route "support@", to: MyApp.SupportMailbox
end
defmodule MyApp.SupportMailbox do
use Letterbox.Mailbox
@impl true
def process(message), do: MyApp.Tickets.open(message.verified_from || message.from, message.text)
endA message reaches the app through an ingress (Letterbox.Ingress): a
provider's webhook (Letterbox.Ingress.Resend), a relay of raw emails
(Letterbox.Ingress.Relay), or the app's own code with ingest/2.
Letterbox keeps the raw email in the app's store, a row for it in the
app's database (Letterbox.Inbound), and, out of the request
(Letterbox.Runner), reads it (Letterbox.Email) and gives it to the
mailbox its routes name (Letterbox.Routing).
Telemetry
[:letterbox, :ingest, :start | :stop | :exception]- a message kept, with:ingressand:bytes; the:stophas its:result, the row's status (or:error).[:letterbox, :process, :start | :stop | :exception]- a mailbox given a message, with:id,:mailbox,:ingressand:attempt; the:stophas its:result::delivered,:bounced,:erroror:exception.
Summary
Functions
Deletes a message: its row and its raw email.
A message's row, or nil.
Deletes the messages done with for longer than days (their row and
their raw email): delivered, bounced, unrouted or failed. Gives how many.
Takes a raw email from the app's own code: kept, then given to its mailbox out of the caller. Gives the message's row.
The messages, the newest first. Options: :status (one or a list),
:mailbox (a module), :limit (50) and :offset.
A message as its mailbox gets it (Letterbox.Message), read again from its raw email.
A message's raw email, as it came.
Gives the runner the messages that were waiting: those to fetch from
their provider, and those for their mailbox. After a restart, with the
local runner, they are not lost (Letterbox.Sweeper does it on start).
Gives how many.
Gives a message to its mailbox again, from its first attempt: one that failed, bounced or was not routed, once the cause is fixed.
Functions
@spec delete(Letterbox.Inbound.t() | String.t()) :: :ok | {:error, term()}
Deletes a message: its row and its raw email.
@spec get(String.t()) :: Letterbox.Inbound.t() | nil
A message's row, or nil.
@spec incinerate(pos_integer()) :: non_neg_integer()
Deletes the messages done with for longer than days (their row and
their raw email): delivered, bounced, unrouted or failed. Gives how many.
@spec ingest(binary(), keyword()) :: {:ok, Letterbox.Inbound.t()} | {:error, term()}
Takes a raw email from the app's own code: kept, then given to its mailbox out of the caller. Gives the message's row.
Options:
:ingress- a name for where it came from ("app").:external_id- its id where it came from: the same id twice is one message.:recipients- the addresses the mail server took it for (its envelope), when they are known.:meta- a map kept with it.:runner- for this message only (Letterbox.Runner).
@spec list(keyword()) :: [Letterbox.Inbound.t()]
The messages, the newest first. Options: :status (one or a list),
:mailbox (a module), :limit (50) and :offset.
@spec message(Letterbox.Inbound.t() | String.t()) :: {:ok, Letterbox.Message.t()} | {:error, term()}
A message as its mailbox gets it (Letterbox.Message), read again from its raw email.
@spec raw(Letterbox.Inbound.t() | String.t()) :: {:ok, binary()} | {:error, term()}
A message's raw email, as it came.
@spec resume(keyword()) :: non_neg_integer()
Gives the runner the messages that were waiting: those to fetch from
their provider, and those for their mailbox. After a restart, with the
local runner, they are not lost (Letterbox.Sweeper does it on start).
Gives how many.
@spec retry(Letterbox.Inbound.t() | String.t(), keyword()) :: {:ok, Letterbox.Inbound.t()} | {:error, term()}
Gives a message to its mailbox again, from its first attempt: one that failed, bounced or was not routed, once the cause is fixed.