Files
GuJumpgate/docs/多注册流程邮件分层设计.md
T

223 lines
6.1 KiB
Markdown
Raw 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.
# 多注册流程邮件分层设计
本文专门解决“邮件轮询虽然看起来像公共能力,但实际 OpenAI 规则已经写进 provider 脚本和后台轮询里”这个问题。
## 1. 先说结论
邮件相关能力必须拆成两层,不能再只写一句“mail polling 通用化”:
1. `mail provider driver`
2. `flow mail rules`
前者负责“怎么从 Gmail / 163 / 2925 / Inbucket / API 邮箱里拿到邮件”,后者负责“哪封邮件算当前 flow 需要的验证码 / magic link / 激活链接”。
## 2. 当前源码里的真实耦合
### 2.1 后台轮询 payload 已经带着 OpenAI 过滤条件
`background/verification-flow.js` 当前在 `getVerificationPollPayload()` 里直接写死:
- `senderFilters: ['openai', 'noreply', 'verify', 'auth', ...]`
- `subjectFilters: ['verify', 'verification', 'code', '验证码', 'confirm', ...]`
这不是 provider 通用逻辑,而是 OpenAI flow 规则。
### 2.2 内容脚本也已经写死 OpenAI / ChatGPT 正则
当前多个 provider 脚本里直接内嵌了 OpenAI / ChatGPT 识别:
- `content/gmail-mail.js`
- `content/mail-163.js`
- `content/mail-2925.js`
- `content/inbucket-mail.js`
例如:
- `openai`
- `chatgpt`
- `verification`
- `log-in code`
- `strictChatGPTCodeOnly`
这意味着现在不是“通用 provider + OpenAI 规则”,而是“OpenAI 规则渗透进 provider 实现本身”。
### 2.3 LuckMail 不能直接算进共享邮件层
LuckMail 当前还有一个额外边界:它不只是“邮箱提供商”,还绑定了 OpenAI 项目购邮与复用语义。
当前事实包括:
- `DEFAULT_LUCKMAIL_PROJECT_CODE = 'openai'`
- sidepanel 明确只展示 `openai` 项目的 LuckMail 邮箱
所以 LuckMail 当前应留在 OpenAI flow 内,不直接并入通用 `mailProviders`
## 3. 目标分层
## 3.1 第一层:`mail provider driver`
这一层只负责 provider 访问与消息归一化,不理解具体网站业务。
职责包括:
- 打开 provider 页面或请求 provider API
- 等待页面 ready / 会话可用
- 列邮件、开邮件、取正文、删邮件
- 会话级去重
- 输出统一格式的消息对象
建议输出结构:
```js
{
providerId: 'gmail',
messageId: 'abc123',
receivedAt: 1710000000000,
sender: 'OpenAI <noreply@openai.com>',
subject: 'Your code is 123456',
previewText: 'Your code is 123456',
normalizedText: 'your code is 123456',
html: '<html>...</html>',
links: ['https://...'],
targetHints: ['user@example.com'],
metadata: {},
}
```
这一层不要再写:
- “这是不是 OpenAI 邮件”
- “是不是 ChatGPT 登录码”
- “这个 code 是否必须 6 位”
## 3.2 第二层:`flow mail rules`
这一层由具体 flow 定义:
- 要找的邮件类型
- 过滤条件
- 选择规则
- 提取规则
- 命中后的消费动作
建议接口:
```js
flow.mailRules = {
signupCode: {
buildQuery(state) {},
matchMessage(message, state) {},
extractArtifact(message, state) {},
afterConsume(message, provider, state) {},
},
loginCode: {
buildQuery(state) {},
matchMessage(message, state) {},
extractArtifact(message, state) {},
},
};
```
其中:
- `buildQuery` 负责时间窗、目标邮箱、允许的发件人线索
- `matchMessage` 负责判定这是不是当前 flow 的邮件
- `extractArtifact` 负责提取 `code / magic-link / activation-link`
- `afterConsume` 负责删除邮件、记录 cursor、保存已试 code
## 4. 建议的共享 mail service 接口
```js
mailService.poll({
providerId: 'gmail',
rule: flow.mailRules.signupCode,
state,
maxAttempts: 5,
intervalMs: 3000,
});
```
内部流程:
1. provider driver 按 query 拉取候选消息
2. rule 决定哪封命中
3. rule 提取 artifact
4. service 返回统一结果
返回值示例:
```js
{
ok: true,
artifact: {
type: 'code',
value: '123456',
},
message: { ...normalizedMessage },
}
```
## 5. OpenAI flow 当前应该拆出的规则
OpenAI 至少需要单独拆出这些规则文件:
- `flows/openai/mail-rules/signup-code.js`
- `flows/openai/mail-rules/login-code.js`
- `flows/openai/mail-rules/add-email-code.js`
它们负责承接现在散落在这些地方的规则:
- `verification-flow.js` 中的 sender / subject filters
- `gmail-mail.js` / `mail-163.js` / `mail-2925.js` / `inbucket-mail.js` 中的 OpenAI / ChatGPT 正则
- `strictChatGPTCodeOnly`
- Step 4 与 Step 8 不同的时间窗和目标邮箱逻辑
## 6. provider driver 的拆分建议
### 6.1 可以进入共享层的 provider
这些 provider 的访问方式本身有共享价值,可以做成共享 mail driver
- Gmail
- 163 / 126 / 163 VIP
- 2925
- Inbucket
- iCloud Mail
- Hotmail helper / Graph Mail
- Cloud Mail / SkyMail
### 6.2 暂时不进入共享层的 provider
- LuckMail:当前仍是 OpenAI 项目购邮与验证码轮询能力的一部分
如果未来第二个 flow 也明确复用 LuckMail,且复用的是“同一套 project / token / 生命周期”,再考虑把它抽出来。
## 7. `registrationEmailState` 与邮件层的关系
`registrationEmailState` 负责“当前流程邮箱身份”,不是“provider 拉信规则”。
所以后续边界应是:
- `registrationEmailState`:运行态身份记录
- `mail provider driver`:拉信能力
- `flow mail rules`:判定与提取
不要再在 `registrationEmailState` 或 provider driver 里夹带 OpenAI `add-email` 业务判断。
## 8. 迁移顺序
1. 先把 `background/verification-flow.js` 里的查询构造迁到 `flows/openai/mail-rules/*`
2. 再把各 provider 脚本里的 OpenAI / ChatGPT 正则搬出到 rule 层
3. 保留 provider 里的“消息抓取 / 页面操作 / 删除策略”
4. 等第二个 flow 接入时,只新增它自己的 `mail-rules`,不改 Gmail / 163 / 2925 driver
## 9. 本文对应解决的缺口
本文主要补齐以下缺口:
- “Mail polling 通用化”表述过于粗糙,没有说明 provider 与 rule 两层
- provider 内容脚本里已经嵌入 OpenAI 规则
- `strictChatGPTCodeOnly` 这类开关的归属边界不清
- LuckMail 当前其实还是 OpenAI flow 私有邮件能力,不是共享 provider