email-worker ingests trading signals from email sources, parses them, and forwards them to trade-worker for execution. It receives emails via Mailgun webhook (POST /webhook) or direct JSON POST (POST /email-signal). No IMAP/SMTP polling — Cloudflare Workers edge runtime does not support the Node.js net/tls modules required for IMAP.
The worker also tracks signal ingestion metrics by forwarding event data to analytics-worker via service binding.
⚡ 1. Endpoints
Note: For the canonical endpoint directory with full request/response examples across all workers, see /docs/devops/api/endpoints.
The Mailgun webhook endpoint is
/webhook, not /webhook/mailgun. The direct
JSON endpoint is /email-signal, not /process.🔐 2. Mailgun Signature Verification
When a POST arrives at/webhook, the worker validates the Mailgun signature before processing the email body:
- Reads
Mailgun-Signature,Mailgun-Timestamp,Mailgun-Tokenfrom request headers - Computes HMAC-SHA256 hex digest of
timestamp + tokenusingMAILGUN_API_KEYas the signing key - Compares computed digest against the
Mailgun-Signatureheader value - Returns
401 Unauthorizedif headers are missing or signature does not match
body-plain or stripped-text field of the Mailgun form-data payload and passes it to the signal parser.
📨 3. Signal Extraction
Two-phase parsing: JSON first, plaintext fallback.Phase 1: JSON Parsing
parseEmailSignal() calls JSON.parse() on the body text. If the result contains exchange, action, and symbol fields, it returns a structured signal immediately:
Phase 2: Plaintext Fallback
If JSON parsing fails or required fields are missing,extractFromPlaintext() uses keyword matching:
extractField()scans forkeyword:prefixes (e.g.exchange:,symbol:,action:)- Coin symbols and action keywords matched via regex from KV config (
coinPattern,actionPattern) normalizeExchange()resolves exchanges:binance,mexc,bybitnormalizeAction()maps:buy/long→buy,sell/short→sell
Zod Validation
Incoming JSON payloads are validated using Zod schemas:EmailSignalSchemavalidates the signal structure (exchange, action as enum, symbol, quantity with default 100, optional price/leverage)WebhookPayloadSchemavalidates the wrapper payload (subject, text, body — all optional)- Invalid payloads return
400 Bad Requestwith structured error - Extra fields are stripped via
.strip()
Forwarding
Once parsed, the signal is sent totrade-worker via:
ctx.waitUntil():
Cloudflare Email Routing
The worker also exposes anemail() handler that processes incoming emails via Cloudflare Email Routing. When an email arrives, postal-mime parses the raw MIME content, extracts the text body, and feeds it through the same parseEmailSignal() pipeline. Validated signals are forwarded to trade-worker with analytics tracking.
🔗 4. Bindings
Service Bindings
Send Email Binding
KV Namespaces
🔑 5. Secrets
All secrets are set viawrangler secret put <name>:
⚙️ 6. Environment Variables (Vars)
🗄️ 7. KV Configuration Keys
The worker loads signal parsing patterns fromCONFIG_KV via loadSignalPatterns():
📊 8. Observability
Full observability enabled with 100% head sampling:- Head sampling rate: 1 (all requests sampled)
- Log persistence: Enabled — logs stored for debugging and audit
- Invocation logs: Enabled — full invocation records available
- Smart Placement: Enabled for 30-60% latency reduction
🛠️ 9. Configuration (wrangler.jsonc)
INTERNAL_KEY_BINDING, MAILGUN_API_KEY, EMAIL_HOST_BINDING, EMAIL_USER_BINDING, EMAIL_PASS_BINDING) are set via wrangler secret put <name> and are not present in the checked-in wrangler.jsonc.
🧪 10. Development
wrangler.jsonc is tracked in git.
🏗️ 11. Architecture Context
The email-worker is one of 10 workers in the Hoox service binding mesh:- Mailgun flow: Inbound email → Mailgun webhook POST → email-worker
/webhook→ trade-worker - Direct flow: Internal tooling →
POST /email-signal(authenticated) → email-worker → trade-worker - Email Routing flow: Cloudflare Email Routing →
email()handler → email-worker → trade-worker - Analytics: Every parsed signal sends
{ source, type, symbol, confidence }to analytics-worker
Next Steps
- trade-worker Profile — How parsed signals become execution orders
- analytics-worker Profile — Signal tracking and observability
- Architecture Overview — Full system architecture and data flow