336 lines
6.5 KiB
Markdown
336 lines
6.5 KiB
Markdown
# 多邮箱帐号收发系统
|
||
|
||
一个基于 Node.js + Express + SQLite 的多邮箱工作台,支持在网页中统一管理多个邮箱渠道与邮箱帐号,进行收信、查看邮件、发信,以及通过 API 调用邮件能力。
|
||
|
||
## 功能特性
|
||
|
||
- 支持配置多个邮箱渠道,如 QQ 邮箱、163 邮箱和自定义 IMAP/SMTP 渠道
|
||
- 支持导入邮箱帐号与授权码
|
||
- 三栏式 Web 界面:邮箱帐号、邮件列表、邮件详情
|
||
- 支持网页写邮件、发邮件、查看邮件详情
|
||
- 支持拉取多文件夹邮件,不限于 `INBOX`
|
||
- 支持按需补拉单封邮件正文,避免全量同步过慢
|
||
- 支持批量导入导出邮箱信息
|
||
- 提供 API 用于发邮件、获取邮件列表、获取最新一封邮件
|
||
|
||
## 技术栈
|
||
|
||
- Node.js
|
||
- Express
|
||
- SQLite `better-sqlite3`
|
||
- SMTP `nodemailer`
|
||
- IMAP `imapflow`
|
||
- 前端:原生 HTML / CSS / JavaScript
|
||
|
||
## 目录结构
|
||
|
||
```text
|
||
mail-sr/
|
||
├── public/
|
||
│ ├── index.html
|
||
│ ├── styles.css
|
||
│ └── app.js
|
||
├── db.js
|
||
├── mailService.js
|
||
├── server.js
|
||
├── Dockerfile
|
||
├── docker-compose.yml
|
||
└── README.md
|
||
```
|
||
|
||
## 本地启动
|
||
|
||
### 1. 安装依赖
|
||
|
||
```bash
|
||
npm install
|
||
```
|
||
|
||
### 2. 配置环境变量
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
默认环境变量:
|
||
|
||
```env
|
||
PORT=3000
|
||
DB_PATH=./mail.db
|
||
```
|
||
|
||
### 3. 启动服务
|
||
|
||
```bash
|
||
npm start
|
||
```
|
||
|
||
访问地址:`http://localhost:3000`
|
||
|
||
## Docker 部署
|
||
|
||
项目已经提供 `Dockerfile` 和 `docker-compose.yml`,可以直接用 Docker Compose 部署。
|
||
|
||
### 1. 准备环境变量
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
如果你不需要额外环境变量,默认配置即可。
|
||
|
||
### 2. 构建并启动
|
||
|
||
```bash
|
||
docker compose up -d --build
|
||
```
|
||
|
||
启动后访问:`http://localhost:3000`
|
||
|
||
### 3. 停止服务
|
||
|
||
```bash
|
||
docker compose down
|
||
```
|
||
|
||
### 4. 查看日志
|
||
|
||
```bash
|
||
docker compose logs -f
|
||
```
|
||
|
||
### 5. 数据持久化
|
||
|
||
Docker Compose 默认使用命名卷 `mail-sr-data` 持久化 SQLite 数据库,容器重建后数据不会丢失。
|
||
|
||
容器内数据库路径:
|
||
|
||
```text
|
||
/data/mail.db
|
||
```
|
||
|
||
## 内置邮箱渠道
|
||
|
||
系统默认会初始化以下渠道:
|
||
|
||
- QQ邮箱
|
||
- IMAP: `imap.qq.com:993`
|
||
- SMTP: `smtp.qq.com:465`
|
||
- 163邮箱
|
||
- IMAP: `imap.163.com:993`
|
||
- SMTP: `smtp.163.com:465`
|
||
|
||
说明:通常需要在邮箱后台开启 IMAP/SMTP,并使用授权码,而不是邮箱登录密码。
|
||
|
||
## Web 使用说明
|
||
|
||
### 1. 渠道管理
|
||
|
||
在设置弹窗中可以新增渠道,填写:
|
||
|
||
- 渠道名称
|
||
- 渠道标识 code
|
||
- IMAP 主机、端口、是否 SSL
|
||
- SMTP 主机、端口、是否 SSL
|
||
|
||
### 2. 单个邮箱帐号导入
|
||
|
||
在设置弹窗中填写:
|
||
|
||
- 渠道
|
||
- 邮箱帐号
|
||
- 授权码
|
||
- 发件人名称,可选
|
||
|
||
### 3. 批量导入导出
|
||
|
||
支持以下格式,每行一条:
|
||
|
||
```text
|
||
渠道名----帐号----授权码
|
||
```
|
||
|
||
例如:
|
||
|
||
```text
|
||
QQ邮箱----demo@qq.com----abcd1234
|
||
163邮箱----demo@163.com----efgh5678
|
||
```
|
||
|
||
说明:
|
||
|
||
- 导入时按“渠道名”匹配已有渠道
|
||
- 如果渠道不存在,会直接报错
|
||
- 如果同一渠道下邮箱已存在,则更新授权码
|
||
- 导出会导出全部帐号,格式同上
|
||
|
||
### 4. 收信
|
||
|
||
点击左侧邮箱帐号后会:
|
||
|
||
- 复制邮箱号到剪贴板
|
||
- 立即触发收信
|
||
- 拉取全部可读文件夹中的最近邮件
|
||
- 在中间栏展示邮件列表
|
||
- 在右侧显示邮件详情
|
||
|
||
为了避免 IMAP 全量拉取过慢,系统使用“两阶段策略”:
|
||
|
||
- 先同步邮件列表与头信息
|
||
- 打开某封邮件时再按需拉取正文详情
|
||
|
||
### 5. 发信
|
||
|
||
点击左上角“写邮件”按钮,选择当前邮箱帐号后即可发信。
|
||
|
||
## API 文档
|
||
|
||
### 健康检查
|
||
|
||
```bash
|
||
curl http://localhost:3000/api/health
|
||
```
|
||
|
||
### 查询渠道
|
||
|
||
```bash
|
||
curl http://localhost:3000/api/channels
|
||
```
|
||
|
||
### 新增渠道
|
||
|
||
```bash
|
||
curl -X POST http://localhost:3000/api/channels \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{
|
||
"name": "企业邮箱",
|
||
"code": "corp",
|
||
"imap_host": "imap.example.com",
|
||
"imap_port": 993,
|
||
"imap_secure": true,
|
||
"smtp_host": "smtp.example.com",
|
||
"smtp_port": 465,
|
||
"smtp_secure": true
|
||
}'
|
||
```
|
||
|
||
### 查询帐号列表
|
||
|
||
```bash
|
||
curl http://localhost:3000/api/accounts
|
||
```
|
||
|
||
### 新增邮箱帐号
|
||
|
||
```bash
|
||
curl -X POST http://localhost:3000/api/accounts \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{
|
||
"channel_id": 1,
|
||
"email": "your-account@qq.com",
|
||
"auth_code": "邮箱授权码",
|
||
"display_name": "业务邮箱"
|
||
}'
|
||
```
|
||
|
||
### 删除邮箱帐号
|
||
|
||
```bash
|
||
curl -X DELETE http://localhost:3000/api/accounts/1
|
||
```
|
||
|
||
### 批量导出帐号
|
||
|
||
```bash
|
||
curl http://localhost:3000/api/accounts/export
|
||
```
|
||
|
||
### 批量导入帐号
|
||
|
||
```bash
|
||
curl -X POST http://localhost:3000/api/accounts/import \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{
|
||
"content": "QQ邮箱----demo@qq.com----abcd1234\n163邮箱----demo@163.com----efgh5678"
|
||
}'
|
||
```
|
||
|
||
### 发送邮件
|
||
|
||
```bash
|
||
curl -X POST http://localhost:3000/api/send \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{
|
||
"accountId": 1,
|
||
"to": "target@example.com",
|
||
"subject": "测试邮件",
|
||
"text": "这是一封来自 API 的测试邮件"
|
||
}'
|
||
```
|
||
|
||
### 获取邮件列表
|
||
|
||
首次建议带 `refresh=true`,从远程 IMAP 同步最新邮件。
|
||
|
||
```bash
|
||
curl "http://localhost:3000/api/messages?accountId=1&limit=20&refresh=true"
|
||
```
|
||
|
||
### 获取最新一封邮件
|
||
|
||
```bash
|
||
curl "http://localhost:3000/api/messages/latest?accountId=1&refresh=true"
|
||
```
|
||
|
||
### 获取单封邮件详情
|
||
|
||
```bash
|
||
curl "http://localhost:3000/api/accounts/1/messages/INBOX%3A123?refresh=true"
|
||
```
|
||
|
||
说明:`uid` 需要使用 URL 编码。
|
||
|
||
## 数据说明
|
||
|
||
- `channels`:邮箱渠道配置
|
||
- `accounts`:邮箱帐号和授权码
|
||
- `mail_cache`:同步后的邮件缓存
|
||
|
||
默认本地数据库文件为:
|
||
|
||
```text
|
||
./mail.db
|
||
```
|
||
|
||
如果通过 Docker 运行,则默认为:
|
||
|
||
```text
|
||
/data/mail.db
|
||
```
|
||
|
||
## 部署建议
|
||
|
||
- 生产环境建议使用反向代理,如 Nginx 或 Traefik
|
||
- 建议通过 HTTPS 暴露服务
|
||
- 当前授权码存储在 SQLite 中,生产环境建议改为加密存储
|
||
- 建议增加访问控制与登录认证,避免未授权访问
|
||
|
||
## 当前实现边界
|
||
|
||
- 当前未实现附件上传与下载
|
||
- 当前未实现用户登录、权限和多租户隔离
|
||
- 当前邮件缓存为本地 SQLite,不适合超大规模并发
|
||
- 当前 HTML 邮件正文做了基础清理,但不是完整沙箱渲染
|
||
|
||
## 后续建议
|
||
|
||
如果准备继续往生产方向演进,建议优先补以下能力:
|
||
|
||
1. 用户登录与权限管理
|
||
2. 授权码加密存储
|
||
3. 附件收发
|
||
4. 邮件标签、已读未读、分页
|
||
5. 定时自动拉取邮件
|
||
6. 发信模板和批量发信
|
||
7. 更完整的 HTML 邮件安全隔离策略
|