Python基于smtplib实现带Cc抄送的邮件回复时抄送方未收到问题咨询
问题根因
smtplib的send_message()方法并不会100%自动识别所有消息头里的收件人。当你手动在消息头中拼接Cc字段时,如果存在格式解析兼容问题,方法会直接跳过所有抄送地址的提取——SMTP投递环节只会给To字段里的原发件人发送投递请求,根本不会向抄送地址发起投递,自然出现“Gmail界面显示已抄送、但抄送收件人收不到邮件”的现象。
修正方案
核心调整点
- 不依赖SMTP的自动地址解析,手动整理所有需要实际投递的收件人列表,显式传入发送方法,绕过自动解析的兼容问题
- 修复原代码中可变默认参数(
cc_addrs: list = [])的全局内存污染隐患 - 补全缺失的顶层
email模块导入,避免工具类调用报错 - 确认SMTP调试输出中能看到所有抄送地址的
RCPT TO投递请求,确保服务器收到所有投递目标
修正后的关键代码片段
def send_answer(original, file_to_attach, body_text="Macros reply", cc_addrs: list = None): # 替换原可变默认参数,避免全局内存污染 if cc_addrs is None: cc_addrs = [] import smtplib import ssl import email # 补全顶层email模块导入,避免工具类调用报错 from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase new = MIMEMultipart("mixed") body = MIMEMultipart("alternative") body.attach(MIMEText(body_text, "plain")) body.attach(MIMEText(f"<html> {body_text} </html>", "html")) new.attach(body) new["Message-ID"] = email.utils.make_msgid() new["In-Reply-To"] = original["Message-ID"] new["References"] = original["Message-ID"] new["Subject"] = "Re: " + original["Subject"] new["From"] = user # 初始化实际投递地址列表 primary_recipient = original["From"].lower() to_addrs = [primary_recipient] new["To"] = primary_recipient if cc_addrs: new['Cc'] = ",".join(cc_addrs) # 把所有抄送地址加入实际投递列表 to_addrs.extend(cc_addrs) # 附件处理逻辑与原代码一致 file_name = file_to_attach.name part = MIMEBase('application', 'octet-stream') with open(file_to_attach, 'rb') as attachment: part.set_payload(attachment.read()) email.encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment', filename=file_name) new.attach(part) context = ssl.create_default_context() with smtplib.SMTP('smtp.gmail.com', 587) as s: s.ehlo() s.starttls(context=context) s.ehlo() s.login(user, password) s.set_debuglevel(True) # 显式传入完整的收件人投递列表 s.send_message(new, to_addrs=to_addrs)
验证标准
修正后运行代码,SMTP调试输出的RCPT TO环节会依次列出原发件人、所有抄送地址的投递记录,服务器会正常向所有列表内的地址投递邮件,不会再出现抄送收件人收不到的问题。
内容的提问来源于stack exchange,提问作者Vasyl Kolomiets
相关产品推荐
相关产品推荐

