AIFans Outbox
涵盖日常使用方法、架构设计、文件说明、部署流程以及后续扩展指南。随时翻阅,无需查外部资料。
目录
访问 aifans-outbox.pages.dev(或已绑定的自定义域名),输入访问密码进入发信台。密码保存在浏览器 sessionStorage,关闭标签页即自动清除。
APP_PASSWORD)存储在 Cloudflare 后台 → Workers & Pages → aifans-outbox → Settings → Variables and Secrets,可在那里查看或修改。点击页面右上角「+ 管理发件域名」,弹出面板后:
添加新域名(第一步)
前往 Resend 域名管理,添加域名并按提示加 DNS 记录,等 Verified 后即可发信。
添加发件人地址(第二步)
切换到「发件人列表」标签,输入 名称 <you@example.com>,点添加——无需重新部署,立即生效(存 localStorage)。
Windows 11
Edge 或 Chrome 打开网址 → 地址栏右侧「安装此应用」图标 → 安装 → 开始菜单出现 Outbox 独立窗口图标。
iPhone / iPad
Safari 打开网址 → 底部分享按钮 → 「添加到主屏幕」→ 主屏出现图标,打开效果近似原生 App。
outbox.ahk,写入 ^!m::Run "https://aifans-outbox.pages.dev",双击运行后 Ctrl+Alt+M 随时打开。整个系统托管在 Cloudflare Pages 上,由两部分组成:
RESEND_DOMAINS 白名单内(如 aifans.fan)走 Resend,其余已验证域名走 Amazon SES。新增 SES 域名无需改代码(详见第 09 节)。RESEND_API_KEY、APP_PASSWORD、AWS 密钥均以加密 Secret 存储在 Cloudflare,仅 Edge Function 运行时可读。localStorage,会话密码存 sessionStorage,零后端状态。| 文件 | 职责 | 改动频率 |
|---|---|---|
| index.html | 全部前端逻辑(单文件 SPA),含登录、撰写、实时预览、发件人 localStorage 管理 | 功能迭代时改 |
| functions/api/send.js | 唯一后端入口,校验密码,按发件域名路由到 Resend 或 SES,组装邮件体并发送 | 发信逻辑/提供商变更时改 |
| functions/api/_aws4fetch.js | AWS Signature V4 签名(aws4fetch,MIT),用 Web Crypto 在 Worker 内给 SES 请求签名 | 几乎不动 |
| manifest.webmanifest | PWA 元数据:名称、图标、启动 URL、显示模式 | 改应用名/图标时改 |
| sw.js | Service Worker:网络优先缓存外壳,保证可安装 + 离线打开 | 缓存策略变更时改 |
项目通过 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。
# 更新 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 whoami
显示 labladodog@163.com 及账号 ID 即表示已登录,权限涵盖 Pages Write。
| Secret 名 | 用途 | 在哪里查看/修改 |
|---|---|---|
| RESEND_API_KEY | 调用 Resend API 发信,格式 re_... | Resend 后台 → API Keys;Cloudflare Pages → Settings → Variables and Secrets |
| APP_PASSWORD | 网页登录密码(自定义),校验头 x-app-password | Cloudflare Pages → Settings → Variables and Secrets |
| RESEND_DOMAINS | 走 Resend 的域名白名单(逗号分隔),当前 aifans.fan;其余域名自动走 SES | Cloudflare Pages → Variables and Secrets |
| AWS_ACCESS_KEY_ID | SES 鉴权用 IAM access key,格式 AKIA... | AWS IAM → Users → 该用户 → Security credentials |
| AWS_SECRET_ACCESS_KEY | SES 鉴权用 IAM secret(仅创建时显示一次) | AWS IAM(丢失只能重新生成) |
| AWS_SES_REGION | SES 区域,当前 us-east-2(必须与域名验证所在区一致) | AWS SES 控制台右上角区域 |
echo "re_新key" | wrangler pages secret put RESEND_API_KEY --project-name aifans-outboxwrangler pages deploy . --project-name aifans-outbox --branch mainecho "AKIA新..." | wrangler pages secret put AWS_ACCESS_KEY_ID --project-name aifans-outbox,secret 同理写 AWS_SECRET_ACCESS_KEY。wrangler pages deploy . --project-name aifans-outbox --branch mainPWA(Progressive Web App)让网页可以像原生应用一样安装到设备。本项目用了三个标准组件:
告诉浏览器「这个网站可以被安装」,描述名称、图标、启动行为:
{
"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" }
]
}
浏览器在后台运行的脚本,拦截网络请求实现缓存。本项目策略:
index.html、manifest、图标,安装时预缓存,断网可打开界面。原始设计是 SVG(深色背景 + 琥珀色同心圆),通过 sharp 库渲染成不同尺寸 PNG:
node gen-icons.mjs // 需先 npm install sharp
icon-maskable-512.png)用于 Android 自适应图标,设计时内容留有约 20% 安全边距,确保圆形裁切后图案居中完整。<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(() => {});
});
}
目前通过 aifans-outbox.pages.dev 访问。如需绑定如 mail.aifans.fan:
wrangler pages domain add aifans-outbox --domain mail.aifans.fan——因 aifans.fan 已在本账号的 Cloudflare,DNS 记录自动添加。*.pages.dev 地址同时保留有效。Telegram 机器人入口 设计已完成,待实施
在 Pages 项目里新增 functions/telegram/webhook.js,复用已有的 RESEND_API_KEY。在 Telegram 发 /send 收件人 || 主题 || 正文 即可触发发信,有回执推送。需额外 3 个 Secret:TELEGRAM_BOT_TOKEN、TELEGRAM_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。
Resend 免费版仅允许 1 个自定义域名。为合法、低成本地支持多域名,后端改为按发件域名自动路由:
aifans.fan 继续走 Resend 免费,新域名走 Amazon SES(域名不限、按量计费 $0.10/1000 封,个人量级近乎免费)。
后端读取 RESEND_DOMAINS 白名单:命中的域名走 Resend,其余一律走 SES。
所以新增 SES 域名时无需改这个变量,也无需改代码。
| 域名 | 通道 | 状态 |
|---|---|---|
| aifans.fan | Resend | ✅ 正常发信(不受改造影响) |
| sinosurg.com | Amazon SES | DKIM 已加 DNS(验证中→Verified);路由 + SigV4 签名已通;SES 生产访问审核中 |
us-east-2)→ Identities → Create identity → Domain → 填域名,得到 3 条 DKIM CNAME。名称 <you@新域名>。functions/api/_aws4fetch.js(基于 Web Crypto 的 HMAC-SHA256 链),在 Cloudflare Worker 内完成签名,无需 AWS SDK。https://email.{region}.amazonaws.com/v2/email/outbound-emails,body 用 SES 的 Simple 邮件结构(Subject/Body Html|Text,支持 cc/bcc/reply_to)。{ ok, id, provider },provider 标明实际走的是 resend 还是 ses,便于排查。为支持「换账号 / 换电脑 / 换人接手」,项目已做到完全自包含、可复现。完整步骤见仓库根目录的
MIGRATION.md,这里是要点速览。
后端依赖以下 6 项(存于 Cloudflare Pages → Settings → Variables and Secrets)。 真实值只在各平台后台,代码内无明文密钥。
| 名称 | 用途 |
|---|---|
| APP_PASSWORD | 网页登录密码 |
| RESEND_API_KEY | Resend 发信 key |
| RESEND_DOMAINS | 走 Resend 的域名白名单(当前 aifans.fan),其余走 SES |
| AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY | SES 鉴权 IAM 密钥 |
| AWS_SES_REGION | SES 区域(当前 us-east-2) |
wrangler pages deploy . --project-name aifans-outbox --branch main换 Cloudflare 账号
新账号 wrangler login → create project → deploy → 重设 6 个 Secret → 再 deploy。若域名 DNS 也迁移,需重建 DKIM/SPF。
换 AWS 账号(SES)
重验证域名(新 DKIM CNAME)→ 新建 IAM key → 更新 3 个 AWS Secret → 重新申请生产访问(新账号默认沙盒)。
换 Resend 账号
新账号验证 aifans.fan → 建新 API Key → 更新 RESEND_API_KEY → 重新部署。
换电脑 / 接手人
账号不变时最简单:装 wrangler → wrangler login → 拷贝项目目录(或 git clone)→ 直接 deploy,Secret 已在云端无需重设。
MIGRATION.md —— 完整迁移/交接手册(外部依赖全景、Secret 清单、各场景步骤、从零重建 Checklist)。scripts/set-secrets.example.ps1 —— 批量设置全部 Secret 的模板(填真实值后运行)。scripts/add-domain-dns.example.ps1 —— 给新 SES 域名批量写 DKIM/DMARC DNS 的模板。.gitignore —— 已配好,可安全 git init 推私有仓库作为交接载体(代码无明文密钥)。AIFans Outbox · Cloudflare Pages + Resend + Amazon SES · 最后更新 2026-05-30