refactor(config): 优化Outlook提供者优先级和验证码匹配逻辑

- 调整Outlook提供者优先级:IMAP_OLD > IMAP_NEW > Graph API
- 增强OpenAI验证邮件发件人匹配模式,支持子域名
- 改进Graph API提供者的401错误处理,避免因权限不足误判
- 修复配置解析中的类型转换问题
This commit is contained in:
cnlimiter
2026-03-15 19:10:53 +08:00
parent 1628552b92
commit 2f2fb51764
4 changed files with 32 additions and 10 deletions

View File

@@ -132,7 +132,8 @@ OTP_CODE_SEMANTIC_PATTERN = r'(?:code\s+is|验证码[是为]?\s*[:]?\s*)(\d{6
OPENAI_EMAIL_SENDERS = [ OPENAI_EMAIL_SENDERS = [
"noreply@openai.com", "noreply@openai.com",
"no-reply@openai.com", "no-reply@openai.com",
"@openai.com", # 通配符匹配 "@openai.com", # 精确域名匹配
".openai.com", # 子域名匹配(如 otp@tm1.openai.com
] ]
# OpenAI 验证邮件关键词 # OpenAI 验证邮件关键词

View File

@@ -301,7 +301,7 @@ SETTING_DEFINITIONS: Dict[str, SettingDefinition] = {
# Outlook 配置 # Outlook 配置
"outlook_provider_priority": SettingDefinition( "outlook_provider_priority": SettingDefinition(
db_key="outlook.provider_priority", db_key="outlook.provider_priority",
default_value=["graph_api", "imap_new", "imap_old"], default_value=["imap_old", "imap_new", "graph_api"],
category=SettingCategory.EMAIL, category=SettingCategory.EMAIL,
description="Outlook 提供者优先级" description="Outlook 提供者优先级"
), ),
@@ -373,13 +373,31 @@ def _convert_value(attr_name: str, value: str) -> Any:
elif target_type == dict: elif target_type == dict:
if isinstance(value, dict): if isinstance(value, dict):
return value return value
if not value:
return {}
import json import json
return json.loads(value) if value else {} import ast
try:
return json.loads(value)
except (json.JSONDecodeError, ValueError):
try:
return ast.literal_eval(value)
except Exception:
return {}
elif target_type == list: elif target_type == list:
if isinstance(value, list): if isinstance(value, list):
return value return value
if not value:
return []
import json import json
return json.loads(value) if value else [] import ast
try:
return json.loads(value)
except (json.JSONDecodeError, ValueError):
try:
return ast.literal_eval(value)
except Exception:
return []
else: else:
return value return value
@@ -568,7 +586,7 @@ class Settings(BaseModel):
email_code_poll_interval: int = 3 email_code_poll_interval: int = 3
# Outlook 配置 # Outlook 配置
outlook_provider_priority: List[str] = ["graph_api", "imap_new", "imap_old"] outlook_provider_priority: List[str] = ["imap_old", "imap_new", "graph_api"]
outlook_health_failure_threshold: int = 5 outlook_health_failure_threshold: int = 5
outlook_health_disable_duration: int = 60 outlook_health_disable_duration: int = 60
outlook_default_client_id: str = "24d9a0ed-8787-4584-883c-2fd79308940a" outlook_default_client_id: str = "24d9a0ed-8787-4584-883c-2fd79308940a"

View File

@@ -145,11 +145,12 @@ class GraphAPIProvider(OutlookProvider):
) )
if resp.status_code == 401: if resp.status_code == 401:
# Token 失效,清除缓存 # Token 无 Graph 权限client_id 未授权),清除缓存但不记录健康失败
# 避免因权限不足导致健康检查器禁用该提供者,影响其他账户
if self._token_manager: if self._token_manager:
self._token_manager.clear_cache() self._token_manager.clear_cache()
self.record_failure(f"HTTP 401: Token 失效") self._connected = False
logger.error(f"[{self.account.email}] Graph API Token 失效") logger.warning(f"[{self.account.email}] Graph API 返回 401client_id 可能无 Graph 权限,跳过")
return [] return []
if resp.status_code != 200: if resp.status_code != 200:

View File

@@ -25,10 +25,12 @@ logger = logging.getLogger(__name__)
# 默认提供者优先级 # 默认提供者优先级
# IMAP_OLD 最兼容(只需 login.live.com tokenIMAP_NEW 次之Graph API 最后
# 原因:部分 client_id 没有 Graph API 权限,但有 IMAP 权限
DEFAULT_PROVIDER_PRIORITY = [ DEFAULT_PROVIDER_PRIORITY = [
ProviderType.GRAPH_API,
ProviderType.IMAP_NEW,
ProviderType.IMAP_OLD, ProviderType.IMAP_OLD,
ProviderType.IMAP_NEW,
ProviderType.GRAPH_API,
] ]