Envoyer des e-mails avec Gmail, Python et Flask

March 03, 2018
Rédigé par

Envoyer des e-mails avec Gmail, Python et Flask

Mise à jour 2019 :

Google a annoncé la limitation de l'accès à des applications moins sécurisées afin de protéger les comptes G Suite, ce qui signifie que vous rencontrerez de plus en plus de problèmes lors de l'envoi d'e-mails avec Gmail. Consultez ce post pour savoir comment envoyer des e-mails en Python avec Sendgrid pour une alternative basée sur API.

Nous avons tous fait face à ce problème : envoyer simplement un e-mail à partir d'une application. Peut-être pour une réinitialisation de mot de passe ou une notification de produit. Si vous lisez ceci, c'est probablement parce que vous avez atteint ce point. Quel que soit votre cas d'utilisation, ce post vous explique comment envoyer un e-mail en code à l'aide d'un bon vieux compte Gmail. Je vais également vous montrer comment corriger certaines erreurs courantes que vous êtes suscetibles de rencontrer en chemin.

Ce dont vous aurez besoin

Pour coder en suivant ce post, vous aurez besoin de :

Dans un nouveau dossier, créez un fichier requirements.txt. Ce fichier vous aidera à gérer vos dépendances dans un projet Python. Nous n'avons qu'une seule dépendance pour ce projet ; ajoutez ce qui suit à votre fichier requirements.txt :

Flask-Mail

Vous pouvez en savoir plus sur Flask-Mail dans leur documentation. Nous pouvons maintenant configurer notre virtualenv, un outil Python qui aide à gérer les dépendances, et installer nos exigences avec les commandes suivantes :

$ virtualenv env
$ source env/bin/activate
$ pip install -r requirements.txt

Envoi d'un e-mail avec du code

Nous devons commencer par configurer notre application. Dans un nouveau fichier (j'ai appelé le mien send.py), ajoutez le code suivant :

from flask import Flask
from flask_mail import Mail, Message
import os

app = Flask(__name__)

mail_settings = {
    "MAIL_SERVER": 'smtp.gmail.com',
    "MAIL_PORT": 465,
    "MAIL_USE_TLS": False,
    "MAIL_USE_SSL": True,
    "MAIL_USERNAME": os.environ['EMAIL_USER'],
    "MAIL_PASSWORD": os.environ['EMAIL_PASSWORD']
}

app.config.update(mail_settings)
mail = Mail(app)

Enregistrez votre EMAIL_USER, qui est votre identifiant complet tel que « mycoolemail@gmail.com », et EMAIL_PASSWORD en tant que variables d'environnement. Ainsi, nous ne codons pas les identifiants dans notre application. Pour en savoir plus sur la définition des variables d'environnement dans votre système d'exploitation, consultez cet article pratique.

Nous pouvons maintenant envoyer un e-mail ! Sous votre code de configuration, ajoutez ce qui suit :

if __name__ == '__main__':
    with app.app_context():
        msg = Message(subject="Hello",
                      sender=app.config.get("MAIL_USERNAME"),
                      recipients=["<recipient email here>"], # replace with your email for testing
                      body="This is a test email I sent with Gmail and Python!")
        mail.send(msg)

Veillez à remplacer la liste des destinataires par une liste contenant uniquement votre adresse e-mail pour pouvoir la tester.

Exécutez le programme en saisissant python send.py dans votre terminal et avec un peu de chance (je vais vous expliquer plus en détail ci-dessous) vous devriez recevoir un e-mail à l'adresse du destinataire que vous avez saisi.

CEPENDANT, il est fort probable que cela ne fonctionne pas ; vous recevrez alors un e-mail comme celui-ci.

alerte de vérification de tentative de connexion bloquée

Si vous obtenez une erreur smtplib.SMTPAuthenticationError, vous devrez configurer quelques éléments dans votre compte Google.

Piratage de la sécurité Gmail

OK, bien que tout cela soit légitime, Google ne l'encourage pas et a mis en place plusieurs paramètres que nous allons devoir reconfigurer.

Mettez à jour les éléments suivants dans les paramètres de sécurité de votre compte.

1. Autoriser les applications moins sécurisées : ACTIVÉ. (https://myaccount.google.com/lesssecureapps)

Par défaut, Google bloque les connexions des applications non sécurisées. Cela inclut probablement celle qui s'exécute sur votre ordinateur portable ou que vous avez déployée sur un serveur Heroku aléatoire.

Notez que cela ne fonctionnera pas avec les comptes pour lesquels l'A2F (authentification à double facteur) est activée, et ne désactivez pas l'A2F sur votre messagerie électronique. Vous pouvez utiliser un compte distinct ou créer des mots de passe propres à l'application.

2FA sur google

Cela suffira *peut-être*, mais si vous obtenez toujours des erreurs d'authentification, essayez ce qui suit :

2. Afficher le Captcha de déverrouillage. (https://accounts.google.com/DisplayUnlockCaptcha)

Enfin, l'accès IMAP vous permettra de stocker une copie de l'e-mail envoyé dans votre dossier de courrier envoyé.

3. Activer l'accès IMAP(https://mail.google.com/mail/#settings/fwdandpop)

acces imap

Essayez à nouveau d'exécuter votre application et cette fois-ci, elle devrait fonctionner. Si vous obtenez toujours des erreurs, vérifiez que l'autorisation pour les applications moins sécurisées est activée, car il arrive que Gmail la désactive à nouveau. Patientez un instant, puis réessayez.

Pourquoi n'est-ce pas une API ?

Google offre un service gratuit, et les services gratuits sont des aimants à fraude. Les fonctions de sécurité qu'ils ont mises en œuvre visent à décourager les gens d'abuser de leur serveur de messagerie. Ils l'ont rendu assez embêtant à utiliser pour que je me résigne à passer à une solution plus facile à entretenir pour des projets plus importants.

L'option Gmail est idéale pour envoyer quelques e-mails pour un projet secondaire, mais je vous encourage à consulter un service comme SendGrid. SendGrid fournit une API similaire à Twilio pour l'envoi d'e-mails et affiche des messages d'erreur beaucoup plus agréables lorsque les choses se passent mal.

Vous pouvez trouver le code de cette application sur mon Github. Avez-vous intégré les e-mails à votre application ? Retrouvez-moi sur Twitter @kelleyrobinson ou laissez-moi un commentaire pour me faire savoir ce qui a fonctionné (et ce qui n'a pas fonctionné !) pour vous.