diff --git a/README.md b/README.md index e637143..d133cb8 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [](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 凭证导出。
@@ -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