From 5563ecf7294884d7c45f390f5b414120a636dec2 Mon Sep 17 00:00:00 2001 From: Aaron Liang <76561968+AaronL725@users.noreply.github.com> Date: Wed, 15 Jul 2026 03:24:21 +0800 Subject: [PATCH] docs: refresh README for modular architecture and recovery flows --- README.md | 528 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 360 insertions(+), 168 deletions(-) diff --git a/README.md b/README.md index e637143..d133cb8 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Grok Register — GUI and CLI registration automation toolkit](assets/banner.png)](https://github.com/AaronL725/grok-register) -Grok Register 是一个面向自动化流程研究、测试环境验证和个人学习的 Python 自动化注册工具 — 支持 GUI / CLI、临时邮箱、浏览器流程控制、账号输出和 grok2api token 池写入。 +Grok Register 是一个面向自动化流程研究、测试环境验证和个人学习的 Python 工具。项目提供 GUI / CLI、四种临时邮箱接入、Chromium 页面自动化、账号安全落盘、pending 恢复、grok2api token 入池,以及可选的 CPA xAI OIDC 凭证导出。

License: MIT @@ -27,109 +27,172 @@ Grok Register 是一个面向自动化流程研究、测试环境验证和个人 --- -> 本项目仅用于自动化流程研究、测试环境验证和个人学习。请遵守目标网站服务条款、当地法律法规和第三方服务限制。 +> [!IMPORTANT] +> 本项目仅用于自动化流程研究、测试环境验证和个人学习。使用者应自行遵守目标网站服务条款、当地法律法规和第三方服务限制。请勿将本项目用于滥用、绕过平台限制或未经授权的商业用途。 -## Contents +## 目录 -- [功能](#功能) +- [当前功能](#当前功能) +- [运行流程](#运行流程) - [环境要求](#环境要求) - [安装](#安装) - [配置](#配置) -- [运行](#运行) -- [输出文件](#输出文件) -- [稳定性机制](#稳定性机制) +- [运行方式](#运行方式) +- [输出与 pending 恢复](#输出与-pending-恢复) +- [稳定性与安全机制](#稳定性与安全机制) +- [项目架构](#项目架构) +- [测试](#测试) - [常见问题](#常见问题) -- [目录结构](#目录结构) - [License](#license) - [Acknowledgments](#acknowledgments) - [Star History](#star-history) -## 功能 +## 当前功能 -- 支持 GUI 图形界面运行。 -- 支持 CLI 终端运行,不启动 Tk GUI。 -- 注册流程使用 Chromium/Chrome 浏览器页面完成。 -- 支持 DuckMail、YYDS、Cloudflare,以及 Cloud Mail 无人收件模式。 -- 支持验证码邮件轮询和解析。 -- 支持成功账号实时写入 `accounts_*.txt`。 -- 支持将 SSO token 写入 grok2api 本地或远端池。 -- 支持注册成功后可选导出 CLIProxyAPI 使用的 CPA xAI OAuth 凭证。 -- 支持注册后尝试开启 NSFW。 -- 支持页面卡住检测、当前账号重试、浏览器重启和内存清理。 +- **GUI 与 CLI 共用同一批量编排流程**,避免两套业务逻辑产生差异。 +- 使用真实 Chromium / Chrome 页面完成注册、验证码、资料填写、Turnstile 与 SSO cookie 获取。 +- 支持四种邮箱服务: + - DuckMail + - YYDS + - Cloudflare 临时邮箱 + - Cloud Mail 无人收件模式 +- 邮件正文统一兼容纯文本、HTML 字符串和 HTML 列表。 +- Cloudflare 收件时严格过滤非目标地址邮件,不依赖是否开启日志。 +- 成功账号实时写入 `accounts_*.txt`。 +- 主结果写入失败时自动写入 `*.pending.jsonl`,可稍后幂等恢复。 +- 支持将 SSO token 写入 grok2api 本地池和远端池。 +- 支持注册成功后可选导出 CLIProxyAPI 使用的 CPA xAI OIDC 凭证。 +- 支持注册后尝试开启 NSFW;失败不会影响账号保存。 +- 支持浏览器重启、卡住重试、邮箱更换、定期内存清理和安全取消。 +- GUI / CLI 均展示四项批次状态: + - 成功 + - 失败 + - 待恢复 + - 后处理警告 + +## 运行流程 + +单个账号的主要流程如下: + +```text +打开注册页 + → 创建临时邮箱并提交 + → 轮询并填写验证码 + → 填写资料 + → 等待 SSO cookie + → 可选开启 NSFW + → 保存账号 + → 可选写入 grok2api + → 可选导出 CPA/OIDC +``` + +当前注册地址保持为: + +```text +https://accounts.x.ai/sign-up?redirect=grok-com +``` + +账号已经注册成功后,token 入池或 CPA 导出属于**附加后处理**。附加功能失败只会增加“后处理警告”,不会把已经保存的账号重新统计为注册失败。 ## 环境要求 -- Python 3.9+ +- Python **3.9+** - Google Chrome 或 Chromium -- 可访问注册页面和临时邮箱 API 的网络环境 +- 可访问注册页面和所选邮箱 API 的网络环境 +- GUI 模式需要 Tkinter;没有 Tkinter 时可使用 CLI 模式 + +项目针对 Python 3.9 与 Python 3.12 执行过完整回归测试。代码应避免使用仅 Python 3.10+ 支持的类型语法。 ## 安装 -下载项目到电脑: +克隆仓库: ```bash git clone https://github.com/AaronL725/grok-register.git cd grok-register ``` +建议创建虚拟环境: + +```bash +python -m venv .venv +``` + +激活虚拟环境: + +```bash +# Windows PowerShell +.venv\Scripts\Activate.ps1 + +# macOS / Linux +source .venv/bin/activate +``` + 安装依赖: ```bash -pip install -r requirements.txt +python -m pip install --upgrade pip +python -m pip install -r requirements.txt ``` 复制配置文件: ```bash +# macOS / Linux cp config.example.json config.json + +# Windows CMD +copy config.example.json config.json ``` -然后按需编辑 `config.json`。 +然后编辑 `config.json`。该文件可能包含 API Key、JWT、代理和远端服务密钥,已经被 `.gitignore` 忽略,不要提交到 Git。 ## 配置 -常用配置项: +配置校验分为两层: + +1. **结构校验**:检查类型、枚举、URL 和数值范围。GUI 启动时只执行这一层,因此旧配置缺少当前服务所需字段时仍可打开界面修改。 +2. **运行校验**:点击“开始注册”或启动 CLI 任务时,检查当前启用功能所需的配置。 + +### 基础配置 | 配置项 | 说明 | | --- | --- | -| `email_provider` | 邮箱服务商:`duckmail`、`yyds`、`cloudflare`、`cloudmail` | -| `register_count` | 本次目标注册数量 | -| `proxy` | 代理地址,可留空 | +| `email_provider` | `duckmail`、`yyds`、`cloudflare` 或 `cloudmail` | +| `register_count` | 本批次目标数量,允许范围由配置校验控制 | +| `proxy` | 主注册流程代理,可留空 | | `enable_nsfw` | 注册后是否尝试开启 NSFW | -| `cloudflare_api_base` | Cloudflare 临时邮箱 API 地址 | -| `cloudflare_api_key` | Cloudflare 临时邮箱接口密钥;默认匿名模式留空,admin 模式填 `ADMIN_PASSWORD` | -| `cloudflare_auth_mode` | Cloudflare API 鉴权模式;默认 `none`,可选 `bearer`、`x-api-key`、`x-admin-auth`、`query-key` | -| `cloudflare_path_domains` | Cloudflare 域名列表路径;默认 `/api/domains` | -| `cloudflare_path_accounts` | Cloudflare 创建邮箱路径;默认匿名模式用 `/api/new_address`,admin 模式用 `/admin/new_address` | -| `cloudflare_path_token` | Cloudflare token 路径;默认 `/api/token` | -| `cloudflare_path_messages` | Cloudflare 收件列表路径;默认 `/api/mails` | -| `defaultDomains` | Cloudflare 临时邮箱默认域名 | -| `cloudmail_api_base` | Cloud Mail 站点地址 | -| `cloudmail_public_token` | Cloud Mail 公共 API Token,不会写入邮箱凭证文件 | -| `cloudmail_domains` | Cloud Mail 无人收件域名,多个域名用英文逗号分隔 | -| `cloudmail_path_messages` | Cloud Mail 公共收件接口路径,默认 `/api/public/emailList` | -| `grok2api_auto_add_local` | 是否写入本地 grok2api token 池 | -| `grok2api_local_token_file` | 本地 grok2api token 文件路径 | -| `grok2api_auto_add_remote` | 是否写入远端 grok2api | -| `grok2api_remote_base` | 远端 grok2api 地址,可填站点根地址或 `/admin/api` 管理 API 地址 | -| `grok2api_remote_app_key` | 远端 grok2api app key | -| `cpa_export_enabled` | 是否在 SSO 成功后额外导出 CPA xAI OIDC 凭证 | -| `cpa_auth_dir` | 本地 CPA 导出目录,生成 `xai-*.json` | -| `cpa_copy_to_hotload` | 是否额外复制到 CLIProxyAPI 的 auth-dir | -| `cpa_hotload_dir` | CLIProxyAPI auth-dir 路径 | -| `cpa_proxy` | CPA/OIDC 专用代理;留空则回退到 `proxy` | -| `cpa_headless` | CPA/OIDC 浏览器是否无头,默认建议 `false` | +| `user_agent` | 浏览器和请求使用的 User-Agent | -### Cloudflare 临时邮箱匿名模式(默认) +### DuckMail -默认情况下,Cloudflare 邮箱使用 `dreamhunter2333/cloudflare_temp_email` 的匿名接口创建邮箱并读取邮件: +| 配置项 | 说明 | +| --- | --- | +| `duckmail_api_key` | 可选 DuckMail API Key | -- 创建邮箱:`POST /api/new_address` -- 读取邮件:`GET /api/mails` -- 鉴权模式:`none` -- `cloudflare_api_key`:留空 +### YYDS -这是项目的默认路线。没有特殊需求时,保持下面配置即可: +| 配置项 | 说明 | +| --- | --- | +| `yyds_api_key` | YYDS API Key | +| `yyds_jwt` | YYDS JWT | + +选择 `yyds` 时,`yyds_api_key` 和 `yyds_jwt` 至少配置一个,否则运行校验会直接拒绝启动。 + +### Cloudflare 临时邮箱 + +| 配置项 | 说明 | +| --- | --- | +| `cloudflare_api_base` | Cloudflare 临时邮箱 API 根地址 | +| `cloudflare_api_key` | 匿名模式留空;admin 模式填写 `ADMIN_PASSWORD` | +| `cloudflare_auth_mode` | `none`、`bearer`、`x-api-key`、`x-admin-auth` 或 `query-key` | +| `cloudflare_path_domains` | 域名列表路径,默认 `/api/domains` | +| `cloudflare_path_accounts` | 创建邮箱路径,默认 `/api/new_address` | +| `cloudflare_path_token` | token 路径,默认 `/api/token` | +| `cloudflare_path_messages` | 收件列表路径,默认 `/api/mails` | +| `defaultDomains` | 默认收信域名;多个域名用英文逗号分隔并轮换使用 | + +#### 匿名创建模式 ```json { @@ -141,13 +204,13 @@ cp config.example.json config.json "cloudflare_path_accounts": "/api/new_address", "cloudflare_path_token": "/api/token", "cloudflare_path_messages": "/api/mails", - "defaultDomains": "你的收信域名.com" + "defaultDomains": "example.com" } ``` -### Cloudflare 临时邮箱 admin 模式(可选) +#### Admin 创建模式 -如果使用 `dreamhunter2333/cloudflare_temp_email` 且匿名 `/api/new_address` 开启了 Turnstile,可以改用 admin 创建邮箱接口: +当匿名 `/api/new_address` 受 Turnstile 限制时,可使用: ```json { @@ -157,80 +220,89 @@ cp config.example.json config.json "cloudflare_auth_mode": "x-admin-auth", "cloudflare_path_accounts": "/admin/new_address", "cloudflare_path_messages": "/api/mails", - "defaultDomains": "你的收信域名.com" + "defaultDomains": "example.com" } ``` -创建邮箱会使用 `x-admin-auth` 调用 `/admin/new_address`,后续收件仍使用接口返回的地址 JWT 调用 `/api/mails`。也就是说,admin 密码只用于创建邮箱,不用于读取邮箱邮件。 +Admin 密码只用于创建邮箱。读取邮件仍使用创建接口返回的邮箱 JWT。 -可先用调试脚本验证 admin 创建接口: +可先使用调试脚本验证接口: ```bash -python cf_mail_debug.py --api-base "https://你的-worker-api-域名" --auth-mode x-admin-auth --api-key "你的 ADMIN_PASSWORD" --create-path /admin/new_address --domain "你的收信域名.com" +python cf_mail_debug.py \ + --api-base "https://你的-worker-api-域名" \ + --auth-mode x-admin-auth \ + --api-key "你的 ADMIN_PASSWORD" \ + --create-path /admin/new_address \ + --domain "example.com" ``` -### Cloud Mail 无人收件模式(可选) +### Cloud Mail 无人收件模式 -该模式对接 `maillab/cloud-mail`,使用其“无人收件”功能:程序直接生成随机邮箱地址,不需要先在 Cloud Mail 中创建邮箱账号。 +| 配置项 | 说明 | +| --- | --- | +| `cloudmail_api_base` | Cloud Mail 站点根地址 | +| `cloudmail_public_token` | 公共收件 API Token | +| `cloudmail_domains` | 无人收件域名,多个域名用英文逗号分隔 | +| `cloudmail_path_messages` | 默认 `/api/public/emailList` | -使用前需要: - -1. 在 Cloud Mail 系统设置中开启“无人收件”。 -2. 使用管理员账号生成公共 API Token: - -```bash -curl -X POST "https://你的-Cloud-Mail-域名/api/public/genToken" \ - -H "Content-Type: application/json" \ - -d '{"email":"管理员邮箱","password":"管理员密码"}' -``` - -3. 配置本项目: +示例: ```json { "email_provider": "cloudmail", "cloudmail_api_base": "https://你的-Cloud-Mail-域名", - "cloudmail_public_token": "返回结果 data 中的 token", - "cloudmail_domains": "你的收信域名.com", + "cloudmail_public_token": "公共 API Token", + "cloudmail_domains": "example.com,example.net", "cloudmail_path_messages": "/api/public/emailList" } ``` -程序会通过 `POST /api/public/emailList` 按目标地址查询邮件。公共 Token 只从 `config.json` 读取,不会作为邮箱 credential 输出到日志或 `mail_credentials.txt`。 +Cloud Mail 模式直接生成随机地址,不预先创建邮箱账户。公共 Token 只从 `config.json` 读取,不会作为邮箱 credential 写入 `mail_credentials.txt`。 -### grok2api 远端入池配置 +### grok2api token 池 -如果开启 `grok2api_auto_add_remote`,`grok2api_remote_base` 可以填写站点根地址,也可以直接填写管理 API 地址: +| 配置项 | 说明 | +| --- | --- | +| `grok2api_auto_add_local` | 是否写入本地 token 池 | +| `grok2api_local_token_file` | 本地 `token.json` 路径;留空使用项目默认路径 | +| `grok2api_pool_name` | `ssoBasic` 或 `ssoSuper` | +| `grok2api_auto_add_remote` | 是否写入远端 token 池 | +| `grok2api_remote_base` | 站点根地址、`/admin` 或 `/admin/api` 地址 | +| `grok2api_remote_app_key` | 远端管理 API 的 app key | +| `grok2api_allow_legacy_full_save` | 是否允许旧版全量保存回退;默认关闭 | -```json -{ - "grok2api_auto_add_remote": true, - "grok2api_remote_base": "https://你的-grok2api-域名", - "grok2api_remote_app_key": "你的 app_key" -} -``` - -或: +远端入池优先尝试增量 `/tokens/add`。旧版全量保存默认关闭,以避免并发覆盖;即使显式开启,也要求远端返回 ETag,并通过 `If-Match` 保护写入。 ```json { "grok2api_auto_add_remote": true, "grok2api_remote_base": "https://你的-grok2api-域名/admin/api", - "grok2api_remote_app_key": "你的 app_key" + "grok2api_remote_app_key": "你的 app_key", + "grok2api_pool_name": "ssoBasic", + "grok2api_allow_legacy_full_save": false } ``` -程序会优先尝试 `/tokens/add`,并兼容 `/admin/api/tokens/add`;旧版全量保存接口也会兼容 `/tokens` 和 `/admin/api/tokens`。 +### CPA / xAI OIDC 导出 -`config.json` 包含个人配置和密钥,不要提交到 Git。 +| 配置项 | 说明 | +| --- | --- | +| `cpa_export_enabled` | 是否在注册成功后导出 CPA xAI OIDC 凭证 | +| `cpa_auth_dir` | 输出目录,默认 `./cpa_auths` | +| `cpa_copy_to_hotload` | 是否复制到 CLIProxyAPI auth-dir | +| `cpa_hotload_dir` | 热加载目录;仅导出开启且复制开启时必填 | +| `cpa_base_url` | CPA 凭证中的 API Base URL | +| `cpa_proxy` | CPA 专用代理;留空回退到主 `proxy` | +| `cpa_headless` | CPA 浏览器是否无头;默认建议 `false` | +| `cpa_force_standalone` | 是否使用独立 CPA 浏览器会话 | +| `cpa_mint_timeout_sec` | 浏览器授权整体超时 | +| `cpa_mint_cookie_inject` | 是否向 CPA 会话注入已取得的 cookie | +| `cpa_oidc_request_timeout_sec` | Device Authorization 请求超时 | +| `cpa_oidc_poll_timeout_sec` | 单次 token 轮询请求超时 | +| `api_reverse_tools` | 可选外部 `cpa_xai` 包目录 | -### CPA / xAI OIDC 导出(可选) - -当 `cpa_export_enabled=true` 时,程序会在**账号已经注册成功、SSO 已保存**之后,额外发起一次 xAI Device Authorization,自动批准授权并导出 `xai-*.json`。 - -这条线路是附加功能,不会替代原有的 SSO 保存流程。即使 OIDC 导出失败,原账号与 SSO 结果仍会保留。 - -推荐最小配置: +最小配置: ```json { @@ -238,101 +310,221 @@ curl -X POST "https://你的-Cloud-Mail-域名/api/public/genToken" \ "cpa_auth_dir": "./cpa_auths", "cpa_base_url": "https://cli-chat-proxy.grok.com/v1", "cpa_proxy": "", - "cpa_headless": false + "cpa_headless": false, + "cpa_force_standalone": true, + "cpa_mint_cookie_inject": true } ``` -如需让 CLIProxyAPI 自动热加载,可额外填写: +CPA 浏览器直接复用 `browser_runtime.py` 的 Chromium options 和 `cpa_xai/proxyutil.py` 的代理桥,不会反向导入主程序或创建第二份主模块全局状态。 -```json -{ - "cpa_copy_to_hotload": true, - "cpa_hotload_dir": "/path/to/cli-proxy-api/auth-dir" -} -``` +## 运行方式 -## 运行 - -### CLI 模式 - -CLI 模式不会启动 Tk GUI,但注册流程仍会打开 Chromium/Chrome 浏览器页面。 - -```bash -python grok_register_ttk.py cli -``` - -看到提示后输入: - -```text -start -``` - -停止任务: - -```text -Ctrl+C -``` - -CLI 模式适合长时间批量运行。程序每成功注册 5 个账号会关闭浏览器、清理运行时对象并重新启动浏览器,降低长任务内存占用。 - -### GUI 模式 +### GUI ```bash python grok_register_ttk.py ``` -GUI 模式会打开 Tkinter 窗口,适合手动调整配置和观察日志。 +GUI 启动时读取配置并执行结构校验。填写配置后点击“开始注册”,程序会执行完整运行校验,只保存一次配置,然后启动后台线程。 -## 输出文件 +每个新批次开始前,成功、失败、待恢复和后处理警告四项统计都会全部清零。 -运行过程中会生成: +### CLI -- `accounts_*.txt`:成功账号、密码和 SSO token。 -- `mail_credentials.txt`:临时邮箱凭证。 -- `cpa_auths/xai-*.json`:可选导出的 CPA xAI OAuth 凭证。 -- `cpa_auths/cpa_auth_failed.txt`:OIDC 导出失败记录。 -- `screenshots/`:CPA/OIDC 浏览器失败调试截图,已被 `.gitignore` 忽略。 -- `*.log`:可选日志文件。 +以下命令等价: -这些文件包含敏感信息,已被 `.gitignore` 忽略。 +```bash +python grok_register_ttk.py cli +python grok_register_ttk.py start +python grok_register_ttk.py --cli +``` -## 稳定性机制 +CLI 读取 `config.json` 中的 `register_count`,通过运行校验后提示: -- 每个账号结束后重启浏览器。 -- 每成功 5 个账号执行一次内存清理。 -- CLI 模式支持 `Ctrl+C` 中断并清理浏览器。 -- 最终页长时间无变化时自动重试当前账号。 -- 验证码未收到时自动更换邮箱重试。 +```text +> start +``` -## 常见问题 +输入 `start` 才会开始。按 `Ctrl+C` 可请求停止并执行最终清理。 -### CLI 模式为什么还会打开浏览器? +> CLI 只是不启动 Tk GUI,注册过程仍会打开 Chromium / Chrome。 -CLI 模式只是不启动 Tk GUI。注册页、Turnstile、验证码提交和 SSO cookie 获取仍依赖真实浏览器环境。 +### 恢复 pending 结果 -### NSFW 开启失败怎么办? +```bash +python grok_register_ttk.py retry-pending [输出文件] +``` -如果日志显示 `Cloudflare 防护拦截,HTTP 403`,说明请求被目标站点防护拦截。程序会继续保存账号和写入 grok2api。 +示例: -### GUI 显示的数量和配置不同? +```bash +python grok_register_ttk.py retry-pending accounts_20260715_120000.txt.pending.jsonl +``` -GUI 数量控件可能有上限。CLI 模式直接读取 `config.json` 中的 `register_count`。 +指定其他输出文件: -## 目录结构 +```bash +python grok_register_ttk.py retry-pending \ + accounts_20260715_120000.txt.pending.jsonl \ + recovered_accounts.txt +``` + +程序会拒绝把 pending 输入文件本身作为输出文件。 + +## 输出与 pending 恢复 + +运行过程中可能生成: + +| 文件 | 内容 | +| --- | --- | +| `accounts_*.txt` | 已成功保存的账号、密码和 SSO token | +| `mail_credentials.txt` | 临时邮箱地址与邮箱凭证 | +| `*.pending.jsonl` | 已注册但主结果文件未成功写入的账号 | +| `*.pending.jsonl.lock` | pending 恢复独占锁 | +| 本地 `token.json` | 可选 grok2api 本地池 | +| `cpa_auths/xai-*.json` | 可选 CPA xAI OIDC 凭证 | +| `cpa_auths/cpa_auth_failed.txt` | CPA 导出失败记录 | +| `screenshots/` | CPA 浏览器失败调试截图 | + +这些文件可能含有账号、密码、JWT、SSO token 或 OAuth 凭证。相关路径已加入 `.gitignore`,仍应妥善限制本机文件权限和备份范围。 + +pending 恢复具有以下保护: + +- 使用 `filelock` 对同一 pending 文件加独占锁; +- 读取、恢复、重写或删除 pending 文件均在锁内完成; +- 主结果文件按 `email+sso` 去重; +- 已存在的记录直接视为恢复成功; +- pending 文件使用临时文件和原子替换更新; +- 输入路径与输出路径相同会被拒绝。 + +因此进程在“账号已追加、pending 尚未更新”之间中断后,重复执行恢复不会重复写入同一个账号。 + +## 稳定性与安全机制 + +### 批量流程 + +- 邮箱验证码失败时可更换邮箱重试。 +- 页面流程卡住时按当前账号槽位重试,达到上限后才计为失败。 +- 每个账号之间重启或重新创建浏览器。 +- 每成功 5 个账号默认执行一次运行时清理。 +- 定期清理失败只记录警告,不修改账号统计。 +- 用户在账号间取消时设置批次 `cancelled` 状态并正常结束。 +- 最终清理异常不会覆盖原始任务异常。 +- GUI observer 异常不会终止批量流程。 + +### 文件写入 + +- 配置、本地 token 池和 pending 更新采用临时文件加原子替换。 +- 本地 token 池使用文件锁,损坏 JSON 不会被静默覆盖。 +- 已存在 token 会被去重。 +- 尽可能将敏感输出权限设置为仅当前用户可读写。 + +### 后处理隔离 + +- 主账号保存完成后,token 入池和 CPA 导出分别捕获异常。 +- 一个后处理步骤失败不会阻止另一个步骤执行。 +- 后处理失败不会把账号重新归类为注册失败。 + +## 项目架构 ```text . -├── grok_register_ttk.py # 主程序(GUI / CLI) -├── cpa_export.py # 注册成功后的 CPA/OIDC 导出入口 -├── cpa_xai/ # xAI Device Auth、浏览器授权和凭证写入模块 -├── cf_mail_debug.py # Cloudflare 邮箱调试工具 -├── config.example.json # 配置示例 -├── requirements.txt # Python 依赖 -├── tests/ # 现有测试用例 -├── assets/ # README 资源 +├── grok_register_ttk.py # GUI、CLI、参数入口和兼容适配层 +├── registration_flow.py # GUI / CLI 唯一批量编排入口 +├── app_config.py # 默认配置、加载保存、结构校验与运行校验 +├── account_outputs.py # 账号输出、pending、token 池和原子写入 +├── mail_service.py # DuckMail、YYDS、Cloudflare、Cloud Mail +├── browser_runtime.py # HTTP、代理和 Chromium options +├── registration_browser.py # 主注册浏览器生命周期与页面自动化 +├── cf_mail_debug.py # Cloudflare 邮箱调试 CLI +├── cpa_export.py # CPA/OIDC 导出兼容入口 +├── cpa_xai/ +│ ├── browser_session.py # CPA 浏览器创建、复用、cookie 与清理 +│ ├── browser_confirm.py # 登录、授权页面与 mint 编排 +│ ├── oauth_device.py # Device Authorization 与 token 轮询 +│ ├── proxyutil.py # 项目唯一认证代理桥实现 +│ ├── mint.py # 凭证 mint 流程 +│ ├── schema.py # CPA 输出结构 +│ └── writer.py # 凭证文件写入 +├── config.example.json # 完整配置示例 +├── requirements.txt # Python 依赖 +├── tests/ # 单元与兼容回归测试 +├── turnstilePatch/ # 浏览器扩展资源 +├── assets/ # README 资源 └── README.md ``` +`grok_register_ttk.py` 暂时保留旧公开函数和部分全局状态的兼容代理,方便已有脚本继续调用。新代码应优先直接导入职责模块,避免继续扩大动态全局注入范围。 + +## 测试 + +运行完整测试: + +```bash +python -m unittest discover -s tests -p "test_*.py" +``` + +检查全部 Python 文件语法: + +```bash +python -m compileall -q . +``` + +重要回归覆盖包括: + +- Python 3.9 类型兼容; +- 注册地址和 redirect 参数; +- 配置对象在 `load_config()` 后仍保持共享身份; +- GUI 新批次四项统计清零; +- 旧浏览器全局状态读取和写入兼容; +- pending 幂等恢复、路径冲突和并发锁; +- Cloudflare admin 创建与非目标邮件过滤; +- 四种邮箱正文标准化; +- CPA 浏览器生命周期、取消和清理; +- OAuth discovery、重试、`slow_down` 和非 JSON 响应; +- 清理、取消和后处理异常边界。 + +提交涉及配置、邮箱、浏览器、输出或 CPA 的修改前,建议至少运行 `compileall` 和完整 unittest。 + +## 常见问题 + +### CLI 为什么仍然打开浏览器? + +CLI 仅省略 Tk GUI。注册页交互、Turnstile、验证码提交和 SSO cookie 获取仍依赖真实 Chromium 环境。 + +### GUI 无法启动怎么办? + +确认当前 Python 包含 Tkinter。Linux 发行版可能需要单独安装系统包,例如 `python3-tk`。也可以改用: + +```bash +python grok_register_ttk.py cli +``` + +### 为什么配置文件不完整时 GUI 仍能打开? + +这是预期行为。GUI 启动只做结构校验,方便在界面中修正服务商配置;点击开始时才做运行校验。 + +### 为什么账号成功数少于实际注册完成数? + +“成功”表示账号注册完成且主结果文件已经保存。注册完成但主文件写入失败的账号会显示在“待恢复”,并写入 pending 文件。 + +### 什么是后处理警告? + +账号已经保存,但 grok2api 入池或 CPA 导出至少一项失败。账号本身仍属于成功,不需要重新注册。 + +### NSFW 开启失败会丢失账号吗? + +不会。NSFW 是可选步骤,失败会记录警告并继续保存账号。 + +### 远端 grok2api 为什么拒绝旧版全量写入? + +全量读改写在多进程环境中可能覆盖其他实例刚写入的 token。项目默认只接受增量接口;显式允许旧版回退时仍要求 ETag 并使用条件写入。 + +### CPA 热加载目录为什么没有配置也能启动? + +只有同时启用 `cpa_export_enabled=true` 和 `cpa_copy_to_hotload=true` 时,`cpa_hotload_dir` 才是必填项。 + ## License [MIT](LICENSE).