Source:
src/Cloudflare/Workers/EmailEventSource.ts
Subscribe to Cloudflare Email Worker events with an Effect handler.
Wires both halves of the consumer in one call:
- Runtime: registers an
emailevent listener on the Worker. The handler receives aForwardableEmailMessagewhose action methods (forward,reply,setReject) returnEffects. - Deploy-time (when
zoneis set): yields aCloudflare.Email.Routingtoggle on the zone plus the routing resource whoseactions: [{ type: "worker", … }]targets this Worker —Cloudflare.Email.CatchAllfor a catch-all subscription,Cloudflare.Email.Rulefor anything more specific. No manual wiring needed inalchemy.run.ts.
Requires EmailEventSourceLive provided on the Worker’s Effect.
Failure semantics: a failing handler is logged and the failure is
re-raised. Cloudflare turns that into a temporary SMTP failure, so the
sending server keeps the message and retries later — mail is never
accepted and then silently dropped. Handle the failures you consider
final inside the handler (Effect.retry, Effect.catchTag, or
message.setReject(...) to bounce permanently); anything you let
escape becomes a retryable delivery failure.
Subscribing to Inbound Mail
Section titled “Subscribing to Inbound Mail”Catch-all on a zone — auto-creates routing + catch-all
import * as Cloudflare from "alchemy/Cloudflare";import * as Effect from "effect/Effect";
export default Cloudflare.Worker( "Inbox", { main: import.meta.url }, Effect.gen(function* () { yield* Cloudflare.email({ zone: "example.com" }).subscribe( (message) => message.forward("ops@example.com"), ); return {}; }).pipe(Effect.provide(Cloudflare.EmailEventSourceLive)),);Match a specific address
yield* Cloudflare.email({ zone: "example.com", matchers: [{ type: "literal", field: "to", value: "hello@example.com" }],}).subscribe((message) => message.forward("ops@example.com"));Reject (bounce) a message
yield* Cloudflare.email({ zone: "example.com" }).subscribe((message) => message.setReject("Mailbox closed"),);Bring-your-own routing — no zone, no auto-create
// Manage `Email.Routing` / `Email.Rule` yourself in alchemy.run.ts.yield* Cloudflare.email().subscribe((message) => Effect.log(`from ${message.from}`),);