pub struct InboundEmail { /* private fields */ }Expand description
An email that Cloudflare Email Routing delivered to the Worker, handed to the app’s mailbox.
receive builds it. The envelope (from, to) comes from
Cloudflare; headers and bodies are parsed from the raw message
(multipart, quoted-printable, base64, RFC 2047 encoded words; files in
attachments, the bytes in raw). Bounce it with
reject or pass it on with forward.
Receiving is free and unlimited on every plan.
§Examples
use ocre::mail::InboundEmail;
use ocre::{Ctx, Result};
// src/mailbox.rs
pub async fn receive(_ctx: Ctx, email: InboundEmail) -> Result<()> {
match email.to() {
"support@example.com" => email.forward("team@example.com").await?,
_ => email.reject("Unknown address"),
}
Ok(())
}Implementations§
Source§impl InboundEmail
impl InboundEmail
Sourcepub fn from(&self) -> &str
pub fn from(&self) -> &str
Returns the envelope sender (SMTP MAIL FROM), checked by Cloudflare.
The From header may differ: read it with email.header("From").
§Examples
if email.from().ends_with("@example.com") {
// a colleague
}Sourcepub fn to(&self) -> &str
pub fn to(&self) -> &str
Returns the envelope recipient: the address of this app that received the email.
Match on it to route several addresses to one Worker.
§Examples
let team = email.to().starts_with("support@");Sourcepub fn subject(&self) -> &str
pub fn subject(&self) -> &str
Returns the decoded Subject header, or "" when it is missing.
§Examples
let urgent = email.subject().contains("URGENT");Sourcepub fn header(&self, name: &str) -> Option<&str>
pub fn header(&self, name: &str) -> Option<&str>
Returns the first header with this name (case-insensitive), decoded.
Folded lines are joined and RFC 2047 encoded words decoded. None
when the message has no such header.
§Examples
let id = email.header("message-id").unwrap_or("");Sourcepub fn headers(&self) -> &[(String, String)]
pub fn headers(&self) -> &[(String, String)]
Returns every header, in message order, as decoded (name, value) pairs.
Repeated headers (Received, …) appear once per occurrence.
§Examples
let hops = email.headers().iter().filter(|(name, _)| name.eq_ignore_ascii_case("Received")).count();Sourcepub fn text(&self) -> Option<&str>
pub fn text(&self) -> Option<&str>
Returns the first text/plain part, decoded to UTF-8, or None when there is none.
§Examples
let body = email.text().unwrap_or_default();Sourcepub fn attachments(&self) -> &[Attachment]
pub fn attachments(&self) -> &[Attachment]
Returns the files of the email, decoded: every part that is not the first text or HTML body.
Inline images carry their content_id. Store them in R2
(ocre::storage) rather than D1; they are the sender’s files, so
check the type and size before keeping them.
§Examples
for file in email.attachments() {
worker::console_log!("{} ({}, {} bytes)", file.filename, file.content_type, file.content.len());
}Sourcepub fn html(&self) -> Option<&str>
pub fn html(&self) -> Option<&str>
Returns the first text/html part, decoded to UTF-8, or None when there is none.
It is the sender’s HTML: never render it unescaped.
§Examples
let has_html = email.html().is_some();Sourcepub fn raw(&self) -> &[u8] ⓘ
pub fn raw(&self) -> &[u8] ⓘ
Returns the whole message as received (RFC 5322 bytes), e.g. to store it in R2 or read attachments.
§Examples
let size = email.raw().len();Sourcepub async fn forward(&self, to: &str) -> Result<()>
pub async fn forward(&self, to: &str) -> Result<()>
Forwards the email unchanged to to, which must be a verified destination address of the Cloudflare account.
§Errors
Error::Internal when Cloudflare refuses, typically because
to is not a verified destination address in Email Routing (the
message says so).
§Examples
email.forward("team@example.com").await?;