邮件与 Webhook 订阅 API (Newsletter)

APay 核心层内置了统一的邮件与 Webhook 订阅底座(newsletter_subscribers 表与 server/utils/newsletter.ts),供全站博客专栏、Hoxi 可喜 AI(blog / hoxi_updates)以及 TiboSay Codex 重置监控(codex_resets)共用。


公开接口

1. 提交订阅 (POST /api/newsletter/subscribe)

登记或重新激活指定主题(topic)的邮箱或 HTTPS Webhook 订阅。

请求体 (Body)

{
  "channel": "email",
  "email": "developer@example.com",
  "topic": "blog",
  "source": "hoxi_blog",
  "locale": "zh",
  "sendWelcome": true
}
字段类型必填说明
channel'email' | 'webhook'否默认为 'email'
target / emailstring是邮箱地址或 https:// Webhook 地址(禁止指向内网/本地地址)
topicstring否订阅分组(如 general、blog、hoxi_updates、codex_resets),默认 'general'
sourcestring否订阅来源标识(如 web、hoxi_blog、codex、codex_chat)
localestring否语言偏好(zh / en)
sendWelcomeboolean否新增或重新激活时是否发送欢迎确认邮件(默认 true)

成功响应 (200)

{
  "ok": true,
  "code": 0,
  "isNew": true,
  "reactivated": false,
  "topic": "blog",
  "channel": "email",
  "message": "订阅成功!有重要更新时我们将第一时间邮件通知您。"
}

2. 一键退订与恢复订阅 (GET / POST /api/newsletter/unsubscribe)

系统发出的每封订阅邮件底部都会自动附带签名退订链接 /api/newsletter/unsubscribe?token=<unsubscribeToken>。

  • GET /api/newsletter/unsubscribe?token=...:将该订阅标记为 unsubscribed,并返回自带「误点恢复订阅(?action=resubscribe)」按钮的双语确认页面;若携带 format=json 或 Accept: application/json 则返回 JSON。
  • POST /api/newsletter/unsubscribe:支持 { "token": "...", "action": "unsubscribe" | "resubscribe" }。

管理员接口 (/api/admin/email/*)

需管理员 settings:view(查询)或 settings:edit(变更与群发)权限:

  1. GET /api/admin/email/subscribers:分页查询订阅者列表及活跃/退订统计(支持 search、topic、status、channel 过滤)。
  2. POST /api/admin/email/subscribers:支持管理员手动添加订阅者(action: 'create')、切换订阅状态(action: 'toggle')或删除记录(action: 'delete')。
  3. POST /api/admin/email/broadcast:按指定 topic 向所有活跃邮箱与 Webhook 订阅者群发通知(或通过 targetEmail 发送单封测试邮件),底层统一走 deliverEmail() 并记录 email_logs。