Files
AutoDoneTeam/auto_register.py
2026-01-11 18:31:12 +08:00

404 lines
14 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""自动化注册 OpenAI 账号(使用临时邮箱)
使用方式:
python auto_register.py # 注册 1 个账号
python auto_register.py --count 10 # 注册 10 个账号
python auto_register.py --password mypass # 指定密码
"""
import sys
import argparse
import secrets
import json
from typing import List, Dict
from modules.register import OpenAIRegistrar
from modules.tempmail import TempMailClient
from modules.iban_generator import GermanIbanGenerator
from config import TEMPMAIL_CONFIG, DEBUG
def generate_random_password(length: int = 16) -> str:
"""生成随机密码"""
# 包含大小写字母、数字、特殊字符
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*'
return ''.join(secrets.choice(chars) for _ in range(length))
def register_single_account(
tempmail_client: TempMailClient,
password: str = None,
generate_billing: bool = False,
add_payment: bool = False,
payment_info: Dict = None
) -> Dict:
"""注册单个账号
Args:
tempmail_client: 临时邮箱客户端
password: 密码None 则自动生成)
generate_billing: 是否生成欧洲账单 URL
add_payment: 是否添加支付方式
payment_info: 支付信息字典(包含 iban, name, address 等)
Returns:
注册结果(包含可选的 checkout_url 和 payment_status
"""
# 生成密码(如果未指定)
if not password:
password = generate_random_password()
# 创建注册器
registrar = OpenAIRegistrar(tempmail_client=tempmail_client)
# 执行注册(自动生成邮箱 + 验证)
result = registrar.register_with_auto_email(password)
# 如果注册成功且需要生成账单
if result.get('success') and generate_billing:
try:
# Step 5: 获取 access token
access_token = registrar._step5_get_access_token()
# 生成欧洲账单 URL
from modules.billing import EUBillingGenerator
billing_gen = EUBillingGenerator()
billing_result = billing_gen.generate_checkout_url(access_token)
if billing_result.success:
result['checkout_url'] = billing_result.checkout_url
if DEBUG:
print(f"✅ EU billing URL generated")
print(f" URL: {billing_result.checkout_url[:80]}...")
# 如果需要自动添加支付方式
if add_payment and payment_info:
try:
if DEBUG:
print(f"\n🔐 Adding payment method...")
payment_result = registrar.add_payment_method(
checkout_session_url=billing_result.checkout_url,
iban=payment_info.get('iban', 'DE89370400440532013000'),
name=payment_info.get('name', 'John Doe'),
email=result['email'], # 使用注册的邮箱
address_line1=payment_info.get('address_line1', '123 Main Street'),
city=payment_info.get('city', 'New York'),
postal_code=payment_info.get('postal_code', '10001'),
state=payment_info.get('state', 'NY'),
country=payment_info.get('country', 'US')
)
result['payment_status'] = payment_result
if payment_result.get('success'):
if DEBUG:
print(f"✅ Payment method added successfully")
else:
if DEBUG:
print(f"⚠️ Payment method failed: {payment_result.get('error')}")
except Exception as e:
result['payment_error'] = str(e)
if DEBUG:
print(f"❌ Payment exception: {e}")
else:
result['billing_error'] = billing_result.error
if DEBUG:
print(f"⚠️ Billing generation failed: {billing_result.error}")
except Exception as e:
result['billing_error'] = str(e)
if DEBUG:
print(f"❌ Billing generation exception: {e}")
return result
def register_multiple_accounts(
count: int,
password: str = None,
save_to_file: str = None,
generate_billing: bool = False,
add_payment: bool = False,
payment_info: Dict = None
):
"""批量注册账号
Args:
count: 注册数量
password: 密码None 则每个账号生成不同密码)
save_to_file: 保存成功账号的文件路径JSON 格式)
generate_billing: 是否生成欧洲账单 URL
add_payment: 是否自动添加支付方式
payment_info: 支付信息字典
"""
print(f"\n{'='*60}")
print(f"Starting batch registration: {count} accounts")
if generate_billing:
print(f"EU Billing: Enabled")
if add_payment:
print(f"Payment: Enabled (auto-generating IBANs)")
print(f"{'='*60}\n")
# 初始化IBAN生成器如果需要支付
iban_generator = None
if add_payment:
iban_generator = GermanIbanGenerator()
if DEBUG:
print(f"✅ IBAN Generator initialized")
# 检查临时邮箱配置
api_base_url = TEMPMAIL_CONFIG.get('api_base_url')
username = TEMPMAIL_CONFIG.get('username')
password_cfg = TEMPMAIL_CONFIG.get('password')
admin_token = TEMPMAIL_CONFIG.get('admin_token')
if not api_base_url or 'your.tempmail.domain' in api_base_url:
print("❌ Error: TEMPMAIL_CONFIG.api_base_url not configured in config.py")
sys.exit(1)
# 检查认证方式:优先用户名密码,其次 Token
if username and password_cfg:
if 'your_password_here' in password_cfg:
print("❌ Error: TEMPMAIL_CONFIG.password not configured in config.py")
print(" Please set username and password")
sys.exit(1)
# 初始化临时邮箱客户端(用户名密码方式)
tempmail_client = TempMailClient(
api_base_url=api_base_url,
username=username,
password=password_cfg
)
elif admin_token:
if 'your_jwt_token_here' in admin_token:
print("❌ Error: TEMPMAIL_CONFIG.admin_token not configured in config.py")
sys.exit(1)
# 初始化临时邮箱客户端Token 方式)
tempmail_client = TempMailClient(
api_base_url=api_base_url,
admin_token=admin_token
)
else:
print("❌ Error: TEMPMAIL_CONFIG not properly configured in config.py")
print(" Please provide either (username, password) or admin_token")
sys.exit(1)
# 统计
success_accounts = []
failed_accounts = []
# 批量注册
for i in range(1, count + 1):
print(f"\n{''*60}")
print(f"[{i}/{count}] Registering account #{i}...")
print(f"{''*60}")
try:
# 如果需要自动生成IBAN
current_payment_info = payment_info
if add_payment and iban_generator:
# 为每个账号生成新的IBAN
generated_iban = iban_generator.generate(1)[0]
# 复制payment_info并更新IBAN
current_payment_info = payment_info.copy() if payment_info else {}
current_payment_info['iban'] = generated_iban
if DEBUG:
print(f"🔢 Generated IBAN: {generated_iban}")
# 注册单个账号
result = register_single_account(
tempmail_client=tempmail_client,
password=password, # None 则自动生成
generate_billing=generate_billing,
add_payment=add_payment,
payment_info=current_payment_info
)
if result.get('success'):
account_info = {
'email': result['email'],
'password': result['password'],
'verified': result.get('verified', False),
}
# 如果生成了账单 URL添加到输出
if 'checkout_url' in result:
account_info['checkout_url'] = result['checkout_url']
# 如果添加了支付方式记录状态和IBAN
if 'payment_status' in result:
account_info['payment_added'] = result['payment_status'].get('success', False)
# 记录使用的IBAN
if current_payment_info and 'iban' in current_payment_info:
account_info['iban'] = current_payment_info['iban']
success_accounts.append(account_info)
print(f"\n✅ Account #{i} registered successfully!")
print(f" Email: {account_info['email']}")
print(f" Password: {account_info['password']}")
# 如果有账单 URL打印出来
if 'checkout_url' in account_info:
print(f" Checkout URL: {account_info['checkout_url']}")
# 如果添加了支付
if 'payment_added' in account_info:
if account_info['payment_added']:
print(f" Payment: ✅ Added")
if 'iban' in account_info:
print(f" IBAN: {account_info['iban']}")
else:
print(f" Payment: ❌ Failed")
else:
failed_info = {
'email': result.get('email', 'N/A'),
'error': result.get('error', 'Unknown error'),
}
failed_accounts.append(failed_info)
print(f"\n❌ Account #{i} failed")
print(f" Email: {failed_info['email']}")
print(f" Error: {failed_info['error']}")
except KeyboardInterrupt:
print(f"\n\n❌ Interrupted by user at account #{i}")
break
except Exception as e:
print(f"\n❌ Unexpected error at account #{i}: {e}")
failed_accounts.append({
'email': 'N/A',
'error': str(e),
})
# 打印最终统计
print(f"\n{'='*60}")
print(f"BATCH REGISTRATION COMPLETE")
print(f"{'='*60}")
print(f"Total: {count} accounts")
print(f"Success: {len(success_accounts)} accounts ✅")
print(f"Failed: {len(failed_accounts)} accounts ❌")
print(f"{'='*60}\n")
# 保存成功的账号
if success_accounts:
if save_to_file:
output_file = save_to_file
else:
output_file = "registered_accounts.json"
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(success_accounts, f, indent=2, ensure_ascii=False)
print(f"✅ Saved {len(success_accounts)} accounts to: {output_file}")
# 打印成功账号列表
if success_accounts:
print(f"\n{''*60}")
print(f"SUCCESSFUL ACCOUNTS:")
print(f"{''*60}")
for idx, acc in enumerate(success_accounts, 1):
print(f"{idx}. {acc['email']} | {acc['password']}")
print(f"{''*60}\n")
def main():
parser = argparse.ArgumentParser(
description='自动化注册 OpenAI 账号(使用临时邮箱)',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
示例:
python auto_register.py # 注册 1 个账号
python auto_register.py --count 10 # 注册 10 个账号
python auto_register.py --password mypass # 指定密码(所有账号相同)
python auto_register.py -c 5 -o out.json # 注册 5 个,保存到 out.json
python auto_register.py --eu-billing --add-payment # 生成账单并自动添加支付方式
"""
)
parser.add_argument(
'-c', '--count',
type=int,
default=1,
help='注册账号数量(默认: 1'
)
parser.add_argument(
'-p', '--password',
type=str,
default=None,
help='指定密码(默认: 自动生成随机密码)'
)
parser.add_argument(
'-o', '--output',
type=str,
default=None,
help='保存成功账号的 JSON 文件路径(默认: registered_accounts.json'
)
parser.add_argument(
'--eu-billing',
action='store_true',
help='注册后自动生成欧洲账单 checkout URL'
)
parser.add_argument(
'--add-payment',
action='store_true',
help='自动添加 Stripe 支付方式自动生成德国IBAN需要同时启用 --eu-billing'
)
# 支付信息参数除了IBAN其他可选
parser.add_argument('--name', type=str, default='John Doe', help='持卡人姓名(默认: John Doe')
parser.add_argument('--address', type=str, default='123 Main Street', help='街道地址(默认: 123 Main Street')
parser.add_argument('--city', type=str, default='New York', help='城市(默认: New York')
parser.add_argument('--postal-code', type=str, default='10001', help='邮编(默认: 10001')
parser.add_argument('--state', type=str, default='NY', help='州/省(默认: NY')
parser.add_argument('--country', type=str, default='US', help='国家代码(默认: US')
args = parser.parse_args()
# 如果启用支付但没启用账单,给出警告
if args.add_payment and not args.eu_billing:
print("⚠️ Warning: --add-payment requires --eu-billing to be enabled")
print(" Enabling --eu-billing automatically...")
args.eu_billing = True
# 准备支付信息不包含IBAN会自动生成
payment_info = None
if args.add_payment:
payment_info = {
# IBAN会在循环中为每个账号自动生成
'name': args.name,
'address_line1': args.address,
'city': args.city,
'postal_code': args.postal_code,
'state': args.state,
'country': args.country
}
# 执行批量注册
register_multiple_accounts(
count=args.count,
password=args.password,
save_to_file=args.output,
generate_billing=args.eu_billing,
add_payment=args.add_payment,
payment_info=payment_info
)
if __name__ == '__main__':
main()