{"id":23235100,"url":"https://github.com/beilunyang/moemail","last_synced_at":"2025-05-14T19:02:36.873Z","repository":{"id":268591343,"uuid":"896908848","full_name":"beilunyang/moemail","owner":"beilunyang","description":"一个基于 NextJS + Cloudflare 技术栈构建的可爱临时邮箱服务🎉","archived":false,"fork":false,"pushed_at":"2025-03-31T15:00:50.000Z","size":1792,"stargazers_count":964,"open_issues_count":12,"forks_count":368,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-03T18:11:14.776Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://moemail.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/beilunyang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-01T15:50:31.000Z","updated_at":"2025-04-03T09:20:07.000Z","dependencies_parsed_at":"2024-12-17T18:36:28.404Z","dependency_job_id":"b3ac05c5-fced-4613-8325-4b6a574341ee","html_url":"https://github.com/beilunyang/moemail","commit_stats":{"total_commits":35,"total_committers":3,"mean_commits":"11.666666666666666","dds":0.08571428571428574,"last_synced_commit":"7b9a2df145daf55fa63da6558de7e8241f5bd48d"},"previous_names":["beilunyang/moemail"],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beilunyang%2Fmoemail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beilunyang%2Fmoemail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beilunyang%2Fmoemail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beilunyang%2Fmoemail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/beilunyang","download_url":"https://codeload.github.com/beilunyang/moemail/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248352186,"owners_count":21089397,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-19T03:18:32.791Z","updated_at":"2025-04-11T06:20:21.347Z","avatar_url":"https://github.com/beilunyang.png","language":"TypeScript","funding_links":["https://www.buymeacoffee.com/beilunyang"],"categories":["TypeScript","邮箱","AI 相关"],"sub_categories":["注册相关"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"public/icons/icon-192x192.png\" alt=\"MoeMail Logo\" width=\"100\" height=\"100\"\u003e\n  \u003ch1 align=\"center\"\u003eMoeMail\u003c/h1\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  一个基于 NextJS + Cloudflare 技术栈构建的可爱临时邮箱服务🎉\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#在线演示\"\u003e在线演示\u003c/a\u003e •\n  \u003ca href=\"#特性\"\u003e特性\u003c/a\u003e •\n  \u003ca href=\"#技术栈\"\u003e技术栈\u003c/a\u003e •\n  \u003ca href=\"#本地运行\"\u003e本地运行\u003c/a\u003e •\n  \u003ca href=\"#部署\"\u003e部署\u003c/a\u003e •\n  \u003ca href=\"#邮箱域名配置\"\u003e邮箱域名配置\u003c/a\u003e •\n  \u003ca href=\"#权限系统\"\u003e权限系统\u003c/a\u003e •\n  \u003ca href=\"#系统设置\"\u003e系统设置\u003c/a\u003e •\n  \u003ca href=\"#Webhook 集成\"\u003eWebhook 集成\u003c/a\u003e •\n  \u003ca href=\"#OpenAPI\"\u003eOpenAPI\u003c/a\u003e •\n  \u003ca href=\"#环境变量\"\u003e环境变量\u003c/a\u003e •\n  \u003ca href=\"#Github OAuth App 配置\"\u003eGithub OAuth App 配置\u003c/a\u003e •\n  \u003ca href=\"#贡献\"\u003e贡献\u003c/a\u003e •\n  \u003ca href=\"#许可证\"\u003e许可证\u003c/a\u003e •\n  \u003ca href=\"#交流群\"\u003e交流群\u003c/a\u003e •\n  \u003ca href=\"#支持\"\u003e支持\u003c/a\u003e\n\u003c/p\u003e\n\n## 在线演示\n[https://moemail.app](https://moemail.app)\n\n![首页](https://pic.otaku.ren/20241209/AQADwsUxG9k1uVZ-.jpg \"首页\")\n\n\n![邮箱](https://pic.otaku.ren/20241209/AQADw8UxG9k1uVZ-.jpg \"邮箱\")\n\n![个人中心](https://pic.otaku.ren/20241227/AQADVsIxG7OzcFd-.jpg \"个人中心\")\n\n## 特性\n\n- 🔒 **隐私保护**：保护您的真实邮箱地址，远离垃圾邮件和不必要的订阅\n- ⚡ **实时收件**：自动轮询，即时接收邮件通知\n- ⏱️ **灵活有效期**：支持 1 小时、24 小时、3 天或永久有效\n- 🎨 **主题切换**：支持亮色和暗色模式\n- 📱 **响应式设计**：完美适配桌面和移动设备\n- 🔄 **自动清理**：自动清理过期的邮箱和邮件\n- 📱 **PWA 支持**：支持 PWA 安装\n- 💸 **免费自部署**：基于 Cloudflare 构建, 可实现免费自部署，无需任何费用\n- 🎉 **可爱的 UI**：简洁可爱萌萌哒 UI 界面\n- 🔔 **Webhook 通知**：支持通过 webhook 接收新邮件通知\n- 🛡️ **权限系统**：支持基于角色的权限控制系统\n- 🔑 **OpenAPI**：支持通过 API Key 访问 OpenAPI\n\n## 技术栈\n\n- **框架**: [Next.js](https://nextjs.org/) (App Router)\n- **平台**: [Cloudflare Pages](https://pages.cloudflare.com/)\n- **数据库**: [Cloudflare D1](https://developers.cloudflare.com/d1/) (SQLite)\n- **认证**: [NextAuth](https://authjs.dev/getting-started/installation?framework=Next.js) 配合 GitHub 登录\n- **样式**: [Tailwind CSS](https://tailwindcss.com/)\n- **UI 组件**: 基于 [Radix UI](https://www.radix-ui.com/) 的自定义组件\n- **邮件处理**: [Cloudflare Email Workers](https://developers.cloudflare.com/email-routing/)\n- **类型安全**: [TypeScript](https://www.typescriptlang.org/)\n- **ORM**: [Drizzle ORM](https://orm.drizzle.team/)\n\n## 本地运行\n\n### 前置要求\n\n- Node.js 18+\n- Pnpm\n- Wrangler CLI\n- Cloudflare 账号\n\n### 安装\n\n1. 克隆仓库：\n```bash\ngit clone https://github.com/beilunyang/moemail.git\ncd moemail\n```\n\n2. 安装依赖：\n```bash\npnpm install\n```\n\n3. 设置 wrangler：\n```bash\ncp wrangler.example.json wrangler.json\ncp wrangler.email.example.json wrangler.email.json\ncp wrangler.cleanup.example.json wrangler.cleanup.json\n```\n设置 Cloudflare D1 数据库名以及数据库 ID\n\n4. 设置环境变量：\n```bash\ncp .env.example .env.local\n```\n设置 AUTH_GITHUB_ID, AUTH_GITHUB_SECRET, AUTH_SECRET\n\n5. 创建本地数据库表结构\n```bash\npnpm db:migrate-local\n```\n\n### 开发\n\n1. 启动开发服务器：\n```bash\npnpm dev\n```\n\n2. 测试邮件 worker：\n目前无法本地运行并测试，请使用 wrangler 部署邮件 worker 并测试\n```bash\npnpm deploy:email\n```\n\n3. 测试清理 worker：\n```bash\npnpm dev:cleanup\npnpm test:cleanup\n```\n\n4. 生成 Mock 数据（邮箱以及邮件消息）\n```bash\npnpm generate-test-data\n```\n## 部署\n\n### 视频版保姆级部署教程\nhttps://www.bilibili.com/video/BV19wrXY2ESM/\n\n### 本地 Wrangler 部署\n1. 创建 .env 文件\n```bash\ncp .env.example .env\n```\n2. 在 .env 文件中设置[环境变量](#环境变量)\n\n3. 运行部署脚本\n```bash\npnpm dlx tsx ./scripts/deploy/index.ts\n```\n\n### Github Actions 部署\n\n本项目可使用 GitHub Actions 实现自动化部署。支持以下触发方式：\n\n1. **自动触发**：推送新的 tag 时自动触发部署流程\n2. **手动触发**：在 GitHub Actions 页面手动触发\n\n#### 部署步骤\n\n1. 在 GitHub 仓库设置中添加以下 Secrets：\n   - `CLOUDFLARE_API_TOKEN`: Cloudflare API 令牌\n   - `CLOUDFLARE_ACCOUNT_ID`: Cloudflare 账户 ID\n   - `AUTH_GITHUB_ID`: GitHub OAuth App ID\n   - `AUTH_GITHUB_SECRET`: GitHub OAuth App Secret\n   - `AUTH_SECRET`: NextAuth Secret，用来加密 session，请设置一个随机字符串\n   - `CUSTOM_DOMAIN`: 网站自定义域名，用于访问 MoeMail (可选， 如果不填, 则会使用 Cloudflare Pages 默认域名)\n   - `PROJECT_NAME`: Pages 项目名 （可选，如果不填，则为 moemail） \n   - `DATABASE_NAME`: D1 数据库名称 (可选，如果不填，则为 moemail-db)\n   - `KV_NAMESPACE_NAME`: Cloudflare KV namespace 名称，用于存储网站配置 （可选，如果不填，则为 moemail-kv）\n\n2. 选择触发方式：\n\n   **方式一：推送 tag 触发**\n   ```bash\n   # 创建新的 tag\n   git tag v1.0.0\n   \n   # 推送 tag 到远程仓库\n   git push origin v1.0.0\n   ```\n\n   **方式二：手动触发**\n   - 进入仓库的 Actions 页面\n   - 选择 \"Deploy\" workflow\n   - 点击 \"Run workflow\"\n\n3. 部署进度可以在仓库的 Actions 标签页查看\n\n#### 注意事项\n- 确保所有 Secrets 都已正确设置\n- 使用 tag 触发时，tag 必须以 `v` 开头（例如：v1.0.0）\n\n[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/beilunyang/moemail)\n\n\n## 邮箱域名配置\n\n在 MoeMail 个人中心页面，可以配置网站的邮箱域名，支持多域名配置，多个域名用逗号分隔\n![邮箱域名配置](https://pic.otaku.ren/20241227/AQAD88AxG67zeVd-.jpg \"邮箱域名配置\")\n\n### Cloudflare 邮件路由配置\n\n为了使邮箱域名生效，还需要在 Cloudflare 控制台配置邮件路由，将收到的邮件转发给 Email Worker 处理。\n\n1. 登录 [Cloudflare 控制台](https://dash.cloudflare.com/)\n2. 选择您的域名\n3. 点击左侧菜单的 \"电子邮件\" -\u003e \"电子邮件路由\"\n4. 如果显示 “电子邮件路由当前被禁用，没有在路由电子邮件”，请点击 \"启用电子邮件路由\"\n![启用电子邮件路由](https://pic.otaku.ren/20241223/AQADNcQxG_K0SVd-.jpg \"启用电子邮件路由\")\n5. 点击后，会提示你添加电子邮件路由 DNS 记录，点击 “添加记录并启用” 即可\n![添加电子邮件路由 DNS 记录](https://pic.otaku.ren/20241223/AQADN8QxG_K0SVd-.jpg \"添加电子邮件路由 DNS 记录\")\n6. 配置路由规则：\n   - Catch-all 地址: 启用 \"Catch-all\"\n   - 编辑 Catch-all 地址\n    - 操作: 选择 \"发送到 Worker\"\n    - 目标位置: 选择刚刚部署的 \"email-receiver-worker\"\n    - 保存\n  ![配置路由规则](https://pic.otaku.ren/20241223/AQADNsQxG_K0SVd-.jpg \"配置路由规则\")\n\n### 注意事项\n- 确保域名的 DNS 托管在 Cloudflare\n- Email Worker 必须已经部署成功\n- 如果 Catch-All 状态不可用(一直 loading)，请点击`路由规则`旁边的`目标地址`, 进去绑定一个邮箱\n\n## 权限系统\n\n本项目采用基于角色的权限控制系统（RBAC）。\n\n### 角色配置\n\n新用户默认角色由皇帝在个人中心的网站设置中配置：\n- 公爵：新用户将获得临时邮箱、Webhook 配置权限以及 API Key 管理权限\n- 骑士：新用户将获得临时邮箱和 Webhook 配置权限\n- 平民：新用户无任何权限，需要等待皇帝册封为骑士或公爵\n\n### 角色等级\n\n系统包含四个角色等级：\n\n1. **皇帝（Emperor）**\n   - 网站所有者\n   - 拥有所有权限\n   - 每个站点只能有一个皇帝\n\n2. **公爵（Duke）**  \n   - 超级用户\n   - 可以使用临时邮箱功能\n   - 可以配置 Webhook\n   - 可以使用创建 API Key 调用 OpenAPI\n   - 可以被皇帝贬为骑士或平民\n\n3. **骑士（Knight）**\n   - 高级用户\n   - 可以使用临时邮箱功能\n   - 可以配置 Webhook\n   - 可以被皇帝贬为平民或册封为公爵\n\n3. **平民（Civilian）**\n   - 普通用户\n   - 无任何权限\n   - 可以被皇帝册封为骑士或者公爵\n\n### 角色升级\n\n1. **成为皇帝**\n   - 第一个访问 `/api/roles/init-emperor` 接口的用户将成为皇帝，即网站所有者\n   - 站点已有皇帝后，无法再提升其他用户为皇帝\n\n2. **角色变更**\n   - 皇帝可以在个人中心页面将其他用户设为公爵、骑士或平民\n\n### 权限说明\n\n- **邮箱管理**：创建和管理临时邮箱\n- **Webhook 管理**：配置邮件通知的 Webhook\n- **API Key 管理**：创建和管理 API 访问密钥\n- **用户管理**：升降用户角色\n- **系统设置**：管理系统全局设置\n\n## 系统设置\n\n系统设置存储在 Cloudflare KV 中，包括以下内容：\n\n- `DEFAULT_ROLE`: 新注册用户默认角色，可选值为 `CIVILIAN`、`KNIGHT`、`DUKE`\n- `EMAIL_DOMAINS`: 支持的邮箱域名，多个域名用逗号分隔\n- `ADMIN_CONTACT`: 管理员联系方式\n- `MAX_EMAILS`: 每个用户可创建的最大邮箱数量\n\n**皇帝**角色可以在个人中心页面设置\n\n## Webhook 集成\n\n当收到新邮件时，系统会向用户配置并且已启用的 Webhook URL 发送 POST 请求。\n\n### 请求头\n```http\nContent-Type: application/json\nX-Webhook-Event: new_message\n```\n\n### 请求体\n```json\n{\n  \"emailId\": \"email-uuid\",\n  \"messageId\": \"message-uuid\",\n  \"fromAddress\": \"sender@example.com\",\n  \"subject\": \"邮件主题\",\n  \"content\": \"邮件文本内容\",\n  \"html\": \"邮件HTML内容\",\n  \"receivedAt\": \"2024-01-01T12:00:00.000Z\",\n  \"toAddress\": \"your-email@moemail.app\"\n}\n```\n\n### 配置说明\n1. 点击个人头像，进入个人中心\n2. 在个人中心启用 Webhook\n3. 设置接收通知的 URL\n4. 点击测试按钮验证配置\n5. 保存配置后即可接收新邮件通知\n\n### 测试\n\n项目提供了一个简单的测试服务器, 可以通过如下命令运行:\n\n```bash\npnpm webhook-test-server\n```\n\n测试服务器会在本地启动一个 HTTP 服务器，监听 3001 端口（http://localhost:3001）, 并打印收到的 Webhook 消息详情。\n\n如果需要进行外网测试，可以通过 Cloudflare Tunnel 将服务暴露到外网：\n```bash\npnpx cloudflared tunnel --url http://localhost:3001\n```\n\n### 注意事项\n- Webhook 接口应在 10 秒内响应\n- 非 2xx 响应码会触发重试\n\n## OpenAPI\n\n本项目提供了 OpenAPI 接口，支持通过 API Key 进行访问。API Key 可以在个人中心页面创建（需要是公爵或皇帝角色）。\n\n### 使用 API Key\n\n在请求头中添加 API Key：\n```http\nX-API-Key: YOUR_API_KEY\n```\n\n### API 接口\n\n#### 创建临时邮箱\n```http\nPOST /api/emails/generate\nContent-Type: application/json\n\n{\n  \"name\": \"test\",\n  \"expiryTime\": 3600000,\n  \"domain\": \"moemail.app\"\n}\n```\n参数说明：\n- `name`: 邮箱前缀，可选\n- `expiryTime`: 有效期（毫秒），可选值：3600000（1小时）、86400000（1天）、604800000（7天）、0（永久）\n- `domain`: 邮箱域名，可通过 `/api/emails/domains` 获取可用域名列表\n\n#### 获取邮箱列表\n```http\nGET /api/emails?cursor=xxx\n```\n参数说明：\n- `cursor`: 分页游标，可选\n\n#### 获取指定邮箱邮件列表\n```http\nGET /api/emails/{emailId}?cursor=xxx\n```\n参数说明：\n- `cursor`: 分页游标，可选\n\n#### 删除邮箱\n```http\nDELETE /api/emails/{emailId}\n```\n\n#### 获取单封邮件内容\n```http\nGET /api/emails/{emailId}/{messageId}\n```\n\n### 使用示例\n\n使用 curl 创建临时邮箱：\n```bash\ncurl -X POST https://your-domain.com/api/emails/generate \\\n  -H \"X-API-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"test\",\n    \"expiryTime\": 3600000,\n    \"domain\": \"moemail.app\"\n  }'\n```\n\n使用 JavaScript 获取邮件列表：\n```javascript\nconst res = await fetch('https://your-domain.com/api/emails/your-email-id', {\n  headers: {\n    'X-API-Key': 'YOUR_API_KEY'\n  }\n});\nconst data = await res.json();\n```\n\n## 环境变量\n\n本项目使用以下环境变量：\n\n### 认证相关\n- `AUTH_GITHUB_ID`: GitHub OAuth App ID\n- `AUTH_GITHUB_SECRET`: GitHub OAuth App Secret\n- `AUTH_SECRET`: NextAuth Secret，用来加密 session，请设置一个随机字符串\n\n### Cloudflare 配置\n- `CLOUDFLARE_API_TOKEN`: Cloudflare API Token\n- `CLOUDFLARE_ACCOUNT_ID`: Cloudflare Account ID\n- `DATABASE_NAME`: D1 数据库名称\n- `DATABASE_ID`: D1 数据库 ID (可选, 如果不填, 则会自动通过 Cloudflare API 获取)\n- `KV_NAMESPACE_NAME`: Cloudflare KV namespace 名称，用于存储网站配置\n- `KV_NAMESPACE_ID`: Cloudflare KV namespace ID，用于存储网站配置 （可选， 如果不填, 则会自动通过 Cloudflare API 获取）\n- `CUSTOM_DOMAIN`: 网站自定义域名, 如：moemail.app (可选， 如果不填, 则会使用 Cloudflare Pages 默认域名)\n- `PROJECT_NAME`: Pages 项目名 （可选，如果不填，则为 moemail） \n\n## Github OAuth App 配置\n\n- 登录 [Github Developer](https://github.com/settings/developers) 创建一个新的 OAuth App\n- 生成一个新的 `Client ID` 和 `Client Secret`\n- 设置 `Application name` 为 `\u003cyour-app-name\u003e`\n- 设置 `Homepage URL` 为 `https://\u003cyour-domain\u003e`\n- 设置 `Authorization callback URL` 为 `https://\u003cyour-domain\u003e/api/auth/callback/github`\n\n\n## 贡献\n\n欢迎提交 Pull Request 或者 Issue来帮助改进这个项目\n\n## 许可证\n\n本项目采用 [MIT](LICENSE) 许可证\n\n## 交流\n\u003ctable\u003e\n  \u003ctr style=\"max-width: 360px\"\u003e\n    \u003ctd\u003e\n      \u003cimg src=\"https://pic.otaku.ren/20250309/AQADAcQxGxQjaVZ-.jpg\" /\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cimg src=\"https://pic.otaku.ren/20250309/AQADCMQxGxQjaVZ-.jpg\" /\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr style=\"max-width: 360px\"\u003e\n    \u003ctd\u003e\n      关注公众号，了解更多项目进展以及AI，区块链，独立开发资讯\n    \u003c/td\u003e\n    \u003ctd\u003e\n      添加微信，备注 \"MoeMail\" 拉你进微信交流群\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## 支持\n\n如果你喜欢这个项目，欢迎给它一个 Star ⭐️\n或者进行赞助\n\u003cbr /\u003e\n\u003cbr /\u003e\n\u003cimg src=\"https://pic.otaku.ren/20240212/AQADPrgxGwoIWFZ-.jpg\" style=\"width: 400px;\"/\u003e\n\u003cbr /\u003e\n\u003cbr /\u003e\n\u003ca href=\"https://www.buymeacoffee.com/beilunyang\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-blue.png\" alt=\"Buy Me A Coffee\" style=\"width: 400px;\" \u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeilunyang%2Fmoemail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbeilunyang%2Fmoemail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeilunyang%2Fmoemail/lists"}