如何使用Python imaplib回复电子邮件并包含原始邮件? [英] How do I reply to an email using the Python imaplib and include the original message?
问题描述
我目前正在使用 imaplib
从服务器获取电子邮件,并处理内容和附件。
我想回复带有状态/错误消息的消息,并链接到如果可以处理,我的网站上生成的内容。这应该包括原始的消息,但应该删除任何附件(这将是很大的),并最好用他们的文件名/尺寸替换。
由于我已经走了MIME消息部分,我假设我需要做的是构建一个新的MIME消息树,其中包含原始消息的副本,并删除/替换附件节点。
在我开始这条路之前,我希望有人可以给我一些提示。有什么样的图书馆功能吗?我应该坚持什么样的标准行为?
我目前知道/正在使用 imaplib
, smtplib
和电子邮件
模块,但可能错过了明显的东西。这也是在Django中运行的,所以可以使用 django.core.email
中的任何东西,如果这样做更容易。
传入消息的原始MIME树结构如下(使用 email.iterators._structure(msg)
):
multipart / mixed
文本/ html(消息)
应用程序/八位字节流(附件1)
应用程序/八位字节流(附件2)
通过GMail回复结果如下: / p>
multipart / alternative
text / plain
text / html
他们并不如我想象的那么聪明,只是丢弃附件(好),并提供明确重组引用内容的文本和HTML版本。
我开始认为这就是我应该做的,只是回复一个简单的消息,因为丢弃附件没有太多的意义保留原始消息。
仍然可能以及回答我原来的问题,因为我已经弄清楚如何现在无论如何。
首先,使用文本/简单占位符替换原始消息中的所有附件: p>
导入电子邮件
original = email.message_from_string(...)
部分在original.walk():
if(part.get('Content-Disposition')
和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]
然后创建回复消息:
从email.mime.Mtip导入MIMEMultipart从email.mime.text import MIMEText
from email.mime.message
$ MIM $($)
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]或original [ From]
new [From] =me @ mysi te.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
/ b
$ b 或者使用Django有点简单:
<$ p $来自django.core.mail的邮件导入EmailMultiAlternatives
来自email.mime.message import MIMEMessage
new = EmailMultiAlternatives(Re:+ original [Subject ],
回复正文,
me@mysite.com,#从
[原始[回覆]或原始[从]],#到
标题= {'回覆':me@mysite.com,
回复:original [Message-ID],
References:original [Message-ID]})
new.attach_alternative(< html> reply body text< / html> ,text / html)
new.attach(MIMEMessage(original))#附加原始消息
new.send()
结果(至少在GMail中)显示原始消息为----转发的消息----,这不完全是我以后的,但是一般想法工作,我希望这个答案有助于有人试图找出如何解决MIME消息。
I'm currently using imaplib
to fetch email messages from a server and process the contents and attachments.
I'd like to reply to the messages with a status/error message and links to the resulting generated content on my site if they can be processed. This should include the original message but should drop any attachments (which will be large) and preferably replace them with just their filenames/sizes.
Since I'm already walking the MIME message parts, I'm assuming what I need to do is build a new MIME message tree containing a copy of the original message and delete/replace the attachment nodes.
Before I start down that path, I was hoping someone can give me some tips. Is there any kind of library function to do this? Any kind of standard behavior I should stick to?
I currently know of/am using the imaplib
, smtplib
and email
modules and but may have missed something obvious in there. This is running in Django too, so can use anything in django.core.email
if that makes it easier.
The original MIME tree structure of the incoming message is as follows (using email.iterators._structure(msg)
):
multipart/mixed
text/html (message)
application/octet-stream (attachment 1)
application/octet-stream (attachment 2)
Replying via GMail results in the following structure:
multipart/alternative
text/plain
text/html
I.e. they aren't being as smart as I thought, just discarding the attachments (good) and providing text and HTML versions that explicitly restructure the "quoted content."
I'm beginning to think that's all I should do too, just reply with a simple message as after discarding the attachments there's not much point in keeping the original message.
Still, might as well answer my original question since I've figured out how to now anyway.
First, replace all the attachments in the original message with text/plain placeholders:
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"]
Then create a reply message:
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"
Then attach the original MIME message object and send:
new.attach( MIMEMessage(original) )
s = smtplib.SMTP()
s.sendmail("me@mysite.com", [new["To"]], new.as_string())
s.quit()
The resulting structure is:
multipart/mixed
multipart/alternative
text/plain
text/html
message/rfc822
multipart/mixed
text/html
text/plain
text/plain
Or it's a bit simpler using 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()
The result ends (in GMail at least) showing the original message as "---- Forwarded message ----" which isn't quite what I was after, but the general idea works and I hope this answer helps someone trying to figure out how to fiddle with MIME messages.
这篇关于如何使用Python imaplib回复电子邮件并包含原始邮件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!