Redirigez un email vers une autre application avec Postfix et PHP sous Mac OS X

Souvent certaines applications ne proposent que l’envoi d’un email comme procédé pour vous avertir d’un évènement, c’est le cas par exemple du logiciel de sauvegarde Carbon Copy Cloner.

Si vous souhaitez rediriger cet email vers un autre applicatif, il existe une petite astuce pour permettre la récupération de ce message et le transférer à un autre service.

L’idée : Filtrage Postfix

L’idée ici est d’envoyer le mail au compte mail local et charger le serveur Postfix du Mac de filtrer cet email reçu en le transmettant à un script qui se chargera du travail

  • ici en PHP.
    Le script PHP nécessite des librairies pour pouvoir lire convenablement le fichier MIME qu’il recevra.

    Envoi du mail > Filtrage Postfix > Script PHP > Redirection de la notification

Ensuite si l’objet de ce mail correspond à une certaine chaine de caractère

  • le message est transféré sous la forme d’une notification Push via Pushover et le mail est supprimé.

Si la chaine ne correspond pas

  • le script PHP se charge de transmettre le mail à bonne destination via sendmail.

Vous pouvez éditer cette partie si vous n’utilisez pas Pushover

  • vous pouvez transmettre le message à Boxcar
  • au centre de notification de Mac OS X
  • dans un fichier texte que vous afficherez sur le bureau avec GeekTool ou tout autre moyen qui vous vient à l’idée.

Votre email local

Pour récupérer le nom de votre compte email local

  • vous pouvez faire comme ça dans le terminal
  • c’est à cet email que vous enverrez le message :
1
echo "`whoami`@`hostname`"

Ce qui donnera quelque chose comme ça : utilisateur@nomdumac.local

Créer le script PHP

Installer MailParse

Tout d’abord

  • il faut installer l’extension PEAR MailParse nécessaire à la classe PHP pour décrypter le mail et ensuite inclure celle-ci dans le php.ini
1
2
3
4
5
sudo pear install pecl/mailparse
sudo vi /etc/php.ini

# Puis ajouter ceci au php.ini pour activer l'extension
extension=mailparse.so

Mime Mail Parser

Ensuite vous pouvez télécharger la classe qui va bien

  • disponible sur Google Code
  • pour parser le contenu de l’email et décrypter le MIME (PHP Mime Mail Parser) :

https://code.google.com/p/php-mime-mail-parser/

Programme PHP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/php

require_once('lib/MimeMailParser.class.php');

// Pushover
$token = "YOUR_APPLICATION_TOKEN";
$user_key = "YOUR_USER_KEY";
// Debug
$debug = false;
$debug_log_path = "/Users/YOUR_USERNAME/Desktop/";

// DEBUG : PHP Errors Output
if ($debug) {
ini_set("log_errors"
- 1);
ini_set("error_log"
- $debug_log_path."php-error.log");
}

// Read message from stdin
$fd = fopen("php://stdin"
- "r");
$email = "";
while (!feof($fd)) {
$line = fread($fd
- 1024);
$email .= $line;
}
fclose($fd);

// Parse mail message
$parser = new MimeMailParser();
$parser->parseSource($email
- 'string');
$Subject = iconv_mime_decode($parser->getHeader('subject'),0,"UTF-8");
$Body = trim($parser->getBody());
$To = $parser->getHeader('to');

if ($debug) {
// Write to Temp File
$file = fopen($debug_log_path."postfix-filter.log"
- "a");
fwrite($file
- "Script successfully ran at ".date("Y-m-d H:i:s")."\n");
$output = "To:".$To." - Subject:".$Subject."\n".$Body."\n-------\n";
fwrite($file
- $output);
fclose($file);
}

// Send notification and quit if subject match !
if (preg_match('/\[CCC\] Sauvegarde/',$Subject)) {
// Send Message with Pushover
curl_setopt_array($ch = curl_init()
- array(
CURLOPT_URL => "https://api.pushover.net/1/messages.json"
- CURLOPT_POSTFIELDS => array(
"token" => $token
- "user" => $user_key
- "device" => "iPhone"
- "sound" => "magic"
- "title" => $Subject
- "message" => $Body
)
));
$curlresult = curl_exec($ch);
curl_close($ch);
exit(0);
}

// Continue transfering the message via sendmail
$sendmail = '/usr/sbin/sendmail -G -i ' . $argv[2];
$handle = popen($sendmail
- 'w');
fwrite($handle
- $email);
$sendmail_return_value = pclose($handle);

Rendre le fichier exécutable et Test

1
2
3
4
# Rendre le fichier PHP exécutable
chmod a+x postfix-filter.php
# Par la suite pour tester vous pourrez faire comme ça :
postfix-filter.php SENDER RECIPIENT 0 < ~/Desktop/mime.mail.exemple.message.txt

Du côté de Postfix

Editez le fichier master.cf de Postfix

1
sudo vi /etc/postfix/master.cf

Ajoutez la règle de filtrage suivante :

1
2
smtpd     pass  -       -       n       -       -       smtpd
-o content_filter=myAwesomeFilter:dummy

Et à la fin du fichier ajoutez la ligne correspondant au filtre à appliquer

1
2
myAwesomeFilter   unix  -       n       n       -       -      pipe
flags=F user=YOUR_USERNAME argv=/path/to/the/script/postfix-filter.php ${size} ${sender} ${recipient}

Redémarrez Postfix

1
sudo postfix reload

Une fois les différents éléments du programme configurés avec vos paramètres

  • vous pouvez transmettre un mail via l’application externe à votre nom d’utilisateur.
    (Ne fonctionne pas dans cette configuration avec sendmail)

    Email : utilisateur@nomdumac.local
    Serveur : localhost
    Destinataire : utilisateur ou utilisateur@nomdumac.local

Pour déboguer le mail :

1
tail -f /var/log/mail.log

Vous devriez avoir une ligne du type

myMac.local postfix/pipe[8318]: 1778B30FDD0E: to=<username@myMac.local>, relay=myAwesomefilter, delay=1.6, delays=0.04/0.01/0/1.6, dsn=2.0.0, status=sent (delivered via myAwesomefilter service)

Liens