¿Cómo respondo a un correo electrónico utilizando el imaplib Python e incluir el mensaje original?

StackOverflow https://stackoverflow.com/questions/2182196

Pregunta

Actualmente estoy usando imaplib en busca de mensajes de correo electrónico desde un servidor y procesar la contenidos y archivos adjuntos.

Me gustaría responder a los mensajes con un mensaje de estado / error y enlaces a los contenidos generados como resultado en mi sitio si pueden ser procesados. Esto debe incluir el mensaje original, pero debe bajar los archivos adjuntos (que será grande) y preferiblemente reemplazarlos con sólo sus nombres de archivo / tamaños.

Desde ya estoy caminando por las partes del mensaje MIME, asumo lo que tengo que hacer es construir un nuevo árbol mensaje MIME que contiene una copia del mensaje original y borrar / reemplazar los nodos de conexión.

Antes de empezar por ese camino, yo estaba esperando que alguien me puede dar algunos consejos. ¿Hay algún tipo de función de biblioteca para hacer esto? Cualquier tipo de comportamiento estándar que debería atenerse a?

Actualmente no conozco / AM utilizando las imaplib, módulos y smtplib email y aunque puede haber perdido algo obvio en ese país. Esto se ejecuta en Django también, así que puede usar cualquier cosa en django.core.email si eso hace que sea más fácil.

¿Fue útil?

Solución

La estructura de árbol MIME original del mensaje entrante es de la siguiente manera (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. que no están siendo tan inteligente como pensaba, simplemente descartando los archivos adjuntos (bueno) y la disponibilidad para las versiones de texto y HTML que explícitamente reestructurar el "contenido citado."

Me estoy empezando a pensar que es todo lo que debería hacer también, sólo responder con un mensaje simple como después de descartar los archivos adjuntos no hay mucho sentido mantener el mensaje original.

Sin embargo, como bien podría responder a mi pregunta original desde que he descubierto la manera de ahora de todos modos.

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

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

A 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"] = "me@mysite.com"

A continuación, adjuntar el objeto de mensaje MIME original y enviar:

new.attach( MIMEMessage(original) )

s = smtplib.SMTP()
s.sendmail("me@mysite.com", [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", 
                             "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()

Los extremos de Resultados (en Gmail, por lo menos) que muestra el mensaje original como "mensaje reenviado ---- ----", que no es exactamente lo que estaba buscando, pero la idea general de obras y espero que esta respuesta ayuda alguien tratando de encontrar la manera de jugar con los mensajes MIME.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top