Ludovic ROLAND

Blog technique sur mes expériences de développeur.

Envoyer et recevoir des e-mails en Perl 5 (5/5) : Consulter ses e-mails via IMAP

10 août 2022

Dans le chapitre précédent, nous avons vu comment consulter ses e-mails via le protocole POP3. Il est grand temps de s’attaquer au second protocole, à savoir IMAP.

Plan

Installation du module Net::IMAP::Simple

Une nouvelle fois, nous allons utiliser un module issu de la bibliothèque libnet : Net::IMAP::Simple. Cependant, contrairement aux modules Net::POP3 et Net::SMTP, il n’est pas installé par défaut sur votre machine. C’est pourquoi nous allons devoir l’installer avant de voir plus en détails son fonctionnement !

Installation sous Linux

Il existe deux façons d’installer ce module : une installation manuelle et une installation automatique. Je vous laisse choisir celle que vous préférez !

Installation manuelle

Avant d’installer ce module, vous vous doutez bien qu’il va falloir le télécharger ! Pour ce faire, rendez-vous ici, puis cliquez sur le tout premier lien comme le montre la capture d’écran ci-dessous.

Regardez ensuite le côté droit de la page, puis cliquez sur Download afin de télécharger l’archive.

Un fois l’archive enregistrée sur votre ordinateur, ouvrez votre plus beau terminal et tapez successivement les commandes suivantes :

tar -xzvf Net-IMAP-Simple-xxx.tar.gz
cd Net-IMAP-Simple-xxx/
perl Makefile.PL
make
sudo make install

Installation automatique

Commencez par ouvrir un terminal, puis tapez la commande suivante :

sudo cpan

Après avoir saisi votre mot de passe, vous devriez avoir une nouvelle ligne dans l’invite de commandes de la forme :

cpan[1]>

Il vous suffit alors de lancer l’installation du module grâce à la commande :

install Net::IMAP::Simple

Installation sous Windows

Si vous utilisez Active Perl, ouvrez un terminal, puis tapez la commande suivante :

ppm

Vous devriez alors avoir une nouvelle ligne dans l’invite de commandes de la forme :

PPM>

Il vous suffit alors de lancer l’installation du module grâce à la commande :

install Net-IMAP-Simple

Maintenant que le module est installé, passons à sa présentation. ;)

Les différentes étapes

Tout comme pour le protocole POP3, la consultation de son courrier via le protocole IMAP nécessite un travail ordonné. Une nouvelle fois, nous pouvons découper ce travail en plusieurs étapes. Elles sont au nombre de 4 :

  • se connecter au serveur IMAP ;
  • s’identifier ;
  • consulter / gérer ses e-mails ;
  • quitter proprement le serveur.

Le module Net::IMAP::Simple

Afin d’implémenter ces 4 étapes, nous allons utiliser le module Net::IMAP::Simple. Ce module va nous permettre en fait de faire l’intermédiaire entre notre programme et le serveur avec lequel nous souhaitons communiquer.

Je vous propose de regarder immédiatement les quelques méthodes et fonctions qui nous serviront par la suite.

new() : instancier un objet

Le module Net::IMAP::Simple est un module orienté objet. Cette méthode lui sert donc de constructeur.

Cette méthode peut prendre plusieurs paramètres :

  • le serveur auquel on souhaite se connecter ;
  • le numéro du port auquel on souhaite se connecter ;
  • le mode débogage ;
  • durée limite pour établir la connexion.

login() : s’identifier

C’est grâce à cette fonction que l’on s’identifie auprès du serveur. Elle prend généralement 2 paramètres à savoir le nom d’utilisateur et un mot de passe. Contrairement à la même méthode du module Net::POP3, ici, le nombre d’e-mails n’est pas renvoyé de par l’architecture du protocole IMAP (possibilité d’avoir plusieurs boites au sein d’une adresse électronique).

select() : sélectionner une boite

Cette méthode permet de sélectionner la boite auquel on souhaite accéder. Le nom est passé en paramètre. Elle renvoie alors le nombre de messages présents dans la boite sélectionnée.

list() : lister les messages

Cette fonction fonctionne exactement comme celle du module Net::POP3.

Sans argument, cette méthode renvoie une référence à un hachage dont les clefs sont les numéros des messages sur le serveur, et les valeurs représentent la taille en octets du message.

Appelée avec un numéro de message en argument, cette méthode renvoie la taille du message en octets.

top() : obtenir l’en-tête d’un message

Tout comme la fonction du même nom du module Net::POP3, cette méthode permet de récupérer l’en-tête du message dont le numéro est passé en paramètre.

Grâce à cette fonction, il est également possible de récupérer les premières lignes d’un message. Pour ce faire, il suffit d’ajouter un second paramètre correspondant au nombre de ligne que l’on souhaite récupérer.

Quelque soit le nombre de paramètre, cette méthode renvoie le texte demandé sous la forme d’une référence à un tableau.

get() : obtenir le contenu d’un message

Cette méthode permet de récupérer le texte (en-tête et corps) du message dont le numéro est passé en paramètre. Le texte du message est alors renvoyé.

Il est également possible d’indiquer un descripteur de fichier comme second paramètre. Les lignes seront alors directement écrites dans le fichier.

seen() : connaître le statut d’un e-mail

Cette méthode permet de savoir si un message est marqué comme “lu” ou “non-lu”. Le numéro du message dont on souhaite connaître le statut est passé en paramètre.

Un booléen est alors renvoyé. Dans le cas d’un message “lu”, c’est la valeur vrai est renvoyée. Si un message est marqué comme “non-lu”, c’est la valeur “faux” qui est renvoyée.

delete() : supprimer un message

Cette méthode permet de marquer le message dont le numéro est passé en paramètre comme étant à effacer. La suppression des messages marqués s’effectue seulement si la connexion avec le serveur est fermée proprement.

reset() : remettre le serveur en état

Cette méthode permet de remettre le serveur dans l’état où il se trouvait au moment de notre connexion. Cette méthode est très utile si l’on veut supprimer les marqueurs de suppressions attribués à certains messages via la méthode delete(). Cette fonction ne prend pas de paramètre.

quit() : se déconnecter du serveur

Cette fonction permet de fermer proprement la connexion avec le serveur. Elle ne prend pas de paramètre.

mailboxes() : lister les boites

Sans paramètre, cette fonction permet de lister les boites présentes sur votre adresse électronique. Elle renvoie alors un tableau dans lequel le nom de chaque boite est la valeur d’une case du tableau.

create_mailbox() : créer une nouvelle boite

Cette fonction permet de créer une nouvelle boite sur votre adresse e-mail. Le nom de la boite à créer est à faire passer en paramètre. Cette fonction retourne vrai si la création a pu se faire, faux sinon.

rename_mailbox() : renommer une boite

Grâce à cette fonction, il est possible de renommer une boite existants. La syntaxe des paramètres est un peu particulière. L’ancien nom est suivi du symbole “=>” lui même suivi du nouveau nom.

$imap->rename_mailbox('ancien_nom' => 'nouveau_nom');

Elle renvoie vrai en cas de succès, faux sinon.

delete_mailbox() : supprimer une boite

Cette fonction permet de supprimer une boite de votre adresse électronique. Elle prend en paramètre le nom de la boite à supprimer. Comme les dernières fonctions vues, elle renvoie vrai en cas de succès, faux sinon.

Implémentation Perl

Maintenant que vous avez fait connaissance avec le module Net::IMAP::Simple, nous allons voir ensemble comment implémenter en Perl les 4 étapes décrites un plus haut.

Pour rappel, voici les 4 étapes que nous allons implémenter au cours de ce chapitre :

  • se connecter au serveur IMAP ;
  • s’identifier ;
  • consulter / gérer ses e-mails ;
  • quitter proprement le serveur.

C’est parti ! :pirate:

Étape 1 : se connecter au serveur IMAP

La première étape consiste donc à indiquer à notre programme Perl l’adresse du serveur auquel on souhaite se connecter. Si vous vous souvenez bien, c’est la méthode new() qui nous le permet. Pour rappel, voici quelques paramètres que peut prendre cette fonction :

  • le serveur auquel on souhaite se connecter ;
  • le numéro du port auquel on souhaite se connecter ;
  • le mode débogage ;
  • durée limite pour établir la connexion.

Dans l’exemple suivant, nous allons nous connecter au serveur IMAP de l’université Paris-Sud.

#!/usr/bin/perl -w

use strict;
use Net::IMAP::Simple;

#Étape 1
my $imap = Net::IMAP::Simple->new('imap.u-psud.fr') or die 'Impossible de se connecter au serveur : '.$!;

Comme à chaque fois, le or die permet de gérer les éventuelles exceptions renvoyée par notre programme. La variable $! nous indique la source exacte du problème.

Il est possible de faire passer d’autres paramètres à la méthode new() comme par exemple le mode débogage ou un temps limite de connexion. Le passage de ces nouveaux paramètres se fait sous la forme d’un tableau associatif.

Voyons tout de suite un exemple dans lequel nous les paramètres de limitation de temps et de sélection du port sont présents.

#!/usr/bin/perl -w

use strict;
use Net::IMAP::Simple;

#Étape 1
my $imap = Net::IMAP::Simple->new('imap.u-psud.fr', Timeout => 10, Port => 993) or die 'Impossible de se connecter au serveur : '.$!;

Le temps limite de connexion se donne en seconde. Ainsi, dans mon exemple, si au bout de 10 secondes le programme n’a pas réussi à se connecter au serveur, une exception sera levée, et la variable$!contiendra le message “Connexion terminée par expiration du délai d’attente”.

Toujours dans l’exemple précédent, j’indique à mon programme qu’il ne doit pas écouter le port par défaut, et lui indique donc le bon port à écouter.

Étape 2 : s’identifier

L’identification se fait grâce à la méthode login(). Comme je le disais dans la partie juste au dessus, nous faisons passer 2 paramètres : le nom d’utilisateur et le mot de passe.

#Étape 2
$imap->login('*****', '*****') or die 'Erreur d\'identification !';

Étape 3 : consulter / gérer ses e-mails

C’est dans cette étape que vous allez pouvoir lire vos mails et pourquoi pas en supprimer certains du serveur.

Dans un premier temps, nous allons devoir accéder à la boite qui contient nos e-mails et ce grâce à la méthode select(). Par défaut, ce dossier se nomme INBOX, c’est donc ce nom que nous allons faire passer en paramètre de notre méthode. Puisque cette méthode renvoie le nombre de messages présents dans la boite de réception, nous allons en profiter pour afficher l’information à l’écran.

#Étape 3
my $nbmsg = $imap->select('INBOX') or die 'Impossible d\'accéder à ce dossier !';
print 'Vous avez '.$nbmsg.' messages dans cette boite !';

Vous devriez alors obtenir quelque chose comme ça à l’écran :

> perl imap.pl
Vous avez 125 messages dans cette boite !

Maintenant que nous sommes dans la bonne boite, nous allons voir un exemple qui permet d’afficher à l’écran tous les mails non lus présents dans la boite. Pour ça, nous allons dans un premier temps utiliser la méthode list() afin d’obtenir l’identifiant de chacun des messages. Nous vérifierons ensuite que le message est bien marqué comme “non lu” grâce à la fonction seen(). Finalement; nous utiliserons la méthode get() afin de récupérer le contenu du message (en-tête et corps) puis nous l’afficherons à l’écran. Il conviendra de boucler sur les clefs contenues dans la table hachage renvoyée par la fonction list() afin de pouvoir vérifier tous les messages.

#On récupère la liste des messages
my $index = $imap->list() or die 'Impossible de lister les messages !';

#On boucle sur les messages
foreach my $msgnum (keys %$index) {
        #On vérifie l'état de lecture du message
    if(!$imap->seen($msgnum)) {
                #On affiche les messages non lus
        my $msg = $imap->get($msgnum) or die 'Impossible de récupérer le message n°'.$msgnum.' !';
        print $msg."\n\n";
    }
}

Étape 4 : quitter proprement le serveur

Nous voilà enfin à la dernière étape qui consiste à fermer proprement la connexion avec le serveur grâce à la méthode quit().

#Étape 4
$imap->quit() or die 'Un problème est survenu avec la méthode quit() !';

Pour résumer

Voici le code complet de ce que nous avons vu ensemble sur la consultation d’un e-mail en Perl via le module Net::IMAP::Simple :

#!/usr/bin/perl -w

use strict;
use Net::IMAP::Simple;

#Étape 1
my $imap = Net::IMAP::Simple->new('imap.u-psud.fr') or die 'Impossible de se connecter au serveur : '.$!;

#Étape 2
$imap->login('*****', '*****') or die 'Erreur d\'identification !';

#Étape 3
my $nbmsg = $imap->select('INBOX') or die 'Impossible d\'accéder à ce dossier !';

print 'Vous avez '.$nbmsg." messages dans ce dossier !\n\n";

my $index = $imap->list() or die 'Impossible de lister les messages !';

foreach my $msgnum (keys %$index) {
    if(!$imap->seen($msgnum)) {
        my $msg = $imap->get($msgnum) or die 'Impossible de récupérer le message n°'.$msgnum.' !';
        print $msg."\n\n";
    }
}  

#Étape 4
$imap->quit() or die 'Un problème est survenu avec la méthode quit() !';

La liste des méthodes données au cours de ce chapitre n’est évidemment pas une liste exhaustive ! S’il vous manque quelque chose, je vous encourage fortement à jeter un œil à la documentation officielle !

Commentaires