Self-owned temporary email + Telegram bot
Fully on Cloudflare Workers + D1 + Email Routing — no VPS.
Create disposable addresses on your domain (otp@your-domain), receive OTP / verification links, and read them in Telegram. Multi-domain (swap domains without rewriting the bot). Private whitelist first; multi-user optional.
| ✉️ Disposable addresses | /new — random local-part on an active domain (or /new domain.com) |
| 🔔 Push on inbound | Telegram notify + best-effort OTP / link extraction |
| 📥 Inbox tools | /inbox, /read, /list, /del |
| 🌐 Multi-domain | /adddomain / /offdomain (admin) — burn a domain without bot rewrites |
| 🔌 HTTP API | Create address + read inbox (per-address bearer token) |
| ☁️ Pure Cloudflare | Workers + D1 + Email Routing — no mail VPS |
Site/OTP ──MX──► Cloudflare Email Routing (catch-all)
│
▼
Worker tempmail-tg ──► D1
▲
Telegram webhook ──┘
| Command | Action |
|---|---|
/start |
Auth + help |
/new [domain] |
Create temp address |
/list |
Your active addresses |
/inbox [address|id] |
Last 10 mails |
/read <mail_id> |
Full body + OTP/links |
/del <address|id> |
Soft-delete address |
/domains |
Active domains |
/adddomain /offdomain /adduser |
Admin |
- 20 active addresses per user
- 100 mails per address (FIFO)
- 10
/newper hour per user - Body truncated at 50KB
git clone https://github.com/yxxrn/tempmail-tg.git
cd tempmail-tg
npm installnpx wrangler login
npx wrangler d1 create tempmailPaste the database_id into wrangler.toml → [[d1_databases]].database_id.
cp .dev.vars.example .dev.vars
# fill BOT_TOKEN, WEBHOOK_SECRET, API_KEY, ALLOWED_CHAT_IDS
npx wrangler secret put BOT_TOKEN
npx wrangler secret put WEBHOOK_SECRET
npx wrangler secret put API_KEYSet ALLOWED_CHAT_IDS (your Telegram chat id) in wrangler.toml [vars] or the Worker dashboard.
npm run db:local # dev
npm run db:remote # production
# optional seed:
# edit scripts/seed.sql then:
# npx wrangler d1 execute tempmail --remote --file=scripts/seed.sql- Domain on Cloudflare (zone Active)
- Email → Email Routing → Enable (MX auto-added)
- Catch-all → Send to a Worker →
tempmail-tg→ Enable
npx wrangler deploycurl "https://api.telegram.org/bot$BOT_TOKEN/setWebhook" \
-d "url=https://tempmail-tg.<subdomain>.workers.dev/api/telegram" \
-d "secret_token=$WEBHOOK_SECRET"Telegram bot → /start → /adddomain your.domain → /new
- New domain on CF + Email Routing catch-all → same Worker
- Bot:
/adddomain other.com /newpicks a random active domain- Disable:
/offdomain old.com
You do not need a second domain unless you want a backup or the first is blocked.
| Method | Path | Auth |
|---|---|---|
GET |
/health |
— |
POST |
/api/new |
X-API-Key |
GET |
/api/inbox?address= |
Authorization: Bearer <address.token> |
GET |
/api/mail/:id |
Same bearer |
POST |
/api/telegram |
X-Telegram-Bot-Api-Secret-Token |
POST /api/new optional body:
{ "domain": "example.com", "owner_chat_id": "123456789" }npm test
npm run typecheck
npm run devsrc/
index.ts # fetch + email entrypoints
bot.ts # Telegram commands
email_handler.ts # inbound mail → D1 → push
api.ts # HTTP routes
db.ts # D1 helpers
auth.ts / limits.ts / otp.ts / ids.ts
assets/
banner.svg # README hero
architecture.svg # diagram
logo.svg
migrations/
0001_init.sql
docs/
USER_GUIDE.md / DEPLOY.md / API.md
| File | Content |
|---|---|
| docs/USER_GUIDE.md | Bot usage + multi-domain |
| docs/DEPLOY.md | Production deploy checklist |
| docs/API.md | HTTP API reference |
| docs/superpowers/specs/2026-07-19-tempmail-tg-design.md | Design spec |
| docs/superpowers/plans/2026-07-19-tempmail-tg.md | Implementation plan |
- Do not commit
.dev.vars, secrets, or production chat ids - Secrets only via
wrangler secret - Private bot: whitelist
ALLOWED_CHAT_IDS+userstable - Rotate BotFather / CF API tokens if they ever leak