Modules
Inbound email for Phoenix: emails to your app, kept, read and given to your code.
An email address and the name that came with it.
A file that came with a message: a photograph, a PDF, an invitation, a forwarded email.
The text of an email in UTF-8, whatever charset it was written in.
Letterbox's configuration, in the app's
The development page: write an email to the app and see what became of it, as Action Mailbox's conductor does. Mounted in the app's router, where only developers reach it
The email channel: a raw email as a Letterbox.Message (parse/2), and
an email made from fields (build/1), for tests and the development
page.
A message that came in: one row each, in letterbox_inbound, with the
raw email kept in the app's store (:raw_key).
How messages reach the app: a provider's webhook, a relay, a module of
the app's own. Each is named in the config, and its webhook is a route
of the app's (Letterbox.Plug), POST /inbound/webhooks/<name> as
mix letterbox.install writes it
Raw emails, posted as they are by whatever has them: a mail server's pipe (Postfix, Exim), a Cloudflare Email Worker, a script.
Resend's inbound emails.
An email's structure (MIME, RFC 2045 to 2049): its parts, their headers and their bodies, still encoded.
The headers of an email or of one of its parts (RFC 5322 and MIME), read as mail clients write them, not only as the RFCs say they should.
The app's code that receives a message: one module for each kind
(support, replies, photographs), named in the routes
(Letterbox.Routing).
A message that came to the app, as its mailbox gets it.
The table of Letterbox, in a migration of the app.
The webhooks of the ingresses (Letterbox.Ingress), a route of the
app's own router. mix letterbox.install writes one for every
ingress, the ingress named by the path
Which mailbox takes which message: the app's routes, in one module.
What runs Letterbox's work out of the request: fetching a message its provider told of, and giving each message to its mailbox. One runner does all of it, and another takes its place with no other change.
A runner (Letterbox.Runner) in a process of Letterbox's: each job a
task of Letterbox.TaskSupervisor, tried again with a backoff (one
second, then doubling, at most a minute), up to :max_attempts times.
A runner (Letterbox.Runner) in Oban: each job an Oban job
(Letterbox.Runner.Oban.Worker), kept in the app's database, so it
outlives a deploy, and tried again with Oban's backoff, up to
Letterbox.Config's :max_attempts. A job waiting is not inserted twice.
The Oban worker of Letterbox.Runner.Oban: a job's map as its
arguments, run with Letterbox.Runner.run/1, tried again by Oban when
it fails.
A process of the app's that keeps Letterbox's table: on start, the
messages that were waiting go to the runner again (Letterbox.resume/1);
then, every hour, those done with for :incinerate_after days are
deleted (Letterbox.incinerate/1).
An app's tests of its mailboxes and routes.
Mix Tasks
Generates the migration of Letterbox's table in the app's repo: the one that installs it, or, after an upgrade of Letterbox, the one that brings it to its latest version.
Installs Letterbox in a Phoenix application.