315 lines
11 KiB
Python
315 lines
11 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
完整注册流程封装
|
||
包含:注册 → Access Token → 账单生成 → 支付 → Notion 保存
|
||
"""
|
||
|
||
import os
|
||
from typing import Dict, Optional
|
||
from modules.register import OpenAIRegistrar
|
||
from modules.tempmail import TempMailClient
|
||
from modules.billing import EUBillingGenerator
|
||
from modules.iban_generator import GermanIbanGenerator
|
||
from modules.notion_client import NotionClient
|
||
from modules.delay_utils import HumanDelay
|
||
from modules.data_generator import generate_payment_info
|
||
from config import TEMPMAIL_CONFIG, DEBUG, DELAY_CONFIG
|
||
|
||
|
||
class CompleteRegistrationFlow:
|
||
"""完整注册流程管理器"""
|
||
|
||
def __init__(self, tempmail_client: TempMailClient):
|
||
"""
|
||
初始化流程管理器
|
||
|
||
Args:
|
||
tempmail_client: 临时邮箱客户端实例
|
||
"""
|
||
self.tempmail_client = tempmail_client
|
||
self.registrar = None
|
||
self.notion_client = None
|
||
|
||
# 检查并初始化 Notion 客户端
|
||
notion_token = os.environ.get('NOTION_TOKEN')
|
||
database_id = os.environ.get('DATA_SOURCE_ID')
|
||
|
||
if notion_token and database_id:
|
||
try:
|
||
self.notion_client = NotionClient(
|
||
token=notion_token,
|
||
database_id=database_id
|
||
)
|
||
if DEBUG:
|
||
print(f"✅ Notion 客户端初始化成功")
|
||
except Exception as e:
|
||
if DEBUG:
|
||
print(f"⚠️ Notion 客户端初始化失败: {e}")
|
||
|
||
def register_basic(self, password: str) -> Dict:
|
||
"""
|
||
基础注册(仅注册+验证邮箱)
|
||
|
||
Args:
|
||
password: 账号密码
|
||
|
||
Returns:
|
||
注册结果字典
|
||
"""
|
||
try:
|
||
# 初始化注册器
|
||
self.registrar = OpenAIRegistrar(tempmail_client=self.tempmail_client)
|
||
|
||
# 执行注册
|
||
result = self.registrar.register_with_auto_email(password=password)
|
||
|
||
if result.get('success'):
|
||
return {
|
||
'success': True,
|
||
'email': result.get('email'),
|
||
'password': password,
|
||
'verified': result.get('verified', False)
|
||
}
|
||
else:
|
||
return {
|
||
'success': False,
|
||
'error': result.get('error', 'Unknown error')
|
||
}
|
||
|
||
except Exception as e:
|
||
return {
|
||
'success': False,
|
||
'error': str(e)
|
||
}
|
||
|
||
def register_with_billing(self, password: str) -> Dict:
|
||
"""
|
||
注册 + 生成账单链接
|
||
|
||
Args:
|
||
password: 账号密码
|
||
|
||
Returns:
|
||
包含账单链接的注册结果
|
||
"""
|
||
try:
|
||
# 先执行基础注册
|
||
result = self.register_basic(password)
|
||
|
||
if not result.get('success'):
|
||
return result
|
||
|
||
# 延迟:注册完成后,模拟用户查看邮箱/确认的时间
|
||
HumanDelay.custom(**DELAY_CONFIG['after_registration'])
|
||
|
||
# 获取 Access Token
|
||
try:
|
||
# 延迟:准备获取token
|
||
HumanDelay.custom(**DELAY_CONFIG['before_get_token'])
|
||
|
||
access_token = self.registrar._step5_get_access_token()
|
||
result['access_token'] = access_token
|
||
|
||
if DEBUG:
|
||
print(f"✅ Access Token 获取成功")
|
||
|
||
# 延迟:获取token后
|
||
HumanDelay.custom(**DELAY_CONFIG['after_get_token'])
|
||
|
||
except Exception as e:
|
||
result['billing_error'] = f"获取 Access Token 失败: {str(e)}"
|
||
return result
|
||
|
||
# 生成账单链接
|
||
try:
|
||
# 延迟:准备生成账单
|
||
HumanDelay.custom(**DELAY_CONFIG['before_billing'])
|
||
|
||
billing_generator = EUBillingGenerator()
|
||
billing_result = billing_generator.generate_checkout_url(access_token)
|
||
|
||
if billing_result.success:
|
||
result['checkout_url'] = billing_result.checkout_url
|
||
if DEBUG:
|
||
print(f"✅ 账单链接生成成功")
|
||
|
||
# 延迟:生成账单后
|
||
HumanDelay.custom(**DELAY_CONFIG['after_billing'])
|
||
else:
|
||
result['billing_error'] = billing_result.error
|
||
|
||
except Exception as e:
|
||
result['billing_error'] = str(e)
|
||
|
||
return result
|
||
|
||
except Exception as e:
|
||
return {
|
||
'success': False,
|
||
'error': str(e)
|
||
}
|
||
|
||
def register_with_payment(
|
||
self,
|
||
password: str,
|
||
payment_info: Optional[Dict] = None,
|
||
save_to_notion: bool = True,
|
||
output_format: str = "notion" # "notion" or "json"
|
||
) -> Dict:
|
||
"""
|
||
完整注册流程(注册 + 账单 + 支付 + Notion)
|
||
|
||
Args:
|
||
password: 账号密码
|
||
payment_info: 支付信息字典,包含 name, address_line1, city, postal_code, state, country
|
||
save_to_notion: 是否保存到 Notion
|
||
output_format: 输出格式,"notion" 或 "json"
|
||
|
||
Returns:
|
||
完整的注册结果
|
||
"""
|
||
try:
|
||
# 先执行账单注册
|
||
result = self.register_with_billing(password)
|
||
|
||
if not result.get('success'):
|
||
return result
|
||
|
||
# 检查是否有账单链接
|
||
checkout_url = result.get('checkout_url')
|
||
if not checkout_url:
|
||
result['payment_error'] = result.get('billing_error', '未生成账单链接')
|
||
if output_format == "notion" and save_to_notion and self.notion_client:
|
||
self._save_to_notion(result, password)
|
||
result['output_format'] = output_format
|
||
return result
|
||
|
||
# 生成 IBAN
|
||
try:
|
||
iban_generator = GermanIbanGenerator()
|
||
iban = iban_generator.generate(1)[0]
|
||
result['iban'] = iban
|
||
|
||
if DEBUG:
|
||
print(f"✅ 已生成 IBAN: {iban}")
|
||
|
||
except Exception as e:
|
||
result['payment_error'] = f"生成 IBAN 失败: {str(e)}"
|
||
if output_format == "notion" and save_to_notion and self.notion_client:
|
||
self._save_to_notion(result, password)
|
||
result['output_format'] = output_format
|
||
return result
|
||
|
||
# 准备支付信息(使用随机生成或用户提供的值)
|
||
if payment_info:
|
||
# 用户提供了自定义信息
|
||
final_payment_info = payment_info
|
||
else:
|
||
# 生成随机真实的支付信息
|
||
final_payment_info = generate_payment_info()
|
||
|
||
if DEBUG:
|
||
print(f"💳 [Payment] 使用支付信息:")
|
||
print(f" 姓名: {final_payment_info['name']}")
|
||
print(f" 地址: {final_payment_info['address_line1']}")
|
||
print(f" 城市: {final_payment_info['city']}, {final_payment_info['state']} {final_payment_info['postal_code']}")
|
||
|
||
# 延迟:准备支付
|
||
HumanDelay.custom(**DELAY_CONFIG['before_payment'])
|
||
|
||
# 执行支付
|
||
try:
|
||
payment_result = self.registrar.add_payment_method(
|
||
checkout_session_url=checkout_url,
|
||
iban=iban,
|
||
name=final_payment_info['name'],
|
||
email=result['email'],
|
||
address_line1=final_payment_info['address_line1'],
|
||
city=final_payment_info['city'],
|
||
postal_code=final_payment_info['postal_code'],
|
||
state=final_payment_info['state'],
|
||
country=final_payment_info.get('country', 'US')
|
||
)
|
||
|
||
if payment_result.get('success'):
|
||
result['payment_added'] = True
|
||
result['payment_info'] = final_payment_info # 保存使用的支付信息
|
||
if DEBUG:
|
||
print(f"✅ 支付方式添加成功")
|
||
else:
|
||
result['payment_error'] = payment_result.get('error', 'Payment failed')
|
||
|
||
except Exception as e:
|
||
result['payment_error'] = str(e)
|
||
|
||
# 根据输出格式决定是否保存到 Notion
|
||
if output_format == "notion" and save_to_notion and self.notion_client:
|
||
self._save_to_notion(result, password)
|
||
|
||
# 标记输出格式
|
||
result['output_format'] = output_format
|
||
|
||
return result
|
||
|
||
except Exception as e:
|
||
return {
|
||
'success': False,
|
||
'error': str(e)
|
||
}
|
||
|
||
def _save_to_notion(self, result: Dict, password: str) -> None:
|
||
"""
|
||
保存账号信息到 Notion
|
||
|
||
Args:
|
||
result: 注册结果字典
|
||
password: 账号密码
|
||
"""
|
||
if not self.notion_client:
|
||
if DEBUG:
|
||
print(f"⚠️ Notion 客户端未初始化,跳过保存")
|
||
return
|
||
|
||
try:
|
||
email = result.get('email')
|
||
checkout_url = result.get('checkout_url') if result.get('payment_added') else None
|
||
|
||
# 根据支付结果设置 autoStatus
|
||
# payment_added 为 True 表示支付成功
|
||
auto_status = "success" if result.get('payment_added') else "fail"
|
||
|
||
notion_result = self.notion_client.add_account(
|
||
email=email,
|
||
password=password,
|
||
billing_url=checkout_url,
|
||
person=None,
|
||
status="未开始", # 车状态
|
||
done_status="done", # done 状态
|
||
auto_status=auto_status # 自动检测支付状态
|
||
)
|
||
|
||
if notion_result.get('success'):
|
||
result['notion_saved'] = True
|
||
if DEBUG:
|
||
print(f"✅ 已保存到 Notion (autoStatus: {auto_status})")
|
||
else:
|
||
result['notion_error'] = notion_result.get('error', 'Failed to save')
|
||
|
||
except Exception as e:
|
||
result['notion_error'] = str(e)
|
||
if DEBUG:
|
||
print(f"⚠️ 保存到 Notion 失败: {e}")
|
||
|
||
|
||
def create_flow(tempmail_client: TempMailClient) -> CompleteRegistrationFlow:
|
||
"""
|
||
工厂函数:创建完整流程实例
|
||
|
||
Args:
|
||
tempmail_client: 临时邮箱客户端
|
||
|
||
Returns:
|
||
CompleteRegistrationFlow 实例
|
||
"""
|
||
return CompleteRegistrationFlow(tempmail_client)
|