Files
gpt-plus-gpt/tools/team_invite_analysis.md
2026-03-15 20:48:19 +08:00

4.3 KiB
Raw Permalink Blame History

Team 邀请小号流程分析报告

1. 邀请流程 (Phase-7)

完整流程在 cmd/gptplus/main.go 第 582-718 行:

Team 创建成功 → 获取 workspace token → 循环 invite_count 次:
  1. 创建新 HTTP client (带独立代理 session)
  2. 调用 auth.Register() 注册新账号 ← 消耗一个邮箱
  3. 调用 chatgpt.InviteToTeam() 发送邀请 (POST /backend-api/accounts/{id}/invites)
  4. 成员登录获取 token
  5. 调用 auth.ObtainCodexTokens() 获取 Team 作用域 token (最多重试 3 次)
  6. 保存成员 auth 文件

邀请 API: POST /backend-api/accounts/{team_account_id}/invites

  • payload: {"email_addresses": ["xxx@outlook.com"], "role": "standard-user", "resend_emails": true}
  • 需要 workspace-scoped access token

注意:当前流程只发送邀请,没有"接受邀请"的步骤。 成员注册后直接通过 ObtainCodexTokens 获取 Team token假设邀请自动生效因为是 admin 邀请已注册邮箱)。


2. 小号获取邮件的逻辑

当前行为

小号注册时调用的是同一个 emailProv(第 618 行):

memberRegResult, memberRegErr := auth.Register(ctx, memberClient, emailProv, memberPassword)

auth.Register() 内部会调用 emailProv.CreateMailbox() 获取邮箱,然后调用 emailProv.WaitForVerificationCode() 获取 OTP。

有没有问题?

之前有问题(已修复): WaitForVerificationCode 使用的 $filter 查询被 Outlook REST API 拒绝InefficientFilter导致永远拿不到 OTP。现在已改为无 filter + 客户端过滤。

潜在问题: 无 filter 模式下拉取最近 10 封邮件,如果多个小号同时注册,收件箱里会有多封 OTP 邮件。由于有 notBefore 时间过滤 + $orderby=ReceivedDateTime+desc(最新优先),且代码取到第一个匹配的 OTP 就返回,所以正常情况下不会混淆。但如果两个小号在同一秒内收到 OTP理论上可能取错概率极低因为是串行注册


3. 小号是否遵循邮箱设定Outlook

是的。 小号使用的是同一个 emailProv 实例:

  • 主账号和所有小号共享同一个 OutlookProvider
  • 每次 CreateMailbox() 调用会返回 accounts[nextIdx] 并递增 nextIdx
  • 所以小号注册时会按顺序消耗 outmail.txt 中的 Outlook 账号

如果配置是 email.provider: "outlook",所有小号都会用 Outlook 邮箱。


4. 邮箱消耗顺序问题(核心问题)

场景

  • outmail.txt 有 10 个邮箱 (索引 0-9)
  • invite_count: 4
  • 第一次运行:邮箱 #0 注册 Plus → Team 成功 → 邀请 4 个小号

当前行为

邮箱 #0 → 主账号注册 (CreateMailbox, nextIdx: 0→1)
邮箱 #1 → 小号1注册 (CreateMailbox, nextIdx: 1→2)
邮箱 #2 → 小号2注册 (CreateMailbox, nextIdx: 2→3)
邮箱 #3 → 小号3注册 (CreateMailbox, nextIdx: 3→4)
邮箱 #4 → 小号4注册 (CreateMailbox, nextIdx: 4→5)

一次完整运行消耗 5 个邮箱1 主 + 4 小号)。

下一次运行会怎样?

会从邮箱 #0 重新开始,不是 #5。

原因:OutlookProvider.nextIdx 是内存变量,每次程序启动时初始化为 0。没有持久化记录哪些邮箱已经用过。

// NewOutlookProvider 每次创建时 nextIdx = 0
return &OutlookProvider{
    accounts: accounts,
}, nil

后果

  • 第二次运行会尝试用邮箱 #0 注册,但 #0 已经注册过 → 注册失败
  • 如果 OpenAI 返回的是 "Failed to register username" 而不是 "email already exists",程序无法区分
  • 需要手动从 outmail.txt 删除已用过的邮箱,或者实现已用邮箱的持久化追踪

5. 问题汇总与建议

# 问题 严重度 建议
1 nextIdx 不持久化:重启后从 #0 开始,已用邮箱会重复注册失败 🔴 用文件记录已用邮箱索引,或注册成功后从 outmail.txt 中移除
2 无接受邀请步骤:依赖 ObtainCodexTokens 自动加入 🟡 目前看起来可行,但可能需要验证在某些情况下是否需要显式 accept
3 OTP 串号风险:多小号共用收件箱时理论上可能取错 OTP 🟢 串行注册 + notBefore 过滤已足够,暂不需处理
4 Outlook filter 已修复 已改为无 filter + 客户端过滤