Postfix: Lancer un script sur réception d’un e-mail

Salut,

Si vous tournez votre propre serveur de messagerie, comme c’est mon cas, il peut s’avérer utile de pouvoir lancer un script sur réception d’un e-mail (e-mail entrant). Dans cet article je vous propose de voir comment faire si votre serveur de messagerie est Postfix.

Il y a essentiellement deux façons de faire pour déclencher un script sur réception d’un e-mail, selon ce que vous souhaitez faire:

  1. Soit vous souhaitez déclencher un script sur réception d’un e-mail sur un compte mail bien spécifique, et uniquement celui-là. C’est ce cas d’usage, le plus simple, que je vais traiter dans cet article.
  2. Soit vous souhaitez traiter tout e-mail entrant avec votre script. Ce cas d’usage, un peu plus complexe dans sa configuration et dans son traitement n’est pas l’objet de cet article, mais vous pouvez jeter un œil ->ici<- tout y est bien expliqué.

Principe


La façon la plus simple pour déclencher un script sur réception d’un e-mail est créer un alias (un compte mail virtuel) dont le seul objectif est de déclencher le script. Le fichier /etc/aliases habituellement utilisé pour créer des alias de compte mail, propose également une syntaxe spécifique pour déclencher une commande (voir man /etc/aliases). On va donc éditer le fichier /etc/aliases, créer un alias nommé « bot » et lui faire correspondre un script :

[...]
bot: "|/path/to/script/mailBot.php"
[...]

Pour que postfix prenne en compte ce nouvel alias, il suffit de lancer la commande suivante :

arno@myserver:~$ sudo postalias hash:/etc/aliases

A partir de là, tout e-mail envoyé au compte « bot@your_domain.com » déclenchera le lancement du script /path/to/script/mailBot.php. J’ai pris comme exemple un script en PHP, mais vous pouvez parfaitement faire un simple script shell, ou dans tout autre langage. Ce qu’il est important de noter, c’est que le contenu de l’e-mail entrant est envoyé sur l’entrée standard (stdin) du script appelé, ce qui donne deux options, selon ce que vous souhaitez faire:

  1. Soit vous vous fichez du contenu du mail, celui-ci étant juste utilisé comme déclencheur du script. Dans ce cas, vous n’avez pas besoin d’un « parser » d’e-mail.
  2. Soit vous souhaitez analyser le contenu du mail pour déclencher une action spécifique en fonction du contenu. C’est personnellement l’usage que j’en ai, le contenu du mail (ou le sujet) contient une commande ainsi que les paramètres de cette commande. Il nous faut alors un moyen de « parser » l’e-mail. On s’appuiera alors sur les différentes bibliothèques disponibles dans le langage de programmation choisit, ou des bibliothèques externes.

Pour commencer, voyons un exemple de script minimaliste, en PHP, pour le script mailBot.php. On s’appuiera sur les quelques variables d’environnement mises à disposition par postfix avant l’appel du script (voir man local pour la liste complète) :

#!/usr/bin/php
<?php
$sender = getenv("SENDER");
$recipient = getenv("RECIPIENT");
file_put_contents ("/tmp/mail_rcpt.txt","Mail received from: ".$sender." for: ".$recipient);
?>

Voyons maintenant un deuxième exemple, dans lequel on s’intéresse au contenu de l’e-mail reçu. Il va nous falloir une bibliothèque de parsing d’e-mail en PHP. Mon choix s’est posé sur une bibliothèque assez  légère et facile à utiliser: PlancakeEmailParser. Ce qui nous donne le script suivant (sans contrôle d’erreur etc.):

#!/usr/bin/php
<?php
require_once("lib/PlancakeEmailParser.php");
$sender = getenv("SENDER");
$recipient = getenv("RECIPIENT");
$emailParser = new PlancakeEmailParser(file_get_contents("php://stdin"));
$emailSubject = $emailParser->getSubject();
$emailBody = $emailParser->getPlainBody();
file_put_contents ("/tmp/mail_rcpt.txt","Mail received from: ".$sender.PHP_EOL);
file_put_contents ("/tmp/mail_rcpt.txt","Mail received for: ".$recipient.PHP_EOL,FILE_APPEND);
file_put_contents ("/tmp/mail_rcpt.txt","Mail subject: ".$emailSubject.PHP_EOL,FILE_APPEND);
file_put_contents ("/tmp/mail_rcpt.txt","Mail body: ".$emailBody.PHP_EOL,FILE_APPEND);
?>

Jetez un oeil à la documentation de la lib PlancakeEmailParser, elle permet de faire d’autres petites choses qui pourraient vous intéresser.

Et voilà ! Have fun !

Vous aimez cet article ? Faites le savoir avec quelques bitcoins !

4 réflexions sur “Postfix: Lancer un script sur réception d’un e-mail

  1. Paschy 23 janvier 2018 / 0 h 47 min

    salut , moi j’ai fait un script en shell et j’ai suivi les différentes instructions mais celui-ci ne s’exécute pas lors de la réception du mail.Pouvez vous m’aidez?

    J’aime

  2. grégoire 12 janvier 2017 / 15 h 02 min

    Merci pour cet article, il m’a été très utile.
    Mais chez moi le script est systématiquement appelé deux fois a chaque réception de mai.
    Une idée d’où ça peut venir?

    ci dessous une partie des logs:

    Jan 12 14:36:13 localhost postfix/pipe[28432]: 0EFC4146640: to=, relay=spamassassin, delay=0.85, delays=0.33/0/0/0.52, dsn=2.0.0, status=sent (delivered via spamassassin service)
    Jan 12 14:36:13 localhost amavis[27810]: (27810-09) Passed CLEAN {RelayedInbound}, [1234.1234.1234.1234] -> , Message-ID: , mail_id: 4ABzwYRcrS32, Hits: -, size: 2648, queued_as: BCA48146640, 64 ms
    Jan 12 14:36:13 localhost postfix/smtp[28574]: AD89E1478B1: to=, relay=127.0.0.1[127.0.0.1]:10024, delay=0.08, delays=0.01/0/0/0.06, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as BCA48146640)
    Jan 12 14:36:13 localhost postfix/local[28647]: BCA48146640: to=, relay=local, delay=0.14, delays=0/0/0/0.13, dsn=2.0.0, status=sent (delivered to command: /var/www/script_cron/bot.php)
    Jan 12 14:36:14 localhost postfix/pipe[28586]: 0EDD014663E: to=, relay=spamassassin, delay=1.4, delays=0.33/0/0/1.1, dsn=2.0.0, status=sent (delivered via spamassassin service)
    Jan 12 14:36:14 localhost amavis[26238]: (26238-12) Passed CLEAN {RelayedInbound}, [1234.1234.1234.1234] -> , Message-ID: , mail_id: dbvwJqcgdKUB, Hits: -, size: 2648, queued_as: 51FD714663E, 65 ms
    Jan 12 14:36:14 localhost postfix/smtp[28574]: 42C9D146641: to=, relay=127.0.0.1[127.0.0.1]:10024, delay=0.08, delays=0.01/0/0/0.07, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as 51FD714663E)
    Jan 12 14:36:14 localhost postfix/local[28647]: 51FD714663E: to=, relay=local, delay=0.34, delays=0/0/0/0.34, dsn=2.0.0, status=sent (delivered to command: /var/www/script_cron/bot.php)

    J’aime

    • arno0x0x 12 janvier 2017 / 21 h 00 min

      Salut,

      Là comme ça je n’ai pas d’idée de quel pourrait être le problème. Est-il possible qu’avec les différents milter ou autre « cablâge » entre les divers composants mail, le mail passe deux fois par le MTA principal et donc déclenche deux fois le script ?

      J’aime

  3. xhark 20 février 2016 / 23 h 34 min

    Merci pour ce tuto, je l’attendais 🙂

    J’aime

Laisser un commentaire