Wie kann ich auf eine E-Mail antworten, die Python imaplib und umfassen die ursprüngliche Nachricht mit?
Frage
Ich bin derzeit mit imaplib
um E-Mails von einem Server abrufen und verarbeiten die Inhalt und Anlagen.
Ich mag die Nachrichten mit einer Status / Fehlermeldung und Links zu den resultierenden erzeugten Inhalten auf meiner Website antworten, wenn sie verarbeitet werden können. Dies sollte die ursprüngliche Nachricht enthält aber alle Anlagen fallen sollte (was groß sein) und am besten wechselt mit nur ihre Dateinamen / Größen.
Da ich bereits die MIME-Nachrichtenteile gehen, ich gehe davon aus, was ich tun müssen, ist einen neuen MIME-Nachricht Baum eine Kopie der ursprünglichen Nachricht erstellen enthält, und löschen / ersetzen Sie die Befestigungsknoten.
Bevor ich diesen Weg nach unten beginnen, ich hatte gehofft, jemand kann mir ein paar Tipps geben. Gibt es irgendeine Art von Bibliotheksfunktion, dies zu tun? Jede Art von Standard-Verhalten, das ich bleiben sollte?
Ich weiß, zur Zeit von / bin mit dem imaplib
, smtplib
und email
Module und kann aber etwas offensichtlich dort verpasst haben. Dies wird auch in Django läuft, so etwas in django.core.email
verwenden kann, wenn das macht es einfacher.
Lösung
Die ursprüngliche MIME Baumstruktur der eingehenden Nachricht lautet wie folgt (mit email.iterators._structure(msg)
):
multipart/mixed
text/html (message)
application/octet-stream (attachment 1)
application/octet-stream (attachment 2)
Beantworten über GMail Ergebnisse in der folgenden Struktur:
multipart/alternative
text/plain
text/html
d. sie sind nicht so klug, wie ich dachte, nur die Anlagen zu verwerfen (gut) und die Bereitstellung von Text und HTML-Versionen, dass der explizit restrukturieren „zitierte Inhalt.“
Ich fange an alle zu denken, das ist, ich sollte tun, nur mit einer einfachen Nachricht antworten, da nach dem die Anlagen Verwerfen gibt es nicht viel Sinn, in die ursprüngliche Nachricht zu halten.
Dennoch könnte auch meine ursprüngliche Frage beantworten, da ich dachte, ich heraus, wie man jetzt sowieso.
Zuerst ersetzen alle die Anlagen in der ursprünglichen Nachricht mit text / plain Platzhalter:
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"]
Dann eine Antwortnachricht erstellen:
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"
befestigen Sie dann das ursprüngliche MIME-Nachrichtenobjekt und senden:
new.attach( MIMEMessage(original) )
s = smtplib.SMTP()
s.sendmail("me@mysite.com", [new["To"]], new.as_string())
s.quit()
Die resultierende Struktur ist:
multipart/mixed
multipart/alternative
text/plain
text/html
message/rfc822
multipart/mixed
text/html
text/plain
text/plain
Oder es ist ein bisschen einfacher mit 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()
Das Ergebnis Enden (in GMail zumindest) die ursprüngliche Nachricht als zeigt „---- ---- Weitergeleitete Nachricht“, die nicht ganz das, was ich war nach, aber die allgemeine Idee funktioniert und ich hoffe, dass diese Antwort hilft jemand, um herauszufinden, wie man mit MIME-Nachrichten fiedeln.