Skip to content

Reply to emails from Workers

You can reply to incoming emails with another new message and implement smart auto-responders programmatically, adding any content and context in the main body of the message. Think of a customer support email automatically generating a ticket and returning the link to the sender, an out-of-office reply with instructions when you are on vacation, or a detailed explanation of why you rejected an email.

Reply to emails is a new method of the EmailMessage object in the Runtime API. Here is how it works:

import { EmailMessage } from "cloudflare:email";
import { createMimeMessage } from "mimetext";
export default {
async email(message, env, ctx) {
const ticket = createTicket(message);
const msg = createMimeMessage();
msg.setHeader("In-Reply-To", message.headers.get("Message-ID"));
msg.setSender({ name: "Thank you for your contact", addr: "<SENDER>@example.com" });
msg.setRecipient(message.from);
msg.setSubject("Email Routing Auto-reply");
msg.addMessage({
contentType: 'text/plain',
data: `We got your message, your ticket number is ${ ticket.id }`
});
const replyMessage = new EmailMessage(
"<SENDER>@example.com",
message.from,
msg.asRaw()
);
await message.reply(replyMessage);
}
}

To mitigate security risks and abuse, replying to incoming emails has a few requirements:

  • The incoming email has to have valid DMARC.
  • The email can only be replied to once in the same EmailMessage event.
  • The In-Reply-To header of the reply message must be set to the Message-ID of the incoming message.
  • The recipient in the reply must match the incoming sender.
  • The outgoing sender domain must match the same domain that received the email.

If these and other internal conditions are not met, then reply() will fail with an exception, otherwise you can freely compose your reply message and send it back to the original sender.