如何使用 Python imaplib 回复电子邮件并包含原始邮件

337 阅读2分钟

在使用 Python imaplib 从服务器获取电子邮件并处理内容和附件后,如何使用状态/错误消息和生成内容的链接回复邮件?

2、解决方案

1) 准备 MIME 消息树

  • 构建一个新的 MIME 消息树,包含原始消息的副本。
  • 删除或替换附件节点。

2) 创建回复邮件

  • 使用 MIMEMultipartMIMETextMIMEMessage 创建回复邮件。
  • 设置必要的头字段,如 Message-IDIn-Reply-ToReferencesSubjectToFrom

3) 发送回复邮件

  • 使用 smtplib 发送回复邮件。
  • 或者,可以使用 Django 的 EmailMultiAlternatives 类来发送回复邮件。

代码示例

使用 imaplibsmtplib 回复电子邮件并包含原始邮件的代码示例如下:

import imaplib
import smtplib
import email
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.message import MIMEMessage

# 连接到 IMAP 服务器并登录
imap_server = 'imap.gmail.com'
imap_port = 993
imap_user = 'username'
imap_password = 'password'
imap = imaplib.IMAP4_SSL(imap_server, imap_port)
imap.login(imap_user, imap_password)

# 选择要回复的邮件的邮箱
imap.select('Inbox')

# 获取要回复的邮件
email_id = '12345'
typ, msg = imap.fetch(email_id, '(RFC822)')

# 解析原始邮件
original = email.message_from_string(msg[0][1].decode('utf-8'))

# 替换附件
for part in original.walk():
    if (part.get('Content-Disposition')
        and part.get('Content-Disposition').startswith("attachment")):

        part.set_type("text/plain")
        part.set_payload("Attachment removed: %s (%s, %d bytes)"
                         %(part.get_filename(), 
                           part.get_content_type(), 
                           len(part.get_payload(decode=True))))
        del part["Content-Disposition"]
        del part["Content-Transfer-Encoding"]

# 创建回复邮件
new = MIMEMultipart("mixed")
body = MIMEMultipart("alternative")
body.attach( MIMEText("回复邮件的正文文本", "plain") )
body.attach( MIMEText("<html>回复邮件的正文文本</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"] = "回复:" + original["Subject"]
new["To"] = original["Reply-To"] or original["From"]
new["From"] = "username@example.com"

# 附件原始邮件
new.attach( MIMEMessage(original) )

# 发送回复邮件
smtp_server = 'smtp.gmail.com'
smtp_port = 587
smtp_user = 'username'
smtp_password = 'password'
smtp = smtplib.SMTP(smtp_server, smtp_port)
smtp.starttls()
smtp.login(smtp_user, smtp_password)
smtp.sendmail(smtp_user, [new["To"]], new.as_string())
smtp.quit()

# 关闭 IMAP 连接
imap.close()

使用 Django 的 EmailMultiAlternatives 类回复电子邮件并包含原始邮件的代码示例如下:

from django.core.mail import EmailMultiAlternatives
from email.mime.message import MIMEMessage

# 创建回复邮件
new = EmailMultiAlternatives("回复:" + original["Subject"],
                             "回复邮件的正文文本", 
                             "username@example.com", # 发件人
                             [original["Reply-To"] or original["From"]], # 收件人
                             headers = {'Reply-To': "username@example.com",
                                        "In-Reply-To": original["Message-ID"],
                                        "References": original["Message-ID"]})
new.attach_alternative("<html>回复邮件的正文文本</html>", "text/html")
new.attach( MIMEMessage(original) ) # 附件原始邮件

# 发送回复邮件
new.send()