L'automatisation de l'envoi de courriels est une tâche courante en développement backend. Python facilite cette opération grâce à sa bibliothèque satndard smtplib, qui encapsule le protocole SMTP, et au module email pour la construction des messages.
Compréhension des protocoles de messagerie
Avant de manipuler le code, il est essentiel de distinguer les protocoles qui régissent les échanges de courriels :
- SMTP (Simple Mail Transfer Protocol) : Gère l'envoi et le routage des messages entre le client et le serveur, ou entre deux serveurs de messagerie.
- POP3 (Post Office Protocol) : Permet à un client de récupérer les messages stockés sur le serveur, souvent en les supprimant après téléchargement local.
- IMAP (Internet Message Access Protocol) : Contrairement à POP3, IMAP synchronise l'état des messages (lus, non lus, dossiers) entre le serveur et plusieurs clients simultanément.
Configuration du serveur SMTP
Pour envoyer des e-mails sans héberger votre propre serveur de messagerie, vous pouvez utiliser les services SMTP de fournisseurs tiers (comme Gmail, Outlook, ou Yahoo). Pour des raisons de sécurité, ces services exigent généralement un mot de passe d'application (ou code d'autorisation) plutôt que votre mot de passe de connexion standard. Ce code doit être généré depuis les paramètres de sécurité de votre compte de messaegrie.
Envoi d'un e-mail en texte brut
Depuis Python 3.6, l'utilisation de la classe EmailMessage du module email.message est recommandée car elle simplifie grandement la création de messages par rapport aux anciennnes classes MIME. Voici comment envoyer un message textuel simple en utilisant une connexion sécurisée SSL :
import smtplib
from email.message import EmailMessage
# Configuration du serveur
SMTP_SERVER = "smtp.example.com"
SMTP_PORT = 465 # Port standard pour SMTP_SSL
SMTP_USER = "votre_email@example.com"
APP_PASSWORD = "VOTRE_MOT_DE_PASSE_APPLICATION"
# Création du message
msg = EmailMessage()
msg['Subject'] = "Test d'envoi automatisé"
msg['From'] = f"Expéditeur <{SMTP_USER}>"
msg['To'] = "destinataire@example.com"
msg.set_content("Bonjour, ceci est un message de test envoyé via Python.")
# Envoi sécurisé
try:
with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as server:
server.login(SMTP_USER, APP_PASSWORD)
server.send_message(msg)
print("E-mail texte envoyé avec succès.")
except smtplib.SMTPException as e:
print(f"Erreur lors de l'envoi : {e}")
Envoi d'un e-mail au format HTML
Pour enrichir la mise en forme, vous pouvez intégrer du HTML. Il est fortement conseillé de fournir une version texte de secours pour les clients de messagerie qui ne supportent pas le rendu HTML.
import smtplib
from email.message import EmailMessage
# ... (Configuration SMTP identique à l'exemple précédent) ...
msg = EmailMessage()
msg['Subject'] = "Rapport d'activité hebdomadaire"
msg['From'] = SMTP_USER
msg['To'] = "destinataire@example.com"
# Version texte de secours
msg.set_content("Votre client ne supporte pas le HTML. Voici le rapport en texte brut.")
# Contenu HTML
html_template = """\
<html>
<body>
<h2 style="color: #2a9df4;">Rapport Hebdomadaire</h2>
<p>Voici le résumé des <strong>performances</strong> de la semaine.</p>
<ul>
<li>Tâches complétées : 42</li>
<li>Incidents résolus : 3</li>
</ul>
</body>
</html>
"""
msg.add_alternative(html_template, subtype='html')
with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as server:
server.login(SMTP_USER, APP_PASSWORD)
server.send_message(msg)
Intégration d'images locales dans le HTML
Plutôt que d'héberger des images sur un serveur distant et de risquer qu'elles soient bloquées par les filtres anti-spam, vous pouvez les intégrer directement dans l'e-mail via un identifiant de contenu (CID).
import smtplib
from email.message import EmailMessage
# ... (Configuration SMTP et création de msg) ...
msg.set_content("Message avec image intégrée.")
html_content = """\
<html>
<body>
<h1>Présentation du produit</h1>
<img src="cid:logo_entreprise" alt="Logo">
</body>
</html>
"""
msg.add_alternative(html_content, subtype='html')
# Ajout de l'image à la partie alternative (HTML)
with open('logo.png', 'rb') as image_file:
image_data = image_file.read()
# On accède à la partie alternative pour y attacher l'image liée
html_part = msg.get_payload()[-1]
html_part.add_related(
image_data,
maintype='image',
subtype='png',
cid='logo_entreprise'
)
with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as server:
server.login(SMTP_USER, APP_PASSWORD)
server.send_message(msg)
Ajout de pièces jointes de divers formats
La méthode add_attachment permet d'attacher facilement n'importe quel type de fichier binaire ou texte. Le client de messagerie du destinataire utilisera le type MIME et l'extension pour déterminer comment traiter le fichier reçu.
import smtplib
from email.message import EmailMessage
# ... (Configuration SMTP et création de msg) ...
msg.set_content("Veuillez trouver les documents demandés en pièce jointe.")
msg['Subject'] = "Envoi de documents multiples"
# Liste des fichiers à joindre avec leurs types MIME correspondants
attachments = [
("rapport_financier.pdf", "application", "pdf"),
("donnees_brutes.csv", "text", "csv"),
("archive_projet.zip", "application", "zip"),
("photo_equipe.jpg", "image", "jpeg")
]
for filename, maintype, subtype in attachments:
try:
with open(filename, 'rb') as f:
file_data = f.read()
msg.add_attachment(
file_data,
maintype=maintype,
subtype=subtype,
filename=filename
)
except FileNotFoundError:
print(f"Le fichier {filename} est introuvable et a été ignoré.")
with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as server:
server.login(SMTP_USER, APP_PASSWORD)
server.send_message(msg)
print("E-mail avec pièces jointes envoyé.")