feat(cloudflare/workers): add Email event source for inbound mail#401
Open
sam-goodwin wants to merge 1 commit into
Open
feat(cloudflare/workers): add Email event source for inbound mail#401sam-goodwin wants to merge 1 commit into
sam-goodwin wants to merge 1 commit into
Conversation
Contributor
|
Install the packages built from this commit: alchemy bun add alchemy@https://pkg.ing/alchemy/c3ac23a@alchemy.run/better-auth bun add @alchemy.run/better-auth@https://pkg.ing/@alchemy.run/better-auth/c3ac23a@alchemy.run/pr-package bun add @alchemy.run/pr-package@https://pkg.ing/@alchemy.run/pr-package/c3ac23a |
This was referenced May 22, 2026
Contributor
Author
|
@Mkassabov i don't have an account with email testing capability. Can you set up our test account and drive this home? |
972af75 to
7bd1edb
Compare
Port of the original Binding.Policy implementation to the post-#690 event-source convention (Layer resolves the Worker host directly; sibling Email.Routing + Email.Rule are yielded under Namespace.push guarded by __ALCHEMY_RUNTIME__, mirroring Queues.EventSourceLive). - Cloudflare.email({ zone, matchers }).subscribe(handler) wires the runtime email listener and auto-creates Email.Routing (retained on destroy) + Email.Rule targeting the host Worker - Effect-native ForwardableEmailMessage wrapper (forward/reply/ setReject as Effects, raw escape hatch) - e2e test + fixture gated on CLOUDFLARE_TEST_ZONE / CLOUDFLARE_TEST_EMAIL_INBOX / CLOUDFLARE_TEST_EMAIL_FROM - doc relocated to cloudflare/email/email-worker.mdx (tutorial/ dir no longer exists) - example updated to the Email.Send / Email.SendBinding API Co-authored-by: Michael (Pear) <michael@alchemy.run>
fe991d9 to
c3ac23a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
Cloudflare.email({ zone }).subscribe(handler)— one call wires both halves of an Email Worker consumer:emailevent listener on the Worker.EmailEventSourcePolicyyields a siblingEmailRoutingtoggle on the zone and anEmailRulewhoseactions: [{ type: "worker", … }]targets this Worker — mirroring theQueueEventSourcepolicy pattern.alchemy.run.tsno longer needs hand-rolledEmailRouting+EmailRulecalls.Filtering and dispatching in the handler
matchersscopes which envelopes Cloudflare delivers to this Worker (the auto-createdEmailRule); inside the handler you branch on the message and use the Effect-wrapped actions. A real-world inbox might look like this:The catch-all (
{ type: "all" }) is the default if you omitmatchers. To run with noEmailRuleat all (manage routing yourself), callemail()with nozone— the policy becomes a no-op.Message wrapper
Matches the R2 / KV binding convention —
message.rawis the underlyingcf.ForwardableEmailMessage(escape hatch); ergonomic fields and Effect-wrapped actions sit on top:The cf names
raw/rawSize(the message body and its size) are exposed asbody/bodySizeto avoid clashing with therawescape hatch.Notes
emailis already inExportedHandlerMethodsonWorker.ts, so the runtime dispatch table wires this up automatically.EmailEventSourcePolicyregistered inCloudflare.providers()alongsideQueueEventSourcePolicy/CronEventSourcePolicy.emailevent out to every registered listener, so per-rule dispatch is handled inside the single handler viamessage.to/ headers — exactly like the example above).website/src/content/docs/tutorial/cloudflare/email-worker.mdx.@binding/@section/@examplesobun generate:api-referenceemitsproviders/Cloudflare/EmailEventSource.md.