feat: handle Reply-To header, add account_email field, decode address headers

This commit is contained in:
2026-07-02 22:37:15 +08:00
parent d7daddf491
commit c684090b9c
4 changed files with 43 additions and 14 deletions

View File

@@ -2,7 +2,7 @@ import imaplib
import email
import logging
from email.header import decode_header
from email.utils import parsedate_to_datetime
from email.utils import parsedate_to_datetime, parseaddr
from typing import Optional
from src.config import EmailAccount
from src.retry import retry
@@ -11,13 +11,16 @@ logger = logging.getLogger(__name__)
class Email:
def __init__(self, uid: bytes, subject: str, sender: str, recipient: str, body: str, date: str):
def __init__(self, uid: bytes, subject: str, sender: str, recipient: str,
body: str, date: str, reply_to: str = "", account_email: str = ""):
self.uid = uid
self.subject = subject
self.sender = sender
self.recipient = recipient
self.body = body
self.date = date
self.reply_to = reply_to
self.account_email = account_email
def _decode_str(s: str) -> str:
@@ -34,6 +37,18 @@ def _decode_str(s: str) -> str:
return "".join(result)
def _decode_address_header(header_value: str) -> str:
if not header_value:
return ""
decoded = _decode_str(header_value)
name, addr = parseaddr(decoded)
if not addr:
return name
if name:
return f"{name} <{addr}>"
return addr
def _get_text_from_msg(msg) -> str:
if msg.is_multipart():
for part in msg.walk():
@@ -108,14 +123,16 @@ def fetch_unseen_emails(account: EmailAccount) -> list[Email]:
msg = email.message_from_bytes(raw_email)
subject = _decode_str(msg.get("Subject", ""))
sender = msg.get("From", "")
recipient = msg.get("To", "")
sender = _decode_address_header(msg.get("From", ""))
recipient = _decode_address_header(msg.get("To", ""))
reply_to = _decode_address_header(msg.get("Reply-To", ""))
date_str = msg.get("Date", "")
body = _get_text_from_msg(msg)
body_len = len(body)
logger.info(" 邮件: [%s] from=%s to=%s (%d 字符)", subject, sender, recipient, body_len)
emails.append(Email(uid=uid, subject=subject, sender=sender, recipient=recipient, body=body, date=date_str))
logger.info(" 邮件: [%s] from=%s to=%s reply-to=%s (%d 字符)", subject, sender, recipient, reply_to, body_len)
emails.append(Email(uid=uid, subject=subject, sender=sender, recipient=recipient,
body=body, date=date_str, reply_to=reply_to, account_email=account.username))
conn.logout()
logger.info("共获取 %d 封新邮件", len(emails))