Email relay with web form and API. Toggle between personal/work addresses, built with Cloudflare Workers + MailChannels
MailRelay is an email relay service built on Cloudflare Workers using MailChannels. It provides both a web interface and REST API for sending emails to pre-configured personal and work addresses.
- Pincode Authentication: Optional URL parameter (
?pincode=xxx) for bookmarking. If not provided, displays pincode input field - Address Toggle: Switch between personal and work email addresses
- Subject Field: Text input for email subject line (required)
- Message Field: Textarea for email body/description
- Submit Button: Send email via form submission
- Success/Error Feedback: Visual confirmation of email delivery status
- POST Endpoint:
/api/sendfor programmatic email sending - Authentication: Pincode in request body for simple authentication
- JSON Payload: Accepts structured email data
- Response Codes: Standard HTTP status codes with error messages
- Runtime: Cloudflare Workers
- Email Provider: MailChannels API
- Language: JavaScript/TypeScript
- Deployment: Wrangler CLI
- Framework: Vanilla HTML/CSS/JS (or specify if you want React, etc.)
- Styling: TailwindCSS / plain CSS
- Hosting: Served from same Cloudflare Worker
PERSONAL_EMAIL=your-personal@example.com
WORK_EMAIL=your-work@example.com
MAILCHANNELS_API_KEY=xxx
PINCODE=your-secret-pincode
FROM_EMAIL=noreply@yourdomain.com
FROM_NAME=MailRelay
Headers:
Content-Type: application/json
Request Body:
{
"pincode": "string",
"destination": "personal" | "work",
"subject": "string",
"message": "string"
}Response (Success - 200):
{
"success": true,
"message": "Email sent successfully",
"data": {
"destination": "personal"
}
}Response (Error - 400/401/500):
{
"success": false,
"message": "Error message description",
"data": null
}Consistent Structure Benefits:
- Client only needs to check
successboolean messagealways contains human-readable feedbackdatacontains payload (object on success, null on error)- Same parsing logic for all responses
┌─────────────────────────────────────┐
│ MailRelay 📧 │
├─────────────────────────────────────┤
│ │
│ Pincode: [________________] │
│ (hidden if in URL) │
│ │
│ Send To: ( ) Personal ( ) Work │
│ │
│ Subject: [________________] │
│ │
│ Message: ┌──────────────────┐ │
│ │ │ │
│ │ │ │
│ │ │ │
│ └──────────────────┘ │
│ │
│ [ Send Email ] │
│ │
└─────────────────────────────────────┘
Pincode URL Parameter: Users can bookmark /?pincode=xxx to skip entering pincode each time.
Error feedback is crucial. log all information and print all information except for sensitive information like keys to make debugging easier. In the API return in the response an error message with as much information as possible.
- Simple Pincode Authentication: Pincode compared against
PINCODEenvironment variable- Can be passed as URL parameter
?pincode=xxxfor web form bookmarking - Required in API request body
- Not highly secure, but sufficient for personal use MVP
- Can be passed as URL parameter
- Input Validation: Validate and sanitize all user inputs
- CORS Configuration: Configure appropriate CORS headers for API access
- Environment Variables: Store all sensitive data (emails, pincode, API keys) in environment variables, never in code
- No Rate Limiting: Intentionally omitted for MVP simplicity (add later if needed)
- Manual: Create issue with “@claude setup deployment pipeline”
- Automatic: On push to
mainbranch, deploy to Cloudflare
- Checkout code
- Install dependencies
- Run tests (if any)
- Deploy with Wrangler
- wrangler deploy
- Use secrets from GitHub- llm integration to enhance the subject and description in case of typos.
Questions to finalize:
- Do you want TypeScript or JavaScript? depends, typescript requires compilation, but is type safe. depends on github actions.
- Any specific styling preferences (minimal, modern, colorful)? minimal but modern.
- Should the form have validation (required fields, max length)? Subject is required.
- Do you want email confirmation/receipts? no