2010-02-02 8 views
13

Actualmente estoy usando imaplib para obtener mensajes de correo electrónico de un servidor y procesar los contenidos y archivos adjuntos.¿Cómo respondo a un correo electrónico utilizando el imaplib de Python e incluyo el mensaje original?

Me gustaría responder a los mensajes con un mensaje de estado/error y enlaces al contenido generado resultante en mi sitio si pueden ser procesados. Esto debe incluir el mensaje original, pero debe eliminar los archivos adjuntos (que serán grandes) y preferiblemente reemplazarlos con solo sus nombres/tamaños de archivo.

Dado que ya estoy andando por las partes del mensaje MIME, supongo que lo que tengo que hacer es crear un nuevo árbol de mensajes MIME que contenga una copia del mensaje original y eliminar/reemplazar los nodos adjuntos.

Antes de comenzar ese camino, esperaba que alguien me diera algunos consejos. ¿Hay algún tipo de función de biblioteca para hacer esto? ¿Algún tipo de comportamiento estándar al que me debería apegar?

Actualmente sé de/estoy usando los módulos imaplib, smtplib y email y puede haber olvidado algo obvio allí. Esto también se está ejecutando en Django, por lo que puede usar cualquier cosa en django.core.email si eso lo hace más fácil.

Respuesta

14

La estructura de árbol MIME original del mensaje entrante es como sigue (usando email.iterators._structure(msg)):

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

En respuesta a través de los resultados de Gmail en el siguiente estructura:

multipart/alternative 
    text/plain 
    text/html 

es decir no están siendo tan inteligentes como pensaba, solo descartan los archivos adjuntos (buenos) y proporcionan versiones de texto y HTML que reestructuran explícitamente el "contenido citado".

Estoy empezando a pensar que eso es todo lo que debería hacer también, solo responda con un mensaje simple ya que después de descartar los archivos adjuntos no tiene mucho sentido mantener el mensaje original.

Aún así, podría responder a mi pregunta original ya que de todos modos he descubierto cómo hacerlo.

En primer lugar, vuelva a colocar todos los archivos adjuntos en el mensaje original con el texto/marcadores de posición de civil:

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

continuación, crear un mensaje de respuesta:

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

luego coloque el objeto de mensaje MIME original y enviar:

new.attach(MIMEMessage(original)) 

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

La estructura resultante es:

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

O que es un poco más sencillo el uso de 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() 

Los extremos resultado (en GMail al menos) que muestra el mensaje original como "mensaje reenviado ---- ----", que ISN' Es todo lo que buscaba, pero la idea general funciona y espero que esta respuesta ayude a alguien a tratar de descifrar cómo manipular los mensajes MIME.

+1

"Espero que esta respuesta ayude a alguien a tratar de descubrir cómo jugar con los mensajes MIME". ----- Seguro que sí. Gracias Tom! – aniketd

Cuestiones relacionadas