Pergunta

Estou usando atualmente imaplib Para buscar mensagens de email de um servidor e processar o conteúdo e os anexos.

Gostaria de responder às mensagens com uma mensagem de status/erro e links para o conteúdo gerado resultante no meu site, se eles puderem ser processados. Isso deve incluir a mensagem original, mas deve soltar qualquer anexo (que será grande) e, de preferência, substitua -os apenas por seus nomes de arquivos/tamanhos.

Como já estou andando nas peças da mensagem MIME, estou assumindo o que preciso fazer é criar uma nova árvore de mensagens MIME contendo uma cópia da mensagem original e excluir/substituir os nós de anexo.

Antes de começar esse caminho, eu esperava que alguém pudesse me dar algumas dicas. Existe algum tipo de função da biblioteca para fazer isso? Qualquer tipo de comportamento padrão que eu deveria manter?

Atualmente eu conheço/estou usando o imaplib, smtplib e email módulos e, mas pode ter perdido algo óbvio lá. Isso também está sendo executado em Django, então pode usar qualquer coisa em django.core.email Se isso facilita.

Foi útil?

Solução

A estrutura de árvore mímica original da mensagem de entrada é a seguinte (usando email.iterators._structure(msg)):

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

Responder via Gmail resulta na seguinte estrutura:

multipart/alternative
    text/plain
    text/html

Ou seja, eles não estão sendo tão inteligentes quanto eu pensava, apenas descartando os anexos (bons) e fornecendo versões de texto e HTML que reestruturam explicitamente o "conteúdo citado".

Estou começando a pensar que é tudo o que eu deveria fazer também, basta responder com uma mensagem simples, pois depois de descartar os anexos, não há muito sentido em manter a mensagem original.

Ainda assim, poderia muito bem responder à minha pergunta original, pois eu descobri como agora.

Primeiro, substitua todos os anexos na mensagem original por texto/espaço livre comum:

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

Em seguida, crie uma mensagem de resposta:

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"

Em seguida, anexe o objeto de mensagem MIME original e envie:

new.attach( MIMEMessage(original) )

s = smtplib.SMTP()
s.sendmail("me@mysite.com", [new["To"]], new.as_string())
s.quit()

A estrutura resultante é:

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

Ou é um pouco mais simples usando 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()

O resultado termina (pelo menos no Gmail) mostrando a mensagem original como "---- Mensagem encaminhada ----", o que não é exatamente o que eu estava procurando, mas a ideia geral funciona e espero Descubra como mexer com mensagens MIME.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top