2010-02-02 21 views
13

J'utilise actuellement imaplib pour récupérer des messages électroniques d'un serveur et traiter le contenu et les pièces jointes.Comment répondre à un e-mail en utilisant Python imaplib et inclure le message d'origine?

Je voudrais répondre aux messages avec un message d'état/erreur et des liens vers le contenu généré résultant sur mon site si elles peuvent être traitées. Cela devrait inclure le message d'origine mais devrait supprimer toutes les pièces jointes (qui seront volumineuses) et de préférence les remplacer par leurs noms de fichiers/tailles. Puisque je marche déjà les parties du message MIME, je suppose que ce que je dois faire est de construire un nouvel arbre de message MIME contenant une copie du message original et de supprimer/remplacer les nœuds de la pièce jointe. Avant de commencer ce chemin, j'espérais que quelqu'un puisse me donner quelques conseils. Existe-t-il une sorte de fonction de bibliothèque pour le faire? Quel genre de comportement standard je devrais suivre? Je connais actuellement/suis en train d'utiliser les modules imaplib, smtplib et email, mais j'ai peut-être manqué quelque chose d'évident là-dedans. Cela fonctionne aussi dans Django, donc peut utiliser n'importe quoi dans django.core.email si cela le rend plus facile.

Répondre

14

L'arborescence MIME d'origine du message entrant est le suivant (en utilisant email.iterators._structure(msg)):

multipart/mixed 
    text/html    (message) 
    application/octet-stream (attachment 1) 
    application/octet-stream (attachment 2) 

réponse via les résultats GMail dans la structure suivante:

multipart/alternative 
    text/plain 
    text/html 

à savoir ils ne sont pas aussi intelligents que je le pensais, simplement en rejetant les pièces jointes (bien) et en fournissant des versions texte et HTML qui restructurent explicitement le «contenu cité».

Je commence à penser que c'est tout ce que je devrais faire aussi, il suffit de répondre avec un message simple car après avoir jeté les pièces jointes, il n'y a pas grand intérêt à conserver le message original. Pourtant, peut-être aussi bien répondre à ma question initiale depuis que j'ai compris comment maintenant de toute façon.

D'abord, remplacer toutes les pièces jointes dans le message d'origine avec le texte/caractères génériques simples:

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"] 

Créez ensuite un message de réponse:

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]" 

Fixez ensuite l'objet de message MIME original et envoyer:

new.attach(MIMEMessage(original)) 

s = smtplib.SMTP() 
s.sendmail("[email protected]", [new["To"]], new.as_string()) 
s.quit() 

La structure résultante est la suivante:

multipart/mixed 
    multipart/alternative 
     text/plain 
     text/html 
    message/rfc822 
     multipart/mixed 
      text/html 
      text/plain 
      text/plain 

Ou il est un peu plus simple en utilisant 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() 

Les extrémités de résultat (en GMail au moins) montrant le message d'origine "---- ---- Transmis un message" qui n » Ce que je recherchais, mais l'idée générale fonctionne et j'espère que cette réponse aidera quelqu'un à essayer de comprendre comment manipuler les messages MIME.

+1

"J'espère que cette réponse aidera quelqu'un à comprendre comment manipuler les messages MIME." ----- C'est sûr. Merci Tom! – aniketd