15 Ago 2016, uma peça de 14 minutos por Dev Mukherjee
Os serviços de Internet precisam de enviar e-mails aos seus utilizadores. Construir a mensagem é uma tarefa separada para enviar o e-mail. Este post demonstra a construção adequada de mensagens Multipurpose Internet Mail Extensions (MIME) em Python.
MIME mensagens têm muitos subtipos para encapsular diferentes tipos de conteúdo. A biblioteca MIME de e-mails Python fornece wrappers para trabalhar com eles. Estaremos explorando os seguintes subtipos para demonstrar como empacotar mensagens corretamente:
-
mixed
usado para enviar conteúdo de diferentes tipos, inline ou como anexos -
alternative
usado para enviar versões alternativas do mesmo conteúdo, por exemplo, texto simples de grupo e versões HTML de um corpo de e-mail -
related
usado para incluir recursos relacionados inline ou como anexos, por exemplo imagens usadas no seu conteúdo HTML
A mensagem de e-mail que criaremos neste post conterá:
- HTML e versões em texto puro do conteúdo do corpo
- Um arquivo anexado (que neste caso é um arquivo gerado
ICS
) - Obviamente ter uma imagem no conteúdo HTML
Comecemos por criar uma mensagem mixed
MIME multipartes que irá abrigar os vários componentes (corpo do e-mail, imagens exibidas inline e anexos para download) de nossa mensagem:
from email.mime.multipart import MIMEMultipart# By default the type is set to mixedmessage = MIMEMultipart()message = "Hello World"message = "Anomaly Support <[email protected]>"message = "Anomaly Reception <[email protected]>"# If a Reply-To is explicitly provided then the email client will# use this address when the user hit the reply button message = "Anomaly Support <[email protected]>"
>
HTML e conteúdo do corpo de texto simples
Criaremos uma mensagem alternative
com dois anexos, primeiro contendo a versão em texto simples da mensagem de e-mail seguida da versão HTML.
HTML e conteúdo de texto seriam normalmente produzidos com a ajuda de um motor de templates. Para os propósitos deste post eu assumo que você já gerou o conteúdo e ele está disponível como um Python str
variável.
A mensagem alternative
é criada instanciando um objeto MIMEMultipart
, desta vez pedindo ao construtor para usar o subtipo alternative
.
textual_message = MIMEMultipart('alternative')
Utilizar o helper MIMEText
para criar o texto puro e os anexos HTML.
from email.mime.text import MIMEText# I assume that you have a variable called txt_content# with the textual rendition of the message, this could# have been generated via a templating engineplaintext_part = MIMEText(txt_content, 'plain')textual_message.attach(plaintext_part)# likewise a variable called html_content with the HTMLhtml_part = MIMEText(html_content, 'html')textual_message.attach(html_part)
>
>
Recordar a mensagem alternative
ao pai mixed
mensagem para criar o corpo textual da mensagem de e-mail.
>
# Attach this to the mixed type messagemessage.attach(textual_message)
>
>
Anexo descarregável
Arquivos textuais ou binários podem ser anexados ao seu e-mail usando o ajudante MIMEApplication
. Ele é instanciado com o conteúdo do anexo seguido pelo tipo MIME do anexo, ou seja, para um application/pdf
você fornece a pdf
porção.
Por padrão, o conteúdo estaria contido na linha. Para fazer disto um anexo, use o método add_header
na instância MIMEApplication
e declare que é um anexo. Como o conteúdo do anexo é agora parte de uma mensagem codificada, você deve fornecer explicitamente meta-informações como um nome de arquivo.
from email.mime.application import MIMEApplicationpdf_file = MIMEApplication(pdf_file_data, "pdf")pdf_file.add_header('Content-Disposition', 'attachment', filename='report.pdf')
>
O MIMEApplication
helper automaticamente Base64
codifica o conteúdo quando eles são anexados às mensagens:
message.attach(pdf_file)
>
>>
Imagem opcional para uso no corpo HTML
Considerar uma imagem que você quer exibir no corpo do e-mail mas não quer oferecer ao destinatário para download. Você precisará usar uma mensagem related
para envolver o corpo do e-mail contido na mensagem alternate
que criamos anteriormente e anexar a mensagem related
ao original mixed
mensagem.
Você também precisará usar a subclasse MIMEImage
para garantir que a imagem seja codificada corretamente. A primeira coisa a fazer é criar um MIMEMultipart
mensagem do subtipo related
:
related_message = MIMEMultipart('related')
>
>
Criar uma instância de MIMEImage
que conterá o conteúdo da imagem:
from email.MIMEImage import MIMEImage# Content of an image that relates to the HTML messageimage = MIMEImage(image_binary_contents)# Lets you reference the image locally in HTMLimage.add_header('Content-ID', '<image1>')
>
Adicionar um cabeçalho Content-ID
permitirá referenciar a imagem no conteúdo HTML como <img src="cid:image1">
. Anexe a mensagem criada originalmente alternate
à mensagem related
seguida da mensagem MIMEImage
instance:
# Attach the alternative textural message to the # related messagerelated_message.attach(textual_message)# Attach the image to the related messagerelated_message.attach(image)
>
Anexe finalmente a mensagem related
à mensagem mixed
:
# Attach the related message to our parent messagemessage.attach(related_message)
>
Codificar e enviar o e-mail
Após ter misturado e combinado vários tipos e subtipos MIME
, a sua mensagem pode ser codificada chamando a função as_string
. Isto, por sua vez, pede a cada submensagem e anexo para se renderizar como uma mensagem coerente. O resultado é a string que você pode enviar sobre SMTP
como seu e-mail.
encoded_email = message.as_string()
smtplib
fornece um cliente SMTP
que pode entregar esta mensagem para você. É bastante simples. Dependendo da configuração da sua aplicação e servidor você pode escolher usar relés locais ou relés diretamente para um servidor SMTP disponível. Vou deixar isso para as necessidades específicas da sua aplicação.
from smtplib import SMTPsmtp = SMTP("localhost", 25)smtp.sendmail(message, message, encoded_email)smtp.quit()
>
Note: A diretiva Reply-To
não faz parte da carga útil SMTP; isso é tratado como parte da mensagem MIME
.
.