From 79c3eb733c1d192127fbab42f0475a7b263220e4 Mon Sep 17 00:00:00 2001 From: kyx236 Date: Fri, 30 Jan 2026 12:24:40 +0800 Subject: [PATCH] feat(registration): Add email retry mechanism for API registration failures - Add `allow_fallback` parameter to `register_openai_account_auto()` to control fallback behavior - Return `"retry_new_email"` status when API registration fails without fallback enabled - Return `"domain_blacklisted"` status when domain is blacklisted during registration - Update `register_only()` to handle and propagate `"retry_new_email"` status - Update `register_and_authorize()` to handle and propagate `"retry_new_email"` status - Add retry logic in `process_accounts()` to regenerate email and reinvite on API failures - Add retry logic in `_process_single_account_worker()` to regenerate email and reinvite on API failures - Improve error handling to distinguish between domain blacklist and API failures requiring email regeneration --- browser_automation.py | 44 ++++++++++++++++++++++++++++++++++--------- run.py | 40 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 9 deletions(-) diff --git a/browser_automation.py b/browser_automation.py index 09670ed..8da40fb 100644 --- a/browser_automation.py +++ b/browser_automation.py @@ -1208,11 +1208,10 @@ def register_openai_account_api(email: str, password: str, proxy: str = None, def register_openai_account_auto(page, email: str, password: str, use_api: bool = True, - proxy: str = None, team_name: str = None) -> bool: + proxy: str = None, team_name: str = None, + allow_fallback: bool = False) -> bool: """自动选择模式注册 OpenAI 账号 - 优先使用 API 模式,失败则回退到浏览器模式 - Args: page: 浏览器实例 (用于浏览器模式回退) email: 邮箱地址 @@ -1220,10 +1219,15 @@ def register_openai_account_auto(page, email: str, password: str, use_api: bool use_api: 是否优先使用 API 模式 proxy: 代理地址 (API 模式使用) team_name: Team 名称 (用于验证码超时时邀请新邮箱) + allow_fallback: 是否允许 API 失败后回退到浏览器模式 (默认 False) Returns: - bool: 是否成功 - str: 如果返回 "new_email:xxx@xxx.com:password",表示使用了新邮箱 + bool/str: + - True: 成功 + - False: 失败 + - "retry_new_email": API 失败,需要重新生成邮箱重试 + - "new_email:xxx@xxx.com:password": 使用了新邮箱 + - "domain_blacklisted": 域名被列入黑名单 """ # 如果启用 API 模式且可用 if use_api and API_MODE_AVAILABLE: @@ -1233,12 +1237,23 @@ def register_openai_account_auto(page, email: str, password: str, use_api: bool elif isinstance(result, str) and result.startswith("new_email:"): # 使用了新邮箱,返回新邮箱信息 return result + elif result == "domain_blacklisted": + return "domain_blacklisted" elif result is False: + if not allow_fallback: + log.warning("API 模式注册失败,需要重新生成邮箱重试") + return "retry_new_email" log.warning("API 模式注册失败,回退到浏览器模式...") - # result is None 表示 API 模式不可用,直接使用浏览器模式 + # result is None 表示 API 模式不可用 + elif result is None and not allow_fallback: + log.warning("API 模式不可用,需要重新生成邮箱重试") + return "retry_new_email" - # 使用浏览器模式 - return register_openai_account(page, email, password) + # 如果不使用 API 或允许回退,使用浏览器模式 + if not use_api or allow_fallback: + return register_openai_account(page, email, password) + + return "retry_new_email" def register_openai_account(page, email: str, password: str) -> bool: @@ -2284,6 +2299,7 @@ def register_only(email: str, password: str, use_api_register: bool = True) -> s str: 注册结果 - "success": 注册成功 - "domain_blacklisted": 域名被列入黑名单 + - "retry_new_email": API 失败,需要重新生成邮箱重试 - "failed": 注册失败 """ with browser_context_with_retry(max_browser_retries=2) as ctx: @@ -2300,6 +2316,11 @@ def register_only(email: str, password: str, use_api_register: bool = True) -> s ctx.stop() return "domain_blacklisted" + # 检查是否需要重新生成邮箱 + if register_result == "retry_new_email": + ctx.stop() + return "retry_new_email" + if not register_result: if attempt < ctx.max_retries - 1: log.warning("注册失败,准备重试...") @@ -2330,7 +2351,7 @@ def register_and_authorize(email: str, password: str, use_api_register: bool = T Returns: tuple: (register_success, codex_data, new_email_info) - - register_success: True/False/"domain_blacklisted" + - register_success: True/False/"domain_blacklisted"/"retry_new_email" - CRS 模式: codex_data 包含 tokens - CPA/S2A 模式: codex_data 为 None (后台自动处理) - new_email_info: 如果使用了新邮箱,返回 {"email": "xxx", "password": "xxx"},否则为 None @@ -2364,6 +2385,11 @@ def register_and_authorize(email: str, password: str, use_api_register: bool = T ctx.stop() return "domain_blacklisted", None, None + # 检查是否需要重新生成邮箱 + if register_result == "retry_new_email": + ctx.stop() + return "retry_new_email", None, None + # 检查是否使用了新邮箱 if isinstance(register_result, str) and register_result.startswith("new_email:"): # 解析新邮箱信息: "new_email:xxx@xxx.com:password" diff --git a/run.py b/run.py index 4b55890..1de6481 100644 --- a/run.py +++ b/run.py @@ -453,6 +453,29 @@ def process_accounts(accounts: list, team_name: str, team_index: int = 0, log.error("无法创建有效的新邮箱") continue # 跳过当前账号,继续下一个 + + # 检查是否需要重新生成邮箱重试 (API 模式失败) + if register_success == "retry_new_email": + log.warning("API 注册失败,重新生成邮箱重试...") + + # 从 tracker 中移除旧邮箱 + remove_account_from_tracker(_tracker, team_name, email) + save_team_tracker(_tracker) + + # 创建新邮箱 + new_email, new_password = unified_create_email() + if new_email and not is_email_blacklisted(new_email): + # 邀请新邮箱 + if invite_single_to_team(new_email, _get_team_by_name(team_name)): + add_account_with_password(_tracker, team_name, new_email, new_password, "invited") + save_team_tracker(_tracker) + log.success(f"已创建新邮箱: {new_email},将在下次运行时处理") + else: + log.error("新邮箱邀请失败") + else: + log.error("无法创建有效的新邮箱") + + continue # 跳过当前账号,继续下一个 if register_success and register_success != "domain_blacklisted": update_account_status(_tracker, team_name, email, "registered") @@ -691,6 +714,23 @@ def _process_single_account_worker( remove_account_from_tracker(_tracker, team_name, email) save_team_tracker(_tracker) return result + + # 检查是否需要重新生成邮箱重试 (API 模式失败) + if register_success == "retry_new_email": + log.warning(f"[Worker-{worker_id}] API 注册失败,重新生成邮箱重试...") + with _tracker_lock: + remove_account_from_tracker(_tracker, team_name, email) + save_team_tracker(_tracker) + + # 创建新邮箱并邀请 + new_email, new_password = unified_create_email() + if new_email and not is_email_blacklisted(new_email): + if invite_single_to_team(new_email, _get_team_by_name(team_name)): + with _tracker_lock: + add_account_with_password(_tracker, team_name, new_email, new_password, "invited") + save_team_tracker(_tracker) + log.success(f"[Worker-{worker_id}] 已创建新邮箱: {new_email}") + return result if register_success and register_success != "domain_blacklisted": with _tracker_lock: