Submail System
Describes a self-hosted email alias system for Discord communities with SMTP engine, alias management, and audit logging.
What this file does
Describes a self-hosted email alias system for Discord communities with SMTP engine, alias management, and audit logging.
When to use it
- You want to offer Discord members disposable email aliases
- You need a self-hosted email forwarding service with Discord authentication
- You are building a community tool that requires email alias management
- You want to deploy a secure email gateway with spam filtering
Assumes this stack
<div align="center">Submail System</div>
<div align="center">
A Secure, Self-Hosted Email Alias System for Discord Communities.
Features β’ Prerequisites β’ Quick Start β’ Environment
</div>Features
- π Discord Gate: Restrict access to your guild members.
- π‘οΈ Advanced Security: CSP, HSTS, Rate Limiting, and PII Masking by default.
- π§ SMTP Engine: Built-in Node.js SMTP server with spam filtering.
- π Alias Management: Create, Pause, and Delete aliases instantly.
- π Audit Logs: Track every forwarded email and blocked attempt.
Prerequisites
Before you begin, ensure you have:
- Node.js: v20 or higher (v22 Recommended)
- Docker: For easy deployment (Optional)
- Discord Application: Create one at Discord Developers.
Quick Start
Get up and running locally in 3 steps.
1. Clone & Install
git clone https://github.com/minseo0388/submail.git
cd submail
npm install
2. Configure Environment
Copy the example file and fill in your Discord keys.
cp .env.example .env
(See Environment Setup for details)
3. Run
Start the development server (Web + Bot).
npx prisma db push
npm run dev
Open http://localhost:3000 to verify.
Environment Setup
The .env file is the heart of your security configuration.
π Identity & Database
| Variable | Description | Example |
|---|---|---|
DATABASE_URL | SQLite or PostgreSQL URL | file:./dev.db |
AUTH_SECRET | Secret for session encryption | openssl rand -base64 32 |
NEXTAUTH_URL | URL of your dashboard | http://localhost:3000 |
π€ Discord Configuration
| Variable | Description |
|---|---|
DISCORD_CLIENT_ID | OAuth2 Client ID |
DISCORD_CLIENT_SECRET | OAuth2 Client Secret |
DISCORD_GUILD_ID | (Optional) Restrict login to this Server ID |
β‘ Rate Limiting (Upstash)
| Variable | Description |
|---|---|
UPSTASH_REDIS_REST_URL | Redis URL for Rate Limiting |
UPSTASH_REDIS_REST_TOKEN | Redis Access Token |
π¨ Mail Server
| Variable | Description | Default |
|---|---|---|
SMTP_PORT | Port for incoming mail | 25 |
SMTP_DOMAIN | Domain for aliases | example.com |
π Deployment Guide
Vercel (Web Dashboard)
- Push your code to GitHub.
- Import the project in Vercel.
- Environment Variables: Add all variables from
.envto Vercel Settings. - Build Command:
npx prisma generate && next build- Note: The SMTP server (
apps/bot) cannot run on Vercel. You need a separate VPS or generic host (Render/Railway/EC2) for the Bot.
- Note: The SMTP server (
Database Migration
When deploying to production:
# Apply migrations to prod DB
npx prisma migrate deploy
π‘ Deliverability & DNS
To ensure your emails land in the Inbox (not Spam), you must configure these DNS records.
1. Reverse DNS (PTR)
Action: Go to your VPS Provider (AWS, DigitalOcean, etc.) settings.
- Value:
mail.yourdomain.com(Must match your SMTP hostname)
2. SPF (Sender Policy Framework)
Record Type: TXT
- Host:
@ - Value:
v=spf1 mx a:mail.yourdomain.com -all
3. DKIM (DomainKeys Identified Mail)
Record Type: TXT
- Host:
default._domainkey(or your selector) - Value:
v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY_HERENote: Generate this keypair using
opensslor an online tool. Put the private key on your server and path in.env.
4. DMARC
Record Type: TXT
- Host:
_dmarc - Value:
v=DMARC1; p=quarantine; rua=mailto:admin@yourdomain.com
Troubleshooting
<details> <summary><strong>SMTP Port Permission Denied?</strong></summary> Port 25 requires root privileges. On Linux, grant permission to Node:sudo setcap 'cap_net_bind_service=+ep' $(which node)
</details>
<details>
<summary><strong>Redis Connection Error?</strong></summary>
If you see "Redis Error (Fail-open)", check your Upstash credentials. The system will continue to work but without rate limiting.
</details>
<div align="center"> Made with β€οΈ by Choi Minseo </div>
What's inside
7 sections: features, prerequisites, quick start, environment setup, deployment guide, DNS deliverability, troubleshooting
Change this for your project
- Replace
minseo0388/submailwith your own repository name - Replace
example.comwith your actual domain for SMTP aliases - Replace
mail.yourdomain.comwith your SMTP hostname in DNS records
Where it goes
Save as AGENTS.md in your repository root. Read by Codex, Cursor and other agents that follow the AGENTS.md convention.
Worth borrowing
- Using Discord OAuth2 as the sole authentication gate for a self-hosted service
- Combining a web dashboard with a separate SMTP bot process for deployment flexibility
Related Documents
Browser-only development
Guides AI assistants on an Electron + React + TypeScript desktop app for browsing and organizing AI-generated images locally.
Claude Agents β Reference & Recommendations
Catalogues 40+ Claude agents and marketing skills for building a cat adoption charity landing page, with a ready-to-paste prompt and backend API reference.
Golden DKG Prototype -- Master Plan
Defines an 8-phase implementation plan for a Rust prototype of the Golden non-interactive DKG protocol using BLS12-381 and tokio.
Swarms Examples Index
Lists 60+ example scripts for building single and multi-agent systems with the Swarms framework, organized by category and use case.