Cet article fait suite à l’article sur rediriger les emails / email piping. Tous les emails envoyés vers [email protected] sont donc maintenant redirigés vers le script php que nous avons nommés mailpiping.php. Il devra donc lire ces emails, extraire les pièces jointes si besoin, et appliquer un traitement conditionnel. Vous adapterez ce dernier point en fonction de vos besoins, dans cet article on va surtout montrer comment récupérer, lire et décoder les emails.
Classe PHP pour lire les mails
Il est certain que vous pouvez coder vous-même votre script de lecture d’emails, mais pour qu’on soit tous sur le même pied d’égalité je vais vous indiquer une classe qui effectue ce travail, facile à utiliser, efficace et largement testée. Il s’agit de la classe Pear ::Mail_mimeDecode. Pour rappel, PEAR est un dépôt de packages PHP réutilisables dans un grand nombre de situations quotidiennes. Sur PEAR les packages n’y sont admis qu’après avoir été soumis à un contrôle qualité et que s’ils respectent un certain nombre de normes.
Installer un package PEAR est très facile, pour cela il y a déjà de la documentation en ligne :
http://pear.php.net/manual/en/guide.users.commandline.installing.php
Utilisation de Pear ::Mail_mimeDecode
Une fois mime_Decode installé sur votre serveur, vous l’incluez dans mailpiping.php en ajoutant :
require_once 'Mail/mimeDecode.php';
Vous pouvez maintenant récupérez l’email qui a été dirigé vers le script :
$fd = fopen("php://stdin", "r"); $email = ""; while (!feof($fd)) { $email .= fread($fd, 1024); } fclose($fd);
A la première ligne, fopen lit le flux qu’il reçoit sur l’entrée standard stdinn autrement dit le mail.
La boucle while sert à lire le flux par tranche de 1024 octets et à placer le tout dans la variable $emailcomplet.
Une fois terminé on ferme : fclose
$decoder = new Mail_mimeDecode($emailcomplet);
Il faut maintenant décoder avec la classe Mime_mailDecode ce qu’on vient de mettre dans $emailcomplet. Notre but c’est de transformer ce texte assez compliqué lorsqu’il y a une ou plusieurs pièces jointes en texte et fichier exploitable autrement.
$structure = $decoder->decode($params);
Cette méthode decode() de la classe Mail_mimeDecode, découpe le contenu brut en plusieurs éléments contenus dans une structure (texte normal, texte HTML, images et pièces jointes). decode() reçoit en paramètre un tableau qui lui indique ce qu’il doit faire avec le texte brut (voir le code au complet à la fin).
– include_bodies si on a besoin que le corps du mail soit inclut dans la structure
– decode_bodies si on a besoin que le corps du mail soit décodé
– decode_headers si on veut les entêtes du mail
$subject = $structure->headers['subject']; // on récupère l’objet de l’email $expediteur = $structure->headers['from']; // le nom de l’expéditeur et son email $message = $structure->parts['0']->body;
On aura dans la variable tableau $structure nos différents éléments. Facile non ?
Si vous voulez voir ce qu’elle contient exactement ajoutez un var_dump($structure);
– la troisième ligne c’est pour récupérer le message, en fait encore un tableau, le premier élément du tableau parts (d’où l’index zéro)
Il ne nous reste plus qu’à nous occuper des pièces jointes quand elles sont présentes.
foreach ($structure->parts as $part) { // sauvegarde si c'est une pièce jointe if (isset($part->disposition) && ($part->disposition=='attachment')) { $file_realname = $part->ctype_parameters['name']; $pathinfo = pathinfo($part->ctype_parameters['name']); $file_name = $file_realname; $fileobject = new SplFileObject($file_name, 'w'); // création fichier $fileobject->fwrite($part->body); // écriture dans le fichier } }
Pour chaque pièce jointe (attachment), nous récupérons son nom, il est précisé dans l’email brut à la ligne Content-Type contenu dans la variable ctype_parameters[‘name’] et ceci pour chaque élément du tableau $structure. Nous créons ensuite un objet SplFileObjet. La classe SplFileObjet permet de manipuler les fichiers en mode programmation par objet. Cette opération sera répétée autant de fois qu’il y a de pièces jointes dans l’email.
A la fin, vous aurez donc d’une part l’email de l’expéditeur et l’objet du message dans les variables $from et $subject respectivement, le message dans la variable $message et les pièces jointes éventuelles seront enregistrées dans le dossier.
Le code complet du script : mailpiping.php
Sans serveur mail pour tester il est tout de même possible de le faire en remplaçant le flux entrant stdin par le nom d’un fichier texte qui contiendra le source d’un email :
$fich = fopen('un-mail.txt', 'r');
Appelez ensuite le script depuis votre navigateur ou appelez le en ligne de commande, depuis le répertoire de travail
php mailpiping.php
.
Les pièces jointes vont apparaitre dans ce même répertoire.
Il ne vous restera plus qu’à compléter ce script selon la demande comme filtrer les pièces jointes, filtrer les emails provenant d’une liste préétablie d’expéditeurs, faire une réponse automatique selon le destinataire, etc…