import json from typing import Optional, Dict, Any from loguru import logger from core.exceptions import EmailError from services.fetch_manager import FetchManager class SelfHostedEmail: """自建邮箱服务类,负责从API获取邮箱和验证码""" def __init__(self, fetch_manager: FetchManager, api_base_url: str, api_key: Optional[str] = None): """初始化自建邮箱服务 Args: fetch_manager: HTTP请求管理器 api_base_url: API基础URL,例如 "https://api.cursorpro.com.cn" api_key: API密钥(可选) """ self.fetch_manager = fetch_manager self.api_base_url = "https://api.cursorpro.com.cn" self.api_key = "1234567890" # API端点 self.get_email_endpoint = "/admin/api.email/getEmail" self.get_code_endpoint = "/admin/api.email/getVerificationCode" async def _make_api_request(self, endpoint: str, params: Dict[str, Any] = None) -> Dict[str, Any]: """向API发送请求 Args: endpoint: API端点,例如 "/admin/api.email/getEmail" params: 请求参数 Returns: 解析后的JSON响应 Raises: EmailError: 当API请求失败或响应无法解析时 """ url = f"{self.api_base_url}{endpoint}" headers = {} if self.api_key: headers["Authorization"] = f"Bearer {self.api_key}" logger.debug(f"正在请求: {url}") response = await self.fetch_manager.request( "GET", url, headers=headers, params=params ) if 'error' in response: raise EmailError(f"API请求失败: {response['error']}") try: result = json.loads(response['body'].decode()) return result except Exception as e: raise EmailError(f"解析API响应失败: {str(e)}") async def get_email(self) -> Optional[str]: """从API获取一个可用邮箱 Returns: 邮箱地址,失败时返回None """ try: result = await self._make_api_request(self.get_email_endpoint) if result.get('code') != 0: logger.error(f"获取邮箱失败: {result.get('msg')}") return None email = result.get('data', {}).get('email') if not email: logger.error("API未返回有效邮箱") return None logger.info(f"获取到自建邮箱: {email}") return email except Exception as e: logger.error(f"获取邮箱失败: {str(e)}") return None async def get_verification_code(self, email: str) -> Optional[str]: """从API获取验证码 Args: email: 邮箱地址 Returns: 验证码,失败时返回None """ try: result = await self._make_api_request( self.get_code_endpoint, params={"email": email} ) if result.get('code') != 0: logger.error(f"获取验证码失败: {result.get('msg')}") return None code = result.get('data', {}).get('code') if not code: logger.error("API未返回有效验证码") return None logger.info(f"获取到验证码: {code} (邮箱: {email})") return code except Exception as e: logger.error(f"获取验证码失败: {str(e)}") return None