diff --git a/src/email_client.py b/src/email_client.py index fedaf0f..96e1379 100644 --- a/src/email_client.py +++ b/src/email_client.py @@ -48,16 +48,36 @@ def _get_text_from_msg(msg) -> str: return "" +_PROVIDERS_NEED_ID = ("163.com", "126.com") + + +def _check_provider(email_addr: str, providers: tuple[str, ...]) -> bool: + return any(email_addr.endswith(p) for p in providers) + + +def _send_id_command(conn): + imaplib.Commands["ID"] = "AUTH" + args = ("name", "AI-Mail-Bot", "version", "1.0.0", "vendor", "personal") + conn._simple_command("ID", '("' + '" "'.join(args) + '")') + + def _select_mailbox(conn, mailbox: str = "INBOX"): status, data = conn.select(mailbox) if status != "OK": raise RuntimeError(f"无法选择邮箱 {mailbox}: {data}") -def fetch_unseen_emails(account: EmailAccount) -> list[Email]: +def _login_and_prepare(account: EmailAccount): conn = imaplib.IMAP4_SSL(account.imap_server, account.imap_port) conn.login(account.username, account.password) + if _check_provider(account.username, _PROVIDERS_NEED_ID): + _send_id_command(conn) _select_mailbox(conn) + return conn + + +def fetch_unseen_emails(account: EmailAccount) -> list[Email]: + conn = _login_and_prepare(account) _, data = conn.uid("SEARCH", None, "UNSEEN") uids = data[0].split() if data[0] else [] @@ -84,9 +104,7 @@ def fetch_unseen_emails(account: EmailAccount) -> list[Email]: def mark_as_seen(account: EmailAccount, uids: list[bytes]): if not uids: return - conn = imaplib.IMAP4_SSL(account.imap_server, account.imap_port) - conn.login(account.username, account.password) - _select_mailbox(conn) + conn = _login_and_prepare(account) for uid in uids: conn.uid("STORE", uid, "+FLAGS", "\\Seen") conn.logout()