emailSender

HTTP endpoint called by the agentcr Cloudflare Worker (EmailRoutingAgent) to send outbound reply emails via Val Town's built-in email service.

Cloudflare Workers cannot send arbitrary outbound email without a verified sender domain. This val bridges that gap using Val Town's std/email.

Authorization

The caller (Cloudflare Worker) authenticates by passing the shared secret in the JSON request body:

{ "secret": "<EMAIL_SECRET env var>", "to": "recipient@example.com", "subject": "Re: Your enquiry", "text": "Thank you for your message..." }

This val checks body.secret === process.env.EMAIL_SECRET. If they don't match → 401 Unauthorized.

Secret setup (must be identical on both sides)

Val Town (this val's environment variables):

EMAIL_SECRET=<your-chosen-secret>

Cloudflare — the worker reads EMAIL_INBOUND_SECRET and sends it as body.secret. The two vars must hold the same value:

npx wrangler secret put EMAIL_INBOUND_SECRET # paste the same value as EMAIL_SECRET above

Local dev (.dev.vars in project root):

EMAIL_INBOUND_SECRET=<same-value>
VALTOWN_SEND_URL=https://cookiemonster0922--<id>.web.val.run

Request format

POST <val-url>
Content-Type: application/json

{
  "secret":  string,   // shared secret (required)
  "to":      string,   // recipient address (required)
  "subject": string,   // email subject (required)
  "text":    string    // plain-text body (required)
}

Response

StatusMeaning
200 { ok: true }Email sent successfully
400 { ok: false, error: "..." }Missing fields or invalid JSON
401 Unauthorizedsecret does not match EMAIL_SECRET env var
405 Method Not AllowedNon-POST request (OPTIONS allowed for CORS)
500 { ok: false, error: "..." }Val Town email API error

Troubleshooting

SymptomCause
Worker logs send_reply_error: 401EMAIL_INBOUND_SECRET (Cloudflare) ≠ EMAIL_SECRET (this val), or one/both is unset
Worker logs send_reply_error: 404VALTOWN_SEND_URL points to the wrong val URL

Environment variables

VariableRequiredDescription
EMAIL_SECRETYesShared secret — must match EMAIL_INBOUND_SECRET in Cloudflare