15 agosto 2016, un pezzo di 14 minuti di Dev Mukherjee

La maggior parte dei servizi Internet ha bisogno di inviare email ai propri utenti. La costruzione del messaggio è un compito separato dall’invio dell’email. Questo post dimostra la corretta costruzione di messaggi Multipurpose Internet Mail Extensions (MIME) in Python.

I messaggi MIME hanno molti sottotipi per incapsulare diversi tipi di contenuto. La libreria MIME di Python fornisce dei wrapper per lavorare con essi. Esploreremo i seguenti sottotipi per dimostrare come confezionare correttamente i messaggi:

  • mixed usato per inviare contenuti di diverso tipo, in linea o come allegati
  • alternative usato per inviare versioni alternative dello stesso contenuto, per esempio raggruppare il testo semplice e le versioni HTML di un corpo di email
  • related usato per includere risorse correlate in linea o come allegati, per esempio immagini usate nel contenuto HTML

Il messaggio email che creeremo in questo post conterrà:

  • Versioni HTML e testo semplice del contenuto del corpo
  • Un file allegato (che in questo caso è un file generato ICS)
  • Optionally have an image in the HTML content

Iniziamo a creare un messaggio MIME mixed multipart che ospiterà i vari componenti (corpo della mail, immagini visualizzate in linea e allegati scaricabili) del nostro messaggio:

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 contenuto del corpo del testo semplice

Creeremo un messaggio alternative che ha due allegati, il primo contenente la versione di testo semplice del messaggio email seguito dalla versione HTML.

Il contenuto HTML e quello testuale sarebbero tipicamente prodotti con l’assistenza di un motore di template. Per gli scopi di questo post assumo che tu abbia già generato il contenuto e che sia disponibile come variabile Python str.

Il messaggio alternative viene creato istanziando un oggetto MIMEMultipart, questa volta chiedendo al costruttore di usare il sottotipo alternative.

textual_message = MIMEMultipart('alternative')

Usa l’helper MIMEText per creare gli allegati di testo semplice e 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)

Attacca il messaggio alternative al messaggio padre mixed per creare il corpo testuale del messaggio e-mail.

# Attach this to the mixed type messagemessage.attach(textual_message)

Allegato scaricabile

File testuali o binari possono essere allegati alla tua e-mail usando l’helper MIMEApplication. Viene istanziato con il contenuto dell’allegato seguito dal tipo MIME dell’allegato, cioè per un application/pdf si fornisce la porzione pdf.

Di default il contenuto sarebbe contenuto in linea. Per renderlo un allegato, usate il metodo add_header sull’istanza MIMEApplication e dichiarate che è un allegato. Poiché il contenuto dell’allegato è ora parte di un messaggio codificato, è necessario fornire esplicitamente meta informazioni come un nome di file.

from email.mime.application import MIMEApplicationpdf_file = MIMEApplication(pdf_file_data, "pdf")pdf_file.add_header('Content-Disposition', 'attachment', filename='report.pdf')

L’helper MIMEApplication codifica automaticamente Base64 i contenuti quando sono allegati ai messaggi:

message.attach(pdf_file)

Immagine opzionale da usare nel corpo HTML

Considera un’immagine che vuoi mostrare nel corpo della mail ma che non vuoi offrire al destinatario per il download. Avresti bisogno di usare un messaggio related per avvolgere il corpo dell’email contenuto nel messaggio alternate che abbiamo creato prima e allegare il messaggio related al messaggio originale mixed.

Ti servirà anche l’uso della sottoclasse MIMEImage per assicurarti che l’immagine sia codificata correttamente. Per prima cosa, crea un messaggio MIMEMultipart del sottotipo related:

related_message = MIMEMultipart('related')

Crea un’istanza di MIMEImage che conterrà il contenuto dell’immagine:

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>')

Aggiungendo un’intestazione Content-ID potrai fare riferimento all’immagine nel contenuto HTML come <img src="cid:image1">. Attacca il messaggio alternate creato originariamente al messaggio related seguito dall’istanza MIMEImage:

# Attach the alternative textural message to the # related messagerelated_message.attach(textual_message)# Attach the image to the related messagerelated_message.attach(image)

Finalmente attacca il messaggio related al messaggio mixed:

# Attach the related message to our parent messagemessage.attach(related_message)

Codifica e invio dell’e-mail

Una volta che hai mescolato e abbinato vari tipi e sottotipi MIME, il tuo messaggio può essere codificato chiamando la funzione as_string. Questa, a sua volta, chiede ad ogni sottomessaggio e allegato di rendersi come un messaggio coerente. Il risultato è la stringa che puoi inviare tramite SMTP come email.

encoded_email = message.as_string()

smtplib fornisce un client SMTP che può consegnare questo messaggio per te. È abbastanza semplice. A seconda della vostra applicazione e della configurazione del server, potete scegliere di usare relay locali o relay direttamente a un server SMTP disponibile. Lo lascerò alle esigenze specifiche delle vostre applicazioni.

from smtplib import SMTPsmtp = SMTP("localhost", 25)smtp.sendmail(message, message, encoded_email)smtp.quit()

Nota: La direttiva Reply-To non è parte del payload SMTP; è gestita come parte del messaggio MIME.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.