You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用smtplib和imaplib实现保留原始内容的邮件回复

实现带原始内容的邮件回复(基于smtplib/imaplib)

第一步:读取目标邮件(以Gmail/Exchange为例)

用imaplib连接邮箱服务器,获取邮件原始字节数据后,通过email模块解析为可操作的邮件对象。

import imaplib
from email.parser import BytesParser
from email.policy import default

def fetch_email(imap_host, imap_user, imap_pass, email_id):
    # 连接IMAP服务器
    with imaplib.IMAP4_SSL(imap_host) as imap:
        imap.login(imap_user, imap_pass)
        imap.select('INBOX')  # 可替换为其他邮箱文件夹
        
        # 获取邮件原始内容
        _, data = imap.fetch(email_id, '(RFC822)')
        raw_email = data[0][1]
        
        # 解析为EmailMessage对象
        msg = BytesParser(policy=default).parsebytes(raw_email)
        return msg
  • Gmail的IMAP地址为imap.gmail.com,Exchange/Outlook为outlook.office365.com
  • Gmail开启两步验证后,需使用应用专用密码登录,不能用普通密码

第二步:构建带原始内容的回复邮件

核心是关联原始邮件的标识头,同时拼接新HTML内容与引用格式的原始邮件内容。

from email.message import EmailMessage
import re

def build_reply(original_msg, new_html_content, sender_email):
    reply_msg = EmailMessage(policy=default)
    
    # 处理回复主题
    original_subject = original_msg['Subject'] or ''
    reply_msg['Subject'] = f'Re: {original_subject}' if not original_subject.startswith('Re: ') else original_subject
    
    # 设置收件人、发件人
    reply_msg['To'] = original_msg['From']
    reply_msg['From'] = sender_email
    
    # 关联原始邮件(确保邮件客户端识别为回复)
    original_msg_id = original_msg['Message-ID']
    if original_msg_id:
        reply_msg['In-Reply-To'] = original_msg_id
        reply_msg['References'] = f"{original_msg['References'] or ''} {original_msg_id}".strip()
    
    # 提取原始邮件的纯文本内容(优先取plain text,无则转换HTML为文本)
    def get_original_text(msg):
        if msg.is_multipart():
            for part in msg.walk():
                if part.get_content_type() == 'text/plain':
                    return part.get_content()
            # 无纯文本时,简单去除HTML标签提取文本
            for part in msg.walk():
                if part.get_content_type() == 'text/html':
                    return re.sub(r'<[^>]+>', '', part.get_content())
        else:
            return re.sub(r'<[^>]+>', '', msg.get_content()) if msg.get_content_type() != 'text/plain' else msg.get_content()
    
    # 将原始内容转为Gmail风格的引用格式
    quoted_original = '\n'.join([f'> {line}' for line in get_original_text(original_msg).splitlines()])
    
    # 拼接最终HTML内容:新内容 + 分割线 + 引用的原始邮件
    final_html = f"""
    {new_html_content}
    <hr>
    <div style="color:#666;">
        <p>---------- 原始邮件 ----------</p>
        <pre style="white-space:pre-wrap;">{quoted_original}</pre>
    </div>
    """
    
    reply_msg.set_content(final_html, subtype='html')
    return reply_msg

第三步:发送回复邮件

通过smtplib连接SMTP服务器,发送构建好的回复邮件。

import smtplib

def send_reply(smtp_host, smtp_port, smtp_user, smtp_pass, reply_msg):
    # 针对Exchange/Outlook的587端口(STARTTLS),需替换为SMTP+starttls
    with smtplib.SMTP_SSL(smtp_host, smtp_port) as smtp:
        smtp.login(smtp_user, smtp_pass)
        smtp.send_message(reply_msg)
  • Exchange/Outlook的SMTP端口为587,需修改发送代码:
    with smtplib.SMTP(smtp_host, smtp_port) as smtp:
        smtp.starttls()
        smtp.login(smtp_user, smtp_pass)
        smtp.send_message(reply_msg)
    

完整使用示例

# 配置信息(替换为你的实际内容)
USER_EMAIL = 'your-email@example.com'
USER_PASS = 'your-password-or-app-password'

# Gmail配置
IMAP_HOST = 'imap.gmail.com'
SMTP_HOST = 'smtp.gmail.com'
SMTP_PORT = 465

# Exchange/Outlook配置
# IMAP_HOST = 'outlook.office365.com'
# SMTP_HOST = 'smtp.office365.com'
# SMTP_PORT = 587

# 要回复的邮件ID(可通过imap.search获取,示例为已知ID)
EMAIL_ID = '12345'

# 自定义HTML回复内容
new_html = """
<h3>您好!</h3>
<p>这是我的HTML格式回复,可以添加 <strong>加粗文本</strong> 或 <span style="color:blue">彩色文字</span>。</p>
"""

# 执行流程
original_msg = fetch_email(IMAP_HOST, USER_EMAIL, USER_PASS, EMAIL_ID)
reply_msg = build_reply(original_msg, new_html, USER_EMAIL)
send_reply(SMTP_HOST, SMTP_PORT, USER_EMAIL, USER_PASS, reply_msg)

注意事项

  • 若需保留原始邮件的HTML格式而非转为纯文本引用,可直接提取原始HTML内容并添加引用样式,但可能存在样式冲突,需自行调整
  • 可通过imap.search(None, 'SUBJECT "目标主题"')等条件筛选邮件ID,无需手动指定
  • 企业Exchange可能需管理员开启IMAP/SMTP服务权限

内容的提问来源于stack exchange,提问作者黃郁暉

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:28:11