Pour Kyou-Sushi, un client de la société dans laquelle je bosse actuellent, nous avons mis au point une solution logiciel peu onéreuse et fun à développer. Je vous en reparlerai plus tard ☺. L'important ici, est de savoir que l'on doit être connecté quasiment en permanence à un serveur de messagerie pour y récupérer, à intervalle régulier, les nouveaux messages (les messages non lus).

Commençons par nous connecter à la boîte de messagerie :

# On utilise la version 4 du protocole sous le nom IMAP.
# Si plus tard il y a une version 5, il suffira de mettre cette seule ligne à jour.
from imaplib import IMAP4_SSL as IMAP
# Pour la gestion des erreurs de connexion
from socket import gaierror

# Configuration IMAP
server = 'mail.gandi.net'
user = 'username@domain'
password = 'password'

# Connexion au serveur IMAP
try:
    conn = IMAP(server)
    conn.login(user, password)
    conn.select()
except gaierror:
    # Le serveur IMAP est erroné ou injoignable
except IMAP.error:
    # Problème d'identification !
    # L'utilisateur et mot de passe sont-ils corrects ?

conn.select() permet de sélectionner le dossier où sont stockés les messages. Par défaut, on ne passe aucun argument, mais pour GMail, on pourrait utiliser conn.select('Inbox').

Nous allons maintenant récupérer les identifiants des messages non lus. Pour faire les choses correctement, nous utiliserons la commande uid() qui fonctionne avec des identifiants uniques pour chaque message.

ret, data = conn.uid('search', None, '(UNSEEN)')
if ret == 'OK':
    uids = data[0].split()

uids contiendra, par exemple, [b'9263', b'9264', b'9265'].

Pour finir, avec ces identifiants, téléchargeons le contenu des messages :

for uid in uids:
    ret, data = conn.uid('fetch', uid, '(BODY[TEXT])')
    if ret == 'OK':
        body = data[0][1]

Note : du moment que la commande fetch() est utilisée, le message concerné est marqué comme lu.


Commandes en vrac

1. Marquer un message comme lu :

conn.uid('store', uid, '+FLAGS', '(\\Seen)')

2. Marquer plusieurs messages comme lus :

conn.uid('store', ','.join(uids), '+FLAGS', '(\\Seen)')

3. Marquer un message comme non lu :

conn.uid('store', uid, '-FLAGS', '(\\Seen)')

4. Récupérer les messages non lus et ayant un sujet particulier :

ret, data = conn.uid('search', None, '(UNSEEN SUBJECT "Foo bar")')
if ret == 'OK':
    uids = data[0].split()

5. Récupérer les messages d'un certain émetteur :

ret, data = conn.uid('search', None, '(FROM "alice@example.org")')
if ret == 'OK':
    uids = data[0].split()

6. Récupérer les messages pour un certain destinataire :

ret, data = conn.uid('search', None, '(TO "bob@example.org")')
if ret == 'OK':
    uids = data[0].split()

7. Récupérer les messages d'un certain émetteur pour un certain destinataire :

ret, data = conn.uid('search', None, '(FROM "alice@example.org" TO "bob@example.org")')
if ret == 'OK':
    uids = data[0].split()

8. Récupérer les messages à partir d'une certaine date et ayant un sujet particulier :

day = '2016-09-06'
look_for = '(SENTSINCE {0} SUBJECT "Foo bar")'.format(
    datetime.strptime(day, '%Y-%m-%d').strftime('%d-%b-%Y'))

ret, data = conn.uid('search', None, look_for)
if ret == 'OK':
    uids = data[0].split()

9. GMail : récupérer les messages contenant une pièce jointe :

ret, data = conn.uid('search', None, '(X-GM-RAW "has:attachment")')
if ret == 'OK':
    uids = data[0].split()

10. Supprimer un ou plusieurs messages :

conn.uid("store", uids, "+FLAGS", "\\Deleted")
conn.expunge()

11. Copier un ou plusieurs messages dans le dossier folder :

conn.uid("copy", uids, folder)

12. Déplacer un ou plusieurs messages dans le dossier folder :

# Il n'y a pas de commande MOVE, if faut donc faire une copie puis supprimer l'original
# Étape 1 : utiliser la commande 11
# Étape 2 : utiliser la commande 10

Vous utilisez une commande particulière ? N'hésitez pas à la partager :)


Historique

  • 2018-09-23 : ajout des commandes en vrac 10, 11 et 12.
  • 2016-09-06 : ajout des commandes en vrac 2, 5, 6, 7, 8 et 9.

Source : Python — imaplib IMAP example with Gmail