English | 中文
临时邮箱 API 兼容层 —— 让任意前端客户端对接任意后端邮箱服务。
graph LR
subgraph 前端客户端
A[ShiroMail]
B[Mailpit]
C[Inbucket]
D[CF 客户端]
E[moemail]
F[CloudMail]
end
subgraph everyMail
G[翻译层]
end
subgraph 后端服务
H[cloudflare_temp_email]
I[CloudMail]
J[ShiroMail]
K[Inbucket]
L[Mailpit]
M[moemail]
end
A & B & C & D & E & F -->|原生 API| G
G -->|适配器转换| H & I & J & K & L & M
Loading
N×M 矩阵 — 6 种前端格式 × 6 种后端,任意组合
零改造接入 — 前端客户端无需修改,直接对接 everyMail
一键切换后端 — 修改 MAIL_BACKEND 即可迁移
Docker 一行启动 — 预构建多架构镜像(amd64/arm64)
可扩展 — 实现一个接口即可添加新前端或新后端
值
路由前缀
说明
shiromail
/shiromail
ShiroMail 原生 API
cloudflare
/cftempmail
cloudflare_temp_email 原生 API
inbucket
/inbucket
Inbucket REST API v1
mailpit
/mailpit
Mailpit REST API v1
moemail
/moemail
moemail REST API
cloudmail
/cloudmail
CloudMail REST API
任意前端 × 任意后端均可组合。例如:Mailpit UI → moemail 后端。
git clone https://github.com/WangChuDi/everyMail.git
cd everyMail
npm install
cp .env.example .env # 编辑 .env 填入你的后端配置
npm run dev # 开发模式(热重载)
生产模式:
npm run build && npm start
启动后访问 http://localhost:3100。
docker run -d \
--name everymail \
-p 3100:3100 \
--env-file .env \
ghcr.io/wangchudi/everymail:latest
docker-compose:
services :
everymail :
image : ghcr.io/wangchudi/everymail:latest
ports :
- " 3100:3100"
env_file : .env
restart : unless-stopped
本地构建:
docker build -t everymail .
docker run -d --name everymail -p 3100:3100 --env-file .env everymail
变量
必填
默认值
说明
HOST
否
0.0.0.0
监听地址
PORT
否
3100
监听端口
MAIL_BACKEND
是
—
后端类型(见兼容矩阵)
ENABLED_FRONTENDS
否
shiromail,cloudflare
启用的前端格式,逗号分隔或 all
JWT_SECRET
是
—
JWT 签名密钥
LOG_LEVEL
否
info
日志级别:debug / info / warn / error
CORS_ORIGIN
否
*
CORS 允许的来源
客户端连接 /shiromail 路由时使用的配置:
变量
必填
默认值
说明
SHIROMAIL_API_KEY
否
—
客户端认证 API Key,留空为公开模式
DOMAIN_MAP
否
{}
Domain ID → 域名映射(JSON),如 {"1":"example.com"}
DEFAULT_DOMAIN
否
—
默认域名,留空则从后端自动获取
cloudflare_temp_email
变量
必填
说明
CF_TEMP_EMAIL_BASE_URL
是
Worker 地址
CF_TEMP_EMAIL_AUTH
否
对应 CF 端 PASSWORDS
cloudmail
变量
必填
说明
CLOUDMAIL_BASE_URL
是
CloudMail 服务地址
CLOUDMAIL_AUTH
是
Authorization token(无 Bearer 前缀)
CLOUDMAIL_FRONTEND_AUTH
否
CloudMail 前端格式独立认证,默认同 CLOUDMAIL_AUTH
目标项目:maillab/cloud-mail ,API 文档:https://doc.skymail.ink/api/api-doc.html
shiromail
变量
必填
说明
SHIROMAIL_BACKEND_URL
是
ShiroMail 后端地址
SHIROMAIL_BACKEND_API_KEY
是
API Key
inbucket
变量
必填
说明
INBUCKET_BASE_URL
是
Inbucket 地址(默认 9000 端口)
mailpit
变量
必填
说明
MAILPIT_BASE_URL
是
Mailpit 地址(默认 8025 端口)
MAILPIT_AUTH
否
HTTP Basic Auth(user:pass)
moemail
变量
必填
说明
MOEMAIL_BASE_URL
是
moemail 服务地址
MOEMAIL_AUTH
是
X-API-Key
每种前端格式暴露对应项目的原生 API,所有请求路由到 MAIL_BACKEND 配置的后端。
ShiroMail(/shiromail)
路由
方法
说明
/shiromail/auth/register
POST
注册/创建邮箱
/shiromail/auth/login
POST
登录邮箱
/shiromail/mailboxes
GET
邮箱列表
/shiromail/mailboxes/:id/messages
GET
邮件列表
/shiromail/messages/:id
GET
邮件详情
/shiromail/public/settings
GET
公开设置
Cloudflare(/cftempmail)
路由
方法
说明
/cftempmail/open_api/settings
GET
公开设置
/cftempmail/api/new_address
POST
创建地址
/cftempmail/api/address_login
POST
地址登录
/cftempmail/api/mails
GET
邮件列表
/cftempmail/api/parsed_mails
GET
解析邮件列表
/cftempmail/api/mail/:id
GET
原始邮件
Inbucket(/inbucket)
路由
方法
说明
/inbucket/v1/mailbox/:name
GET
邮箱邮件列表
/inbucket/v1/mailbox/:name/:id
GET
邮件详情
/inbucket/v1/mailbox/:name/:id
DELETE
删除邮件
/inbucket/v1/mailbox/:name
DELETE
清空邮箱
Mailpit(/mailpit)
路由
方法
说明
/mailpit/v1/messages
GET
邮件列表
/mailpit/v1/message/:id
GET
邮件详情
/mailpit/v1/messages
DELETE
删除邮件
/mailpit/v1/search
GET
搜索邮件
moemail(/moemail)
路由
方法
说明
/moemail/api/emails/generate
POST
创建邮箱
/moemail/api/emails/:emailId
GET
邮件列表
/moemail/api/emails/:emailId/:messageId
GET
邮件详情
/moemail/api/emails/:emailId
DELETE
删除邮箱
CloudMail(/cloudmail)
路由
方法
说明
/cloudmail/account/add
POST
创建账号
/cloudmail/account/list
GET
账号列表
/cloudmail/email/list
GET
邮件列表
/cloudmail/email/delete
DELETE
删除邮件
各后端的 API 模型不同,everyMail 通过 BackendAdapter 接口统一抽象。以下是各后端的映射逻辑:
CloudMail 映射
CloudMail 是完整邮箱系统,映射关系非一一同构:
everyMail 语义
CloudMail 接口
说明
创建邮箱
POST /account/add
创建 account/address
登录邮箱
本地 JWT 包装
无 CF 风格 login
邮箱设置
GET /account/list 派生
兼容字段
删除邮箱
DELETE /account/delete
释放 account
邮件列表
GET /email/list
转换为兼容格式
邮件详情
GET /email/list 内查找
列表已含详情
删除邮件
DELETE /email/delete
软删除
清空收件箱
批量 DELETE /email/delete
逐条删除
ShiroMail 映射
反向代理模式,转发到真实 ShiroMail 后端:
everyMail 语义
ShiroMail 接口
说明
创建邮箱
POST /api/v1/mailboxes
返回 mailboxId
登录邮箱
GET /api/v1/mailboxes 查找
按地址查找
删除邮箱
POST /api/v1/mailboxes/:id/release
释放
邮件列表
GET /api/v1/mailboxes/:id/messages
—
邮件详情
GET /api/v1/mailboxes/:id/messages/:msgId
—
删除邮件
不支持
ShiroMail 无此接口
Inbucket 映射
无认证 SMTP 测试工具,邮箱隐式创建:
everyMail 语义
Inbucket 接口
说明
创建邮箱
本地合成
无创建接口
邮件列表
GET /api/v1/mailbox/{name}
—
邮件详情
GET /api/v1/mailbox/{name}/{id}
—
删除邮件
DELETE /api/v1/mailbox/{name}/{id}
—
清空邮箱
DELETE /api/v1/mailbox/{name}
—
Mailpit 映射
全局收件箱模式,通过搜索过滤地址:
everyMail 语义
Mailpit 接口
说明
创建邮箱
本地合成
无邮箱概念
邮件列表
GET /api/v1/search?query=to:{address}
按地址搜索
邮件详情
GET /api/v1/message/{id}
—
删除邮件
DELETE /api/v1/messages + body
—
清空收件箱
DELETE /api/v1/search?query=to:{address}
—
moemail 映射
Cloudflare Pages + D1,X-API-Key 认证:
everyMail 语义
moemail 接口
说明
创建邮箱
POST /api/emails/generate
返回 emailId
邮件列表
GET /api/emails/{emailId}
支持分页
邮件详情
GET /api/emails/{emailId}/{messageId}
—
删除邮件
DELETE /api/emails/{emailId}/{messageId}
—
删除邮箱
DELETE /api/emails/{emailId}
含所有邮件
graph TB
subgraph "FrontendFormat 前端接口"
F1[ShiroMailFormat]
F2[CloudflareFormat]
F3[InbucketFormat]
F4[MailpitFormat]
F5[MoemailFormat]
F6[CloudMailFormat]
end
subgraph "BackendAdapter 后端接口"
B1[CloudflareAdapter]
B2[CloudMailAdapter]
B3[ShiroMailAdapter]
B4[InbucketAdapter]
B5[MailpitAdapter]
B6[MoemailAdapter]
end
F1 & F2 & F3 & F4 & F5 & F6 --> Router{路由分发}
Router --> B1 & B2 & B3 & B4 & B5 & B6
Loading
添加新前端格式 :实现 FrontendFormat 接口,一个文件搞定
添加新后端 :实现 BackendAdapter 接口,一个文件搞定
项目结构
src/
├── index.ts # 入口 - 注册表循环挂载
├── config.ts # 配置管理
├── types/ # API 类型定义
├── adapters/ # 后端适配器(6 个)
│ ├── base.ts # BackendAdapter 接口
│ ├── cloudflare.ts
│ ├── cloudmail.ts
│ ├── shiromail.ts
│ ├── inbucket.ts
│ ├── mailpit.ts
│ └── moemail.ts
├── frontend/ # 前端格式(6 个)
│ ├── types.ts # FrontendFormat 接口
│ ├── index.ts # 格式注册表
│ ├── shiromail.ts
│ ├── cloudflare.ts
│ ├── inbucket.ts
│ ├── mailpit.ts
│ ├── moemail.ts
│ └── cloudmail.ts
├── middleware/ # 认证、日志、错误处理
└── utils/ # JWT、数据转换工具
认证流程
sequenceDiagram
participant Client as ShiroMail 前端
participant EM as everyMail
participant Backend as CF 后端
Client->>EM: POST /shiromail/auth/register<br/>{name, domain}
EM->>Backend: POST /api/new_address<br/>{name, domain}
Backend-->>EM: {jwt, address}
Note over EM: 签发 everyMail JWT(内嵌 CF JWT)
EM-->>Client: {token, user, mailbox}
Client->>EM: GET /shiromail/mailboxes/:id/messages<br/>Authorization: Bearer <everymail-jwt>
Note over EM: 解码 JWT → 提取 CF JWT
EM->>Backend: GET /api/parsed_mails<br/>Authorization: Bearer <cf-jwt>
Backend-->>EM: {results, count}
EM-->>Client: {data: messages[]}
Loading
本项目已在 LINUX DO 社区 发布,感谢社区的支持与反馈。
MIT