Email agents
Handle inbound email as an event in an agent workflow.
- Libraries
Runtime.AgentsAiChatAgent - npm
agents 0.22.0 - Upstream/API Requires an Email Routing configuration
Email as an input
An Email Worker receives a message through an Email Routing rule. Your handler can inspect it, forward it, or connect it to application state. The example below filters automatic replies before forwarding support mail.
The agents/email helpers are delivered in Runtime.AgentsAiChatAgent; the assembly name does not mean this example creates an AI chat agent or performs model inference.
Support Inbox
This Email Worker forwards support mail to your team and skips automatic replies. isAutoReplyEmail from the Agents SDK's email module returns true when one of three headers marks a message as an automatic reply, such as an out-of-office notice.
open Fable.Core
module Workers = FSharp.CloudEdge.Runtime.Workers
module Email = FSharp.CloudEdge.Runtime.AgentsAiChatAgent.Email
type Env =
abstract TEAM_ADDRESS: string
let isAutoReply (message: Workers.ForwardableEmailMessage) =
[| "auto-submitted"; "x-auto-response-suppress"; "precedence" |]
|> Array.choose (fun key ->
message.headers.get key
|> Option.map (fun value -> Email.EmailHeader.Create(key = key, value = value)))
|> Email.Exports.isAutoReplyEmail
[<ExportDefault>]
let worker: Workers.ExportedHandler<Env, obj, obj, obj> =
Workers.ExportedHandler.Create(
email = fun message env _ ->
if isAutoReply message then None
else
message.forward env.TEAM_ADDRESS
|> Async.AwaitPromise
|> Async.Ignore
|> Async.StartAsPromise
|> Some
)
Needs an Email Routing rule whose action sends mail to this Worker, and a TEAM_ADDRESS variable set to a verified destination address. Cloudflare's Email Workers guide covers the rule.
Emitted JavaScript
import { isAutoReplyEmail } from "agents/email";
import { choose } from "./fable_modules/fable-library-js.5.13.0/Array.js";
import { awaitPromise, ignore, startAsPromise } from "./fable_modules/fable-library-js.5.13.0/Async.js";
export function isAutoReply(message) {
return isAutoReplyEmail(choose((key) => {
let value;
const option_1 = message.headers.get(key);
if (option_1 != null) {
return (value = option_1, {
key: key,
value: value,
});
}
else {
return undefined;
}
}, ["auto-submitted", "x-auto-response-suppress", "precedence"]));
}
export const worker = {
email: (message, env, _arg) => (isAutoReply(message) ? undefined : startAsPromise(ignore(awaitPromise(message.forward(env.TEAM_ADDRESS))))),
};
export default worker;
Connecting to an agent
Decide which application identity and conversation own the inbound message before invoking an agent. Forwarding alone needs no model. If an agent drafts a reply or takes an action, preserve the relationship between the incoming message, the task record, and the outgoing result.
Related Pages
Testing and feedback
Useful test cases include header and message shapes, optional async handlers, forwarding results, and delivery through Email Routing.
Verify bindings explains how to run checks and report an issue. Include a small reproduction and the package versions used; working examples are welcome too.