15 août 2016, un morceau de 14 minutes par Dev Mukherjee

La plupart des services Internet ont besoin d’envoyer des emails à leurs utilisateurs. La construction du message est une tâche distincte de l’envoi de l’email. Ce post démontre la construction correcte des messages MIME (Multipurpose Internet Mail Extensions) en Python.

Les messages MIME ont de nombreux sous-types pour encapsuler différentes sortes de contenu. La bibliothèque MIME de messagerie de Python fournit des wrappers pour travailler avec eux. Nous allons explorer les sous-types suivants pour démontrer comment emballer les messages correctement :

  • mixed utilisé pour envoyer du contenu de différents types, en ligne ou en tant que pièces jointes
  • alternative utilisé pour envoyer des versions alternatives du même contenu, par exemple grouper le texte brut et les versions HTML du corps d’un courriel
  • related utilisé pour inclure des ressources connexes en ligne ou en tant que pièces jointes, par ex. les images utilisées dans votre contenu HTML

Le message électronique que nous allons créer dans ce post contiendra :

  • Des versions HTML et texte brut du contenu du corps
  • Un fichier joint (qui dans ce cas est un fichier ICS généré)
  • Optionnellement avoir une image dans le contenu HTML

Commençons par créer un message MIME multipart mixed qui abritera les différents composants (corps du courriel, images affichées en ligne et pièces jointes téléchargeables) de notre message :

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

Contenu du corps en texte brut et en HTML

Nous allons créer un message alternative qui comporte deux pièces jointes, la première contenant la version en texte brut du message électronique suivie de la version HTML.

Le contenu HTML et texte serait typiquement produit avec l’aide d’un moteur de templating. Pour les besoins de ce post, je suppose que vous avez déjà généré le contenu et qu’il est disponible en tant que variable Python str.

Le message alternative est créé en instanciant un objet MIMEMultipart, cette fois en demandant au constructeur d’utiliser le sous-type alternative.

textual_message = MIMEMultipart('alternative')

Utilisez l’aide MIMEText pour créer les pièces jointes en texte brut et en 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)

Attachez le message alternative au message parent mixed pour créer le corps textuel du message électronique.

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

Pièce jointe téléchargeable

Des fichiers textuels ou binaires peuvent être joints à votre courriel en utilisant l’aide MIMEApplication. Il est instancié avec le contenu de la pièce jointe suivi du type MIME de la pièce jointe c’est-à-dire que pour un application/pdf vous lui fournissez la portion pdf.

Par défaut le contenu serait contenu en ligne. Pour en faire une pièce jointe, utilisez la méthode add_header sur l’instance MIMEApplication et déclarez qu’elle est une pièce jointe. Comme le contenu de la pièce jointe fait maintenant partie d’un message codé, vous devez fournir explicitement des méta-informations comme un nom de fichier.

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

L’aide MIMEApplication encode automatiquement Base64 le contenu lorsqu’il est joint aux messages :

message.attach(pdf_file)

Image optionnelle à utiliser dans le corps HTML

Pensez à une image que vous voulez afficher dans le corps du courriel mais que vous ne voulez pas offrir au destinataire pour téléchargement. Vous auriez besoin d’utiliser un message related pour envelopper le corps du courriel contenu dans le message alternate que nous avons créé plus tôt et attacher le message related au message mixed original.

Vous aurez également besoin de l’utilisation de la sous-classe MIMEImage pour vous assurer que l’image est encodée correctement. Tout d’abord, créez un message MIMEMultipart de sous-type related:

related_message = MIMEMultipart('related')

Créez une instance de MIMEImage qui contiendra le contenu de l’image:

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

Ajouter un en-tête Content-ID vous permettra de référencer l’image dans le contenu HTML en tant que <img src="cid:image1">. Attachez le message alternate créé initialement au message related suivi de l’instance MIMEImage:

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

Enfin, attachez le message related au message mixed :

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

Encodage et envoi du courriel

Une fois que vous avez mélangé et assorti divers types et sous-types MIME, votre message peut être encodé en appelant la fonction as_string. Celle-ci, à son tour, demande à chaque sous-message et pièce jointe de se rendre en un seul message cohérent. Le résultat est la chaîne que vous pouvez envoyer sur SMTP comme votre courriel.

encoded_email = message.as_string()

smtplib fournit un client SMTP qui peut délivrer ce message pour vous. C’est assez simple. Selon la configuration de votre application et de votre serveur, vous pouvez choisir d’utiliser des relais locaux ou de relayer directement vers un serveur SMTP disponible. Je laisserai cela aux besoins spécifiques de vos applications.

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

Note : La directive Reply-To ne fait pas partie de la charge utile SMTP ; elle est traitée comme faisant partie du message MIME.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.