Files
ni-mail/README.md
2026-04-25 15:46:03 +08:00

220 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ni-mail
一個極簡的 Cloudflare Worker用於接收私人域名郵件並提供 HTTP API 讀取。
無需前端、無需 JWT部署後即可通過 API 取得最新郵件內容。
## 特性
- 📨 通過 Cloudflare Email Routing 接收郵件
- 🗄️ 使用 Durable Objects + SQLite 儲存郵件 metadata使用 R2 儲存附件內容
- 🔑 API Key 鑑權
- 🌐 支持多個自定義域名(域名需托管在 Cloudflare
- 📦 保留原版極簡 API`/latest``/mails``/mail/:id`
- 🧵 支持 threaded inbox、thread detail、附件下載
- ✉️ 可選支持 `send / reply / forward`(配置 `EMAIL` binding 後啟用)
- 🚫 未配置 `EMAIL` binding 時,收信與讀信 API 仍可正常工作
## 工作原理
```
外部郵件 → 你的域名 MXCloudflare Email Routing
↓ catch-all 轉發
Cloudflare Worker收信 + HTTP API
Mailbox Durable Object每個 mailbox 一個)
SQLite郵件 metadata / thread + R2附件
curl /latest → 自動化腳本
```
郵件到達後由 `postal-mime` 解析為結構化 JSON通過帶鑑權的 HTTP API 按需讀取。
## 前置條件
- 域名已托管在 Cloudflare
- 已啟用 Cloudflare Email Routing
- Node.js 20 或更高版本
> ⚠️ 收信地址必須是托管在 Cloudflare 的真實域名(如 `user@yourdomain.com`
> `*.workers.dev` 不支持 Email Routing發往 workers.dev 地址的信不會被收到。
## 部署
### 方式一Cloudflare 一鍵部署
上傳到你自己的 GitHub 倉庫後,將下方按鈕中的 `<YOUR_USERNAME>/<YOUR_REPO>` 換成實際倉庫地址即可:
```markdown
[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/<YOUR_USERNAME>/<YOUR_REPO>)
```
Cloudflare Builds 建議配置:
- Root directory留空或 `/`
- Build command留空
- Deploy command`npm run deploy`
部署完成後,還需在控制台完成以下配置:
**1. 設定 AUTH_KEY**
Settings → Variables and Secrets → 新增:
- 類型:**Secret密鑰**,不要選 Text明文可見
- 變數名稱:`AUTH_KEY`
- 值:自訂一個密碼
儲存後點 **Deploy** 讓設定生效。
**2. 設定可收信域名**
`wrangler.jsonc` 中設定你的域名:
```jsonc
{
"vars": {
"DOMAINS": "example.com,example.net"
}
}
```
公開模板預設留空,方便任何 Cloudflare 帳號先完成第一次部署。
**3. 設定 Email Routing**
Cloudflare 控制台 → 你的域名 → Email → Email Routing → Routing rules → Catch-all
- ActionSend to Worker
- 選擇 `ni-mail`
**4. (可選)啟用發信功能**
若你需要使用發信 / 回覆 / 轉發接口,請為 Worker 新增一個名為 `EMAIL``send_email` binding。
未配置 `EMAIL` binding 時,收信和讀信 API 仍可正常工作,只是發信接口會回 `501`
---
### 方式二:本地 CLI 部署
```bash
git clone https://github.com/<YOUR_USERNAME>/<YOUR_REPO>.git
cd ni-mail
npm ci
npm run check:deploy
npm exec -- wrangler secret put AUTH_KEY
npm run deploy
```
如果你是本地部署,通常只需要:
1. 修改 `wrangler.jsonc` 中的:
- `name`
- `vars.DOMAINS`
- `r2_buckets[*].bucket_name`
2. 在 Cloudflare 後台設置 `AUTH_KEY`
3. 配置 Email Routing 的 Send to Worker 規則
## 自定義域名(可選)
> 域名必須已托管在 Cloudflare無需手動建立 DNS 記錄Cloudflare 會自動處理並簽發 SSL。
首次部署成功後,可以在 Cloudflare 控制台為 Worker 添加 Custom Domain。
如需用 Wrangler 管理,在 `wrangler.jsonc` 中添加你自己的域名:
```jsonc
{
"routes": [
{
"pattern": "mail.example.com",
"custom_domain": true
}
]
}
```
不要把不屬於部署者 Cloudflare 帳號的域名提交到公開模板中。
## API
所有請求需帶上 Header`X-Auth-Key: 你的密碼`
### 與原版兼容的路由
| 方法 | 路徑 | 說明 |
|---|---|---|
| GET | `/latest?mailbox=user@example.com` | 取得最新一封完整郵件 |
| GET | `/mails?mailbox=user@example.com&limit=10` | 取得最近 N 封郵件列表(不含正文) |
| GET | `/mail/:id?mailbox=user@example.com` | 取得單封完整郵件(含 html/text |
| DELETE | `/mails?mailbox=user@example.com&folder=inbox` | 清空收件匣 |
### 新增路由
| 方法 | 路徑 | 說明 |
|---|---|---|
| GET | `/api/mailboxes/:mailboxId/latest` | 讀取指定 mailbox 最新郵件 |
| GET | `/api/mailboxes/:mailboxId/emails` | 列表 / 搜索 / 排序 |
| GET | `/api/mailboxes/:mailboxId/emails/:id` | 讀取單封郵件 |
| POST | `/api/mailboxes/:mailboxId/emails/:id/read` | 標記已讀 |
| GET | `/api/mailboxes/:mailboxId/threads/:threadId` | 讀取整個 thread |
| GET | `/api/attachments/:attachmentId?mailbox=user@example.com` | 下載附件 |
| POST | `/api/mailboxes/:mailboxId/send` | 發新郵件(需 `EMAIL` binding |
| POST | `/api/mailboxes/:mailboxId/reply` | 回覆郵件(需 `EMAIL` binding |
| POST | `/api/mailboxes/:mailboxId/forward` | 轉發郵件(需 `EMAIL` binding |
**範例**
```bash
curl "https://your-worker.workers.dev/latest?mailbox=user@example.com" \
-H "X-Auth-Key: 你的密碼"
```
**無郵件時HTTP 404**
```json
{ "error": "no mail" }
```
**鑑權失敗HTTP 401**
```json
{ "error": "unauthorized" }
```
**未配置發信 binding 而調用發信接口時HTTP 501**
```json
{ "error": "outbound email is not configured; add an EMAIL send_email binding after deployment" }
```
## 常見問題
### error code: 1101
Worker 運行時拋出未捕獲異常,常見原因包括:
- `AUTH_KEY` 沒有設置
- Email Routing 沒有正確指到這個 Worker
- `DOMAINS` 沒有包含當前 mailbox 的域名
- R2 / Durable Object 綁定不完整
先確認:
- Worker 已成功部署
- `wrangler.jsonc` 中的 `MAILBOX``BUCKET` binding 存在
- 控制台裡 `AUTH_KEY` 已設為 Secret
### AUTH_KEY 建議使用 Secret 而非 Text
Settings → Variables and Secrets 新增 `AUTH_KEY` 時,類型請選 **Secret密鑰**,不要選 Text文本
- **Secret**:值加密儲存,部署後不可見,適合密碼類資訊
- **Text**:明文儲存,任何有控制台權限的人都能看到
## License
Apache License 2.0