fix: prefer newest OTP messages

This commit is contained in:
mmc
2026-03-19 16:58:18 +08:00
parent d6ea996e09
commit e13d54191b
2 changed files with 35 additions and 0 deletions

View File

@@ -5,6 +5,7 @@ from __future__ import annotations
import argparse import argparse
import json import json
import os import os
import random
import sys import sys
import time import time
from pathlib import Path from pathlib import Path

View File

@@ -5,7 +5,9 @@ MailProvider 抽象层
from __future__ import annotations from __future__ import annotations
import datetime
import itertools import itertools
import email.utils
import logging import logging
import random import random
import re import re
@@ -113,6 +115,34 @@ def _extract_code(content: str) -> Optional[str]:
return None return None
def _message_timestamp(msg: Dict[str, Any]) -> float:
candidates = [
msg.get("createdAt"),
msg.get("created_at"),
msg.get("receivedAt"),
msg.get("received_at"),
msg.get("updatedAt"),
msg.get("updated_at"),
msg.get("date"),
]
for raw in candidates:
text = str(raw or "").strip()
if not text:
continue
try:
normalized = text.replace("Z", "+00:00")
return datetime.datetime.fromisoformat(normalized).timestamp()
except Exception:
pass
try:
parsed = email.utils.parsedate_to_datetime(text)
if parsed is not None:
return parsed.timestamp()
except Exception:
pass
return 0.0
# ==================== 抽象基类 ==================== # ==================== 抽象基类 ====================
class MailProvider(ABC): class MailProvider(ABC):
@@ -254,6 +284,8 @@ class MailTmProvider(MailProvider):
messages = data if isinstance(data, list) else ( messages = data if isinstance(data, list) else (
data.get("hydra:member") or data.get("messages") or [] data.get("hydra:member") or data.get("messages") or []
) )
if isinstance(messages, list):
messages = sorted(messages, key=_message_timestamp, reverse=True)
for msg in messages: for msg in messages:
if not isinstance(msg, dict): if not isinstance(msg, dict):
@@ -497,6 +529,8 @@ class DuckMailProvider(MailProvider):
if resp.status_code == 200: if resp.status_code == 200:
data = resp.json() data = resp.json()
messages = data.get("hydra:member") or data.get("member") or data.get("data") or [] messages = data.get("hydra:member") or data.get("member") or data.get("data") or []
if isinstance(messages, list):
messages = sorted(messages, key=_message_timestamp, reverse=True)
for msg in (messages if isinstance(messages, list) else []): for msg in (messages if isinstance(messages, list) else []):
if not isinstance(msg, dict): if not isinstance(msg, dict):
continue continue