From b2a2f513aef5eac32a63efef15f80585fb7c00a1 Mon Sep 17 00:00:00 2001 From: yueli Date: Wed, 23 Sep 2026 17:41:35 +0800 Subject: [PATCH] =?UTF-8?q?fix(email):=20=E8=A1=A5=E9=BD=90=20Date=20?= =?UTF-8?q?=E4=B8=8E=20Message-ID=20=E9=82=AE=E4=BB=B6=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:本项目发出的所有邮件都缺少 Date 与 Message-ID —— 这两个头 RFC 5322 要求(Date)或强烈建议(Message-ID)携带,而 smtplib **不会自动补**,构造 MIMEMultipart 时必须自己加。 为什么值得修:缺这两个头是反垃圾引擎的经典扣分项("来源不明的 自动化邮件"特征)。而它是**静默失败** —— 发件服务器照样回 250 Data Ok,客户端完全看不出邮件在收件方被降权。 诊断依据:抓取完整的 SMTP 会话(set_debuglevel(1))后,报文里 只有 Content-Type / MIME-Version / From / To / Subject 五个头。 ★ 需要说明的是:**无法证明这就是此前邮件丢失的原因**。用户实测 未加此头的邮件也能收到,加了之后仍有一封未送达。此改动是补上 一个确定存在的规范缺陷,不等同于修复了投递问题。 影响面:send_email() 是全局共用的发信函数,库存预警、出库/借库 审批通知等所有通知邮件一并受益。 --- inventory-backend/app/utils/email_service.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/inventory-backend/app/utils/email_service.py b/inventory-backend/app/utils/email_service.py index 3923180..b7a3d41 100644 --- a/inventory-backend/app/utils/email_service.py +++ b/inventory-backend/app/utils/email_service.py @@ -10,6 +10,7 @@ import logging from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.header import Header +from email.utils import formatdate, make_msgid from typing import List, Union logger = logging.getLogger(__name__) @@ -94,6 +95,13 @@ def send_email(to_email: Union[str, List[str]], subject: str, content: str, cfg: msg['From'] = cfg['sender'] msg['To'] = ', '.join(recipients) msg['Subject'] = Header(subject, 'utf-8') + # ★ Date 与 Message-ID 是 RFC 5322 的**必需/强烈建议**头, + # smtplib 不会自动补。缺了它们,收件方的反垃圾引擎会显著加分 + # ("来源不明的自动化邮件"),很容易被判成垃圾或进隔离区 —— + # 而发件服务器照样回 250,客户端完全看不出来。 + # 实测本项目的邮件此前两个头都没有。 + msg['Date'] = formatdate(localtime=True) + msg['Message-ID'] = make_msgid(domain=(cfg['sender'].split('@')[-1] or None)) msg.attach(MIMEText(content, 'plain', 'utf-8')) print(f"DEBUG: 准备向服务器提交发信请求,收件人: {recipients} 发件人: {cfg['username']}")