Expand description
Email: send with adapters (log, Resend, Cloudflare), receive from Email Routing.
Sending is Rails’ Action Mailer without the class: build an Email
(several recipients, cc, bcc, headers, attachments and inline images) and
hand it to send, or to deliver_later / deliver_in to send it
from the background jobs queue (see jobs) so the request
does not wait for the provider and a failed delivery is retried.
Receiving is Action Mailbox: receive is the Worker’s email entry
point and hands each message to the app as an InboundEmail. In
ocre dev, dev_routes serves mailer previews, the emails sent, and a
form that delivers test email to the mailbox.
use axum::extract::State;
use ocre::mail::{self, Email};
use ocre::{Ctx, Result};
async fn welcome(State(ctx): State<Ctx>) -> Result<&'static str> {
let email = Email::new("ada@example.com", "Welcome", "Hello Ada,\n\nhttps://example.com/start\n")
.html("<p>Hello Ada,</p><p><a href=\"https://example.com/start\">Start</a></p>");
mail::send(&ctx, email).await?;
Ok("sent")
}§Configuration
The MAIL_ADAPTER Worker variable picks how
mail leaves the Worker, with no guessing from which keys happen to be set,
so a development machine holding a real API key never sends by accident:
log: prints the whole email (headers, text, HTML, attachments) to the Worker console betweenLOG_PREFIXlines, like Rails’ letter_opener, and in debug builds keeps the last 20 for/ocre/dev/mailers(seedev_routes).ocre newwritesMAIL_ADAPTER=logto.dev.vars, which overrides thebindings.textvariables inocre dev. No configuration, no limits.resend:POST https://api.resend.com/emailswith theRESEND_API_KEYsecret,MAIL_FROMon a domain verified in Resend. Free plan (September 2026): 100 emails a day, 3,000 a month, one domain; any recipient.cloudflare: Cloudflare Email Service through theEMAIL_BINDINGbindings.sendEmail()binding,MAIL_FROMon a domain onboarded to Email Service. Workers Free (September 2026) only delivers to verified destination addresses of the account; any recipient needs Workers Paid (3,000 a month included).
The sender is the email’s own from, else the
MAIL_FROM variable, noreply@example.com or
Name <noreply@example.com>. With MAIL_ADAPTER
unset, sending fails with an Error::Internal
naming the fix, so a production Worker never drops mail silently. For
sign-up and password-reset mail on the free plan, use Resend.
Receiving uses Cloudflare Email Routing, free and unlimited on every plan.
Every line Ocre logs about mail starts with LOG_PREFIX.
Structs§
- Attachment
- A file attached to an
Email, or an inline image shown by its HTML. - An outgoing email: recipients, a subject, a plain-text body, and optionally HTML, headers and attachments.
- Inbound
Email - An email that Cloudflare Email Routing delivered to the Worker, handed to the app’s mailbox.
- Preview
- A mailer action shown at
/ocre/dev/mailersinocre dev, rendered with sample data, like Rails’ mailer previews.
Constants§
- APP_URL
- Name of the Worker variable holding the app’s public address,
https://shop.example.com, for links in emails. - EMAIL_
BINDING - Name of the
bindings.sendEmail()binding used whenMAIL_ADAPTER = "cloudflare". - LOG_
PREFIX - Prefix of every line Ocre logs about mail, e.g. in
ocre devoutput. - MAIL_
ADAPTER - Name of the Worker variable that chooses the adapter:
log,resendorcloudflare. - MAIL_
FROM - Name of the Worker variable holding the sender address.
- RESEND_
API_ KEY - Name of the Worker secret holding the Resend API key, used when
MAIL_ADAPTER = "resend".
Functions§
- address_
with_ name - Formats
Name <address>, quoting the name when needed, like Rails’email_address_with_name. - deliver_
in - Checks
emailnow and sends it from the jobs queue afterdelay, like Rails’deliver_later(wait:). - deliver_
later - Checks
emailnow and sends it later from the background jobs queue, like Rails’deliver_later. - dev_
routes - Development pages for email, served by
ocre devonly, like Rails’/rails/mailersand Action Mailbox’s conductor. - receive
- Runs the app’s mailbox
handlerfor an email from Cloudflare Email Routing; the Worker’semailentry point. - send
- Sends
emailnow, fromMAIL_FROM, with the adapter named byMAIL_ADAPTER. - url
- An absolute URL for
pathon the app’s public address, theAPP_URLvariable (Rails’_urlhelpers in mailers).