如何使用Python imaplib回复电子邮件并包含原始邮件? [英] How do I reply to an email using the Python imaplib and include the original message?

查看:1530
本文介绍了如何使用Python imaplib回复电子邮件并包含原始邮件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆