【问题标题】:How do I reply to an email using the Python imaplib and include the original message?如何使用 Python imaplib 回复电子邮件并包含原始消息?
【发布时间】:2011-01-12 00:53:27
【问题描述】:

我目前正在使用imaplib 从服务器获取电子邮件并处理内容和附件。

如果可以处理这些消息,我想用状态/错误消息和指向我网站上生成的内容的链接来回复这些消息。这应该包括原始邮件,但应该删除所有附件(这将是大的),最好只用它们的文件名/大小替换它们。

由于我已经在遍历 MIME 消息部分,我假设我需要做的是构建一个包含原始消息副本的新 MIME 消息树并删除/替换附件节点。

在我开始走这条路之前,我希望有人能给我一些建议。是否有任何类型的库函数可以做到这一点?我应该坚持的任何标准行为?

我目前知道/正在使用imaplibsmtplibemail 模块,但可能错过了其中一些明显的东西。这也在 Django 中运行,因此可以使用 django.core.email 中的任何内容,如果这样更容易的话。

【问题讨论】:

    标签: python django email mime imaplib


    【解决方案1】:

    传入消息的原始MIME树结构如下(使用email.iterators._structure(msg)):

    multipart/mixed
        text/html                (message)
        application/octet-stream (attachment 1)
        application/octet-stream (attachment 2)
    

    通过 GMail 回复会产生以下结构:

    multipart/alternative
        text/plain
        text/html
    

    即他们没有我想象的那么聪明,只是丢弃附件(很好)并提供明确重组“引用内容”的文本和 HTML 版本。

    我开始认为这也是我应该做的,只回复一条简单的消息,因为在丢弃附件后,保留原始消息没有多大意义。

    不过,还是回答我原来的问题吧,因为我现在已经知道该怎么做了。

    首先,将原始邮件中的所有附件替换为文本/纯占位符:

    import email
    
    original = email.message_from_string( ... )
    
    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"]
    

    然后创建回复消息:

    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email.mime.message import MIMEMessage
    
    new = MIMEMultipart("mixed")
    body = MIMEMultipart("alternative")
    body.attach( MIMEText("reply body text", "plain") )
    body.attach( MIMEText("<html>reply 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["To"] = original["Reply-To"] or original["From"]
    new["From"] = "me@mysite.com"
    

    然后附加原始 MIME 消息对象并发送:

    new.attach( MIMEMessage(original) )
    
    s = smtplib.SMTP()
    s.sendmail("me@mysite.com", [new["To"]], new.as_string())
    s.quit()
    

    得到的结构是:

    multipart/mixed
        multipart/alternative
            text/plain
            text/html
        message/rfc822
            multipart/mixed
                text/html
                text/plain
                text/plain
    

    或者使用 Django 更简单一些:

    from django.core.mail import EmailMultiAlternatives
    from email.mime.message import MIMEMessage
    
    new = EmailMultiAlternatives("Re: "+original["Subject"],
                                 "reply body text", 
                                 "me@mysite.com", # from
                                 [original["Reply-To"] or original["From"]], # to
                                 headers = {'Reply-To': "me@mysite.com",
                                            "In-Reply-To": original["Message-ID"],
                                            "References": original["Message-ID"]})
    new.attach_alternative("<html>reply body text</html>", "text/html")
    new.attach( MIMEMessage(original) ) # attach original message
    new.send()
    

    结果结束(至少在 GMail 中)将原始消息显示为“----转发的消息----”这不是我所追求的,但总体思路可行,我希望这个答案有帮助有人试图弄清楚如何摆弄 MIME 消息。

    【讨论】:

    • “我希望这个答案能帮助那些试图弄清楚如何处理 MIME 消息的人。” ----- 确实如此。谢谢汤姆!
    • 嗨!我完成了你写的所有操作,但出现错误 SMTPDataError: (552, b'5.7.0 此邮件已被阻止,因为其内容存在潜在的\n5.7.0 安全问题。请访问\n5.7.0 support.google.com/mail/?p=BlockedMessage 查看我们的\n5。 7.0 邮件内容和附件内容指南。n5sm277571lfd.52 - gsmtp')
    猜你喜欢
    • 2012-04-15
    • 2021-06-16
    • 2016-01-22
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 1970-01-01
    相关资源
    最近更新 更多