Email Signal Routing
Route trade signals into email-worker via Mailgun, Cloudflare® Email Routing, or an authenticated JSON post. There is no IMAP inbox poll.
This page
The email-worker turns an inbound email or a JSON body into a trade signal and forwards it to trade-worker. It does not log into a mailbox. Cloudflare® Workers cannot open IMAP sockets, and EMAIL_HOST, EMAIL_USER, and EMAIL_PASS are reserved names that this worker does not read.
Three ingress paths:
| Path | Route | Auth |
|---|---|---|
| Mailgun | POST /webhook | HMAC-SHA256. Headers Mailgun-Signature, Mailgun-Timestamp, Mailgun-Token. Secret MAILGUN_API_KEY. |
| Cloudflare® Email Routing | the worker email handler | Cloudflare® delivers the message to the binding. |
| Internal JSON | POST /email-signal | X-Internal-Auth-Key only. This route does not check a Mailgun signature. |
hoox secrets set email-worker MAILGUN_API_KEY
hoox secrets set email-worker INTERNAL_KEY_BINDING
Worker name is required. The CLI prompts for each value. INTERNAL_KEY_BINDING is normally generated by hoox setup — only set it here if you are wiring email-worker by hand.
Point the Mailgun route at https://<email-worker-host>/webhook. For Email Routing, bind the destination address to this worker in the Cloudflare® dashboard.
Warning
Use a dedicated Mailgun route or routing address for signals. The scheduled handler only drops the in-memory pattern cache. It does not scan an inbox.
🔎 2. Configuring Regex Parsing Rules in KV
Plain-text bodies are matched against patterns in CONFIG_KV. JSON bodies that already contain exchange, action, and symbol skip the regex.
# Coin symbols pulled out of a plain-text body
hoox config kv set email:coin_pattern "(BTC|ETH|SOL|LINK|AVAX)"
# Buy / sell words in that body
hoox config kv set email:action_pattern "(LONG|SHORT|CLOSE|BUY|SELL)"
The Parsing Mechanism
When a Mailgun webhook or Email Routing message arrives:
- The worker reads the plain body (
body-plain/stripped-textfor Mailgun). - If the body is JSON with
exchange,action, andsymbol, that object is the signal. - Otherwise the regex keys above extract the coin and the action.
LONG/BUYbecomeLONG;SHORT/SELLbecomeSHORT. - The worker forwards the signal to
trade-workerover theTRADE_SERVICEbinding.
JSON body with testnet mode
If the email body is structured JSON (instead of free-text), optional fields are forwarded to trade-worker:
{
"exchange": "bybit",
"action": "LONG",
"symbol": "BTCUSDT",
"quantity": 0.001,
"test": true
}
"test": true requests exchange testnet execution (Binance/Bybit). Plaintext extraction never sets test — always live. See Test Trading.
🛡️ 3. What actually authenticates the message
Mailgun calls are rejected unless MAILGUN_API_KEY is set and the HMAC of timestamp + token matches Mailgun-Signature, inside a ±15 minute window. POST /email-signal ignores that signature and requires the mesh internal key. There is no SPF or DKIM check inside the worker, and there is no sender allowlist key.
🧪 4. Testing the JSON path
POST /email-signal is the path you can call without a Mailgun account. Replace the host and key with your local hoox dev port (unpinned workers start at 8800) and mesh key:
curl -sS -X POST http://localhost:8800/email-signal \
-H "content-type: application/json" \
-H "X-Internal-Auth-Key: $INTERNAL_KEY_BINDING" \
-d '{"exchange":"bybit","action":"LONG","symbol":"BTCUSDT","quantity":0.001,"test":true}'
"test": true requests exchange testnet execution where the exchange allows it. Plain-text extraction never sets test. See Test Trading.
Tail the isolate while you send:
hoox monitor logs email-worker
🔗 Next Steps
- Alert Troubleshooting — Common TradingView® webhook errors and resolutions.
- Platform Configuration Guide — Environment variables and KV keys.
- API Endpoint Reference — Review full REST payloads and HTTP error returns.