2010-02-02 85 views
13

我目前使用imaplib從服務器獲取電子郵件並處理內容和附件。如何使用Python imaplib回覆電子郵件幷包含原始郵件?

我想回復帶有狀態/錯誤消息的郵件,並鏈接到我的網站上生成的內容(如果可以處理它們)。這應該包括原始消息,但應該刪除任何附件(這將是很大的),並且最好用它們的文件名/大小替換它們。

由於我已經走MIME消息部分,我假設我需要做的是構建一個新的MIME消息樹,其中包含原始消息的副本並刪除/替換附件節點。

在我開始走下去之前,我希望有人能給我一些提示。有沒有任何類型的庫函數來做到這一點?我應該堅持的任何一種標準行爲?

我目前知道/正在使用imaplib,smtplibemail模塊,但可能錯過了某些顯而易見的內容。這也是在Django中運行的,所以如果這可以讓它變得更容易,那麼可以使用任何在​​中的東西。

回答

14

傳入消息的原始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"] = "[email protected]" 

然後附原始MIME消息對象和發送

首先,原始郵件文本/純佔位符代替所有的附件:

new.attach(MIMEMessage(original)) 

s = smtplib.SMTP() 
s.sendmail("[email protected]", [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", 
          "[email protected]", # from 
          [original["Reply-To"] or original["From"]], # to 
          headers = {'Reply-To': "[email protected]", 
             "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中至少)示出原始消息爲「----轉發消息----」,這ISN」這與我之後的工作非常相似,但總的想法很有效,我希望這個答案可以幫助有人試圖弄清楚如何處理MIME消息。

+1

「我希望這個答案可以幫助有人試圖弄清楚如何擺弄MIME信息。」 -----它確實如此。謝謝湯姆! – aniketd 2016-05-23 10:26:52

相關問題