Outbox

aifans.fan
← 返回发信台

AIFans Outbox

使用手册 & 实现文档

涵盖日常使用方法、架构设计、文件说明、部署流程以及后续扩展指南。随时翻阅,无需查外部资料。

目录

  1. 日常使用
    1. 登录
    2. 撰写 & 发送邮件
    3. 管理发件人 & 域名
    4. 桌面/手机 App(PWA)
  2. 架构总览
  3. 文件说明
  4. 部署 & 更新
  5. 密钥管理
  6. PWA 实现细节
  7. 绑定自定义域名
  8. 未来扩展
01

日常使用

登录

访问 aifans-outbox.pages.dev(或已绑定的自定义域名),输入访问密码进入发信台。密码保存在浏览器 sessionStorage,关闭标签页即自动清除。

忘记密码? 密码(APP_PASSWORD)存储在 Cloudflare 后台 → Workers & Pages → aifans-outbox → Settings → Variables and Secrets,可在那里查看或修改。

撰写 & 发送邮件

  1. 选择发件人从「发件人」下拉框选一个已验证的地址;选「+ 自定义…」可临时输入任意 aifans.fan 地址。
  2. 填写收件人支持逗号、分号或空格分隔多个地址,下方会实时显示「N 个收件人 ✓」。
  3. 填写主题和正文右侧面板实时预览渲染效果。正文支持 HTML(默认)和纯文本两种模式,通过右上角切换。
  4. 点击「发送」成功后显示绿色回执 ID(来自 Resend),页面底部会追加到本次会话记录。
完整发送历史Resend 后台 → 可查看,包含时间、状态、详细日志。

管理发件人 & 新增域名

点击页面右上角「+ 管理发件域名」,弹出面板后:

添加新域名(第一步)

前往 Resend 域名管理,添加域名并按提示加 DNS 记录,等 Verified 后即可发信。

添加发件人地址(第二步)

切换到「发件人列表」标签,输入 名称 <you@example.com>,点添加——无需重新部署,立即生效(存 localStorage)。

桌面 / 手机 App(PWA)

Windows 11

Edge 或 Chrome 打开网址 → 地址栏右侧「安装此应用」图标 → 安装 → 开始菜单出现 Outbox 独立窗口图标。

iPhone / iPad

Safari 打开网址 → 底部分享按钮 → 「添加到主屏幕」→ 主屏出现图标,打开效果近似原生 App。

Windows 快捷键(可选):安装 AutoHotkey v2,新建 outbox.ahk,写入 ^!m::Run "https://aifans-outbox.pages.dev",双击运行后 Ctrl+Alt+M 随时打开。
02

架构总览

整个系统托管在 Cloudflare Pages 上,由两部分组成:

浏览器 / PWA 填写表单,POST /api/send,带密码头 │ ▼ Cloudflare Pages(aifans-outbox.pages.dev) ┌─────────────────────────────────────────────────────┐ │ 静态资源(Edge CDN 全球分发) │ │ index.html · sw.js · manifest.webmanifest · icons │ │ │ │ Pages Function(Edge Worker,无服务器) │ │ functions/api/send.js │ │ ├─ 校验 APP_PASSWORD │ │ └─ 调用 Resend API → 实际发信 │ └─────────────────────────────────────────────────────┘ │ ▼ Resend(resend.com) 通过已验证的 aifans.fan 域名发出邮件

设计要点

03

文件说明

aifans-outbox/ ├── index.html # 完整前端:登录 + 发信台 + 预览 + 域名管理面板 ├── docs.html # 本文档页面 ├── manifest.webmanifest # PWA 清单(图标/名称/显示模式) ├── sw.js # Service Worker(缓存外壳,/api/* 不缓存) ├── icon-192.png # PWA 图标 192×192 ├── icon-512.png # PWA 图标 512×512 ├── icon-maskable-512.png # Maskable 图标(Android 自适应图标用) ├── apple-touch-icon.png # iOS 主屏图标 180×180 ├── icon.svg # 图标源文件(深色底 + 琥珀圆环) ├── gen-icons.mjs # 一次性脚本:SVG → PNG(需 sharp) ├── README.md # 项目简介(部署说明) └── functions/ # Cloudflare Pages Functions(自动识别) └── api/ └── send.js # 后端:校验密码 + 调 Resend API

关键文件详解

文件职责改动频率
index.html全部前端逻辑(单文件 SPA),含登录、撰写、实时预览、发件人 localStorage 管理功能迭代时改
functions/api/send.js唯一后端入口,校验密码(`APP_PASSWORD`),组装邮件体,调 Resend `/emails`发信逻辑变更时改
manifest.webmanifestPWA 元数据:名称、图标、启动 URL、显示模式改应用名/图标时改
sw.jsService Worker:网络优先缓存外壳,保证可安装 + 离线打开缓存策略变更时改
04

部署 & 更新

项目通过 Wrangler CLI 部署到 Cloudflare Pages,无需 git 仓库。已通过 OAuth 登录,无需每次输入账号密码。

首次部署(已完成,留作记录)

npm i -g wrangler
wrangler pages project create aifans-outbox --production-branch main
wrangler pages deploy . --project-name aifans-outbox --branch main

日常更新流程

修改完任意文件后,在项目目录执行:

cd D:\projects\resend
wrangler pages deploy . --project-name aifans-outbox --branch main

30 秒左右全球生效,无需手动刷新 CDN。

更新 Secret(密钥)

# 更新 Resend API Key
echo "re_新密钥" | wrangler pages secret put RESEND_API_KEY --project-name aifans-outbox

# 更新登录密码
echo "新密码" | wrangler pages secret put APP_PASSWORD --project-name aifans-outbox
注意:用 echo "..." | 写入 Secret 时,部分系统会带换行符导致密钥匹配失败。本项目后端已在两处加 .trim() 规避此问题。

查看 Wrangler 登录状态

wrangler whoami

显示 labladodog@163.com 及账号 ID 即表示已登录,权限涵盖 Pages Write。

05

密钥管理

Secret 名用途在哪里查看/修改
RESEND_API_KEY调用 Resend API 发信,格式 re_...Resend 后台 → API Keys;Cloudflare Pages → Settings → Variables and Secrets
APP_PASSWORD网页登录密码(自定义),校验头 x-app-passwordCloudflare Pages → Settings → Variables and Secrets

Resend API Key Rotate(安全建议)

  1. 生成新 Key登录 resend.com/api-keys,Create API Key,复制新 key。
  2. 写入 Cloudflareecho "re_新key" | wrangler pages secret put RESEND_API_KEY --project-name aifans-outbox
  3. 重新部署wrangler pages deploy . --project-name aifans-outbox --branch main
  4. 删除旧 Key回 Resend 后台删掉旧 key,彻底失效。
06

PWA 实现细节

PWA(Progressive Web App)让网页可以像原生应用一样安装到设备。本项目用了三个标准组件:

① Web App Manifest(manifest.webmanifest)

告诉浏览器「这个网站可以被安装」,描述名称、图标、启动行为:

{
  "name": "AIFans Outbox",
  "short_name": "Outbox",
  "start_url": "/",
  "display": "standalone",      // 独立窗口,无浏览器地址栏
  "background_color": "#16130f",
  "theme_color": "#16130f",
  "icons": [
    { "src": "/icon-192.png", "sizes": "192x192", "purpose": "any" },
    { "src": "/icon-512.png", "sizes": "512x512", "purpose": "any" },
    { "src": "/icon-maskable-512.png", "sizes": "512x512", "purpose": "maskable" }
  ]
}

② Service Worker(sw.js)

浏览器在后台运行的脚本,拦截网络请求实现缓存。本项目策略:

③ 图标生成

原始设计是 SVG(深色背景 + 琥珀色同心圆),通过 sharp 库渲染成不同尺寸 PNG:

node gen-icons.mjs  // 需先 npm install sharp
Maskable 图标(icon-maskable-512.png)用于 Android 自适应图标,设计时内容留有约 20% 安全边距,确保圆形裁切后图案居中完整。

在 index.html 中的引入方式

<link rel="manifest" href="/manifest.webmanifest" />
<meta name="theme-color" content="#16130f" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />

// 脚本末尾注册 Service Worker
if ("serviceWorker" in navigator) {
  window.addEventListener("load", () => {
    navigator.serviceWorker.register("/sw.js").catch(() => {});
  });
}
07

绑定自定义域名

目前通过 aifans-outbox.pages.dev 访问。如需绑定如 mail.aifans.fan

  1. 命令行方式wrangler pages domain add aifans-outbox --domain mail.aifans.fan——因 aifans.fan 已在本账号的 Cloudflare,DNS 记录自动添加。
  2. 或后台操作Cloudflare → Workers & Pages → aifans-outbox → Custom domains → Set up a domain → 填入域名确认。
  3. 等待生效通常 1–5 分钟,SSL 证书自动签发。之后用自定义域名访问即可,*.pages.dev 地址同时保留有效。
08

未来扩展

Telegram 机器人入口 设计已完成,待实施

在 Pages 项目里新增 functions/telegram/webhook.js,复用已有的 RESEND_API_KEY。在 Telegram 发 /send 收件人 || 主题 || 正文 即可触发发信,有回执推送。需额外 3 个 Secret:TELEGRAM_BOT_TOKENTELEGRAM_ALLOWED_CHAT_ID(白名单)、TELEGRAM_WEBHOOK_SECRET

邮件中转(发邮件→自动转发)未来备选

用 Cloudflare Email Routing 接收发往魔法地址(如 relay@aifans.fan)的邮件,Worker 解析后用 Resend 重新以 aifans.fan 域名发出。适合"转发已有内容"场景,Wrangler token 已有 email_routing 权限。

Cloudflare Access 替代密码登录 安全加固

Zero Trust → Access → Applications → Self-hosted,绑定此网址,加一条 Allow 策略(你的邮箱地址)。之后访问自动跳 Cloudflare 邮件验证,无需维护 APP_PASSWORD


AIFans Outbox · Cloudflare Pages + Resend · 最后更新 2026-05