feat: handle Reply-To header, add account_email field, decode address headers
This commit is contained in:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user