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
This commit is contained in:
@@ -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,
|
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 账号
|
"""自动选择模式注册 OpenAI 账号
|
||||||
|
|
||||||
优先使用 API 模式,失败则回退到浏览器模式
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
page: 浏览器实例 (用于浏览器模式回退)
|
page: 浏览器实例 (用于浏览器模式回退)
|
||||||
email: 邮箱地址
|
email: 邮箱地址
|
||||||
@@ -1220,10 +1219,15 @@ def register_openai_account_auto(page, email: str, password: str, use_api: bool
|
|||||||
use_api: 是否优先使用 API 模式
|
use_api: 是否优先使用 API 模式
|
||||||
proxy: 代理地址 (API 模式使用)
|
proxy: 代理地址 (API 模式使用)
|
||||||
team_name: Team 名称 (用于验证码超时时邀请新邮箱)
|
team_name: Team 名称 (用于验证码超时时邀请新邮箱)
|
||||||
|
allow_fallback: 是否允许 API 失败后回退到浏览器模式 (默认 False)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: 是否成功
|
bool/str:
|
||||||
str: 如果返回 "new_email:xxx@xxx.com:password",表示使用了新邮箱
|
- True: 成功
|
||||||
|
- False: 失败
|
||||||
|
- "retry_new_email": API 失败,需要重新生成邮箱重试
|
||||||
|
- "new_email:xxx@xxx.com:password": 使用了新邮箱
|
||||||
|
- "domain_blacklisted": 域名被列入黑名单
|
||||||
"""
|
"""
|
||||||
# 如果启用 API 模式且可用
|
# 如果启用 API 模式且可用
|
||||||
if use_api and API_MODE_AVAILABLE:
|
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:"):
|
elif isinstance(result, str) and result.startswith("new_email:"):
|
||||||
# 使用了新邮箱,返回新邮箱信息
|
# 使用了新邮箱,返回新邮箱信息
|
||||||
return result
|
return result
|
||||||
|
elif result == "domain_blacklisted":
|
||||||
|
return "domain_blacklisted"
|
||||||
elif result is False:
|
elif result is False:
|
||||||
|
if not allow_fallback:
|
||||||
|
log.warning("API 模式注册失败,需要重新生成邮箱重试")
|
||||||
|
return "retry_new_email"
|
||||||
log.warning("API 模式注册失败,回退到浏览器模式...")
|
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"
|
||||||
|
|
||||||
# 使用浏览器模式
|
# 如果不使用 API 或允许回退,使用浏览器模式
|
||||||
return register_openai_account(page, email, password)
|
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:
|
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: 注册结果
|
str: 注册结果
|
||||||
- "success": 注册成功
|
- "success": 注册成功
|
||||||
- "domain_blacklisted": 域名被列入黑名单
|
- "domain_blacklisted": 域名被列入黑名单
|
||||||
|
- "retry_new_email": API 失败,需要重新生成邮箱重试
|
||||||
- "failed": 注册失败
|
- "failed": 注册失败
|
||||||
"""
|
"""
|
||||||
with browser_context_with_retry(max_browser_retries=2) as ctx:
|
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()
|
ctx.stop()
|
||||||
return "domain_blacklisted"
|
return "domain_blacklisted"
|
||||||
|
|
||||||
|
# 检查是否需要重新生成邮箱
|
||||||
|
if register_result == "retry_new_email":
|
||||||
|
ctx.stop()
|
||||||
|
return "retry_new_email"
|
||||||
|
|
||||||
if not register_result:
|
if not register_result:
|
||||||
if attempt < ctx.max_retries - 1:
|
if attempt < ctx.max_retries - 1:
|
||||||
log.warning("注册失败,准备重试...")
|
log.warning("注册失败,准备重试...")
|
||||||
@@ -2330,7 +2351,7 @@ def register_and_authorize(email: str, password: str, use_api_register: bool = T
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
tuple: (register_success, codex_data, new_email_info)
|
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
|
- CRS 模式: codex_data 包含 tokens
|
||||||
- CPA/S2A 模式: codex_data 为 None (后台自动处理)
|
- CPA/S2A 模式: codex_data 为 None (后台自动处理)
|
||||||
- new_email_info: 如果使用了新邮箱,返回 {"email": "xxx", "password": "xxx"},否则为 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()
|
ctx.stop()
|
||||||
return "domain_blacklisted", None, None
|
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:"):
|
if isinstance(register_result, str) and register_result.startswith("new_email:"):
|
||||||
# 解析新邮箱信息: "new_email:xxx@xxx.com:password"
|
# 解析新邮箱信息: "new_email:xxx@xxx.com:password"
|
||||||
|
|||||||
40
run.py
40
run.py
@@ -453,6 +453,29 @@ def process_accounts(accounts: list, team_name: str, team_index: int = 0,
|
|||||||
log.error("无法创建有效的新邮箱")
|
log.error("无法创建有效的新邮箱")
|
||||||
|
|
||||||
continue # 跳过当前账号,继续下一个
|
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":
|
if register_success and register_success != "domain_blacklisted":
|
||||||
update_account_status(_tracker, team_name, email, "registered")
|
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)
|
remove_account_from_tracker(_tracker, team_name, email)
|
||||||
save_team_tracker(_tracker)
|
save_team_tracker(_tracker)
|
||||||
return result
|
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":
|
if register_success and register_success != "domain_blacklisted":
|
||||||
with _tracker_lock:
|
with _tracker_lock:
|
||||||
|
|||||||
Reference in New Issue
Block a user