代码之家  ›  专栏  ›  技术社区  ›  Tom Gruff

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

  •  16
  • Tom Gruff  · 技术社区  · 16 年前

    我目前正在使用 imaplib

    我想回复带有状态/错误消息的消息,并链接到我网站上生成的内容(如果可以处理)。这应包括原始邮件,但应删除任何附件(较大),最好只替换为其文件名/大小。

    在我开始这条路之前,我希望有人能给我一些建议。有什么样的库函数可以做到这一点吗?我应该坚持什么样的标准行为?

    我目前知道/正在使用 , smtplib email 模块,但可能遗漏了一些明显的东西。这也是在Django中运行的,所以可以在中使用任何东西 django.core.email

    1 回复  |  直到 16 年前
        1
  •  20
  •   Tom Gruff    16 年前

    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()