17

私は現在imaplib、サーバーから電子メールメッセージをフェッチし、コンテンツと添付ファイルを処理するために使用しています。

ステータス/エラーメッセージと、処理できる場合はサイトで生成されたコンテンツへのリンクをメッセージに返信したいと思います。これには元のメッセージが含まれている必要がありますが、添付ファイル(大きくなります)を削除し、できればファイル名/サイズだけに置き換えてください。

私はすでにMIMEメッセージの部分を歩いているので、元のメッセージのコピーを含む新しいMIMEメッセージツリーを構築し、添付ファイルノードを削除/置換する必要があると想定しています。

その道を歩む前に、誰かが私にいくつかのヒントをくれることを望んでいました。これを行うためのライブラリ関数はありますか?私が固執すべき標準的な振る舞いはありますか?

私は現在imaplibsmtplibおよびemailモジュールを使用していることを知っていますが、そこにある明らかな何かを見逃している可能性があります。これはDjangoでも実行されているので、django.core.emailそれが簡単であれば何でも使用できます。

4

1 に答える 1

21

着信メッセージの元の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メッセージをいじる方法を理解します。

于 2010-02-03T04:09:59.873 に答える