postfixがメールを受信した時にメールの内容をphpに渡して処理する方法の紹介です。メールを受信したときに、エイリアス(aliases)とパイプ(|)でメールの内容をphpに渡します。メールを解析するのにpearの「Mail_MimeDecode」を使います。「Mail_MimeDecode」インストール方法は、こちらのページ を参考にしてください。
テスト環境
「postfix」ユーザーでメールの処理をします。メールの解析を下記のフォルダー構成にしました。
/home/postfix/shell
/home/postfix/shell/image (←添付画像を格納するフォルダー)
/home/postfix/shell/index.php (←メールデータを解析するphp)
/home/postfix/shell/log.text (←解析した結果やエラーを吐き出すファイル)
Step 1 aliasesの設定
postfixのaliasesを有効にします。postfixの設定ファイル「main.cf」に「aliases」の設定を追記します。
[root@mail ~]# vi /etc/postfix/main.cf
alias_maps = hash:/etc/postfix/aliases
alias_database = hash:/etc/postfix/aliases
Step 2 各ユーザーのaliasesの設定
「aliases」ファイルに各ユーザーの設定を追加します。
[root@mail ~]# vi /etc/postfix/aliases
postfix: “| /home/postfix/shell/index.php” (←postfixユーザーはメールを受信できません)
postfix: postfix,”| /home/postfix/shell/index.php” (←postfixユーザーにメールも送る)
Step 3 上記の設定を有効にする(postfixの再起動)
[root@mail ~]# postalias /etc/postfix/aliases
[root@mail ~]# /etc/init.d/postfix restart
Step 4 解析用phpファイルの準備
下記の様な簡単な解析プログラムを作りました。メールの内容は、「log.text」に保管され、添付画像は、「image」に連番で保管されます。
「index.php」のソース
#! /usr/local/bin/php -q
<?php
require_once(“Mail/mimeDecode.php”);
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$params['input'] = file_get_contents(“php://stdin”);
$params['crlf'] = “\r\n”;
$mail_data = Mail_mimeDecode::decode($params);
$num = 1;
switch (strtolower($mail_data->ctype_primary)) {
case “text”:
$body = $mail_data->body;
break;
case “multipart”:
foreach ($mail_data->parts as $part) {
switch (strtolower($part->ctype_primary)) {
case “text”:
$body = $part->body;
break;
case “image”:
// 画像の拡張子を取得する
$type = strtolower($part->ctype_secondary);
// 添付ファイル保存
$tmpName = ‘/home/postfix/shell/image/’.date(YmdHis).’_’.$num.’.’.$type;
if ($fp = fopen($tmpName, “w”)) {
$length = strlen($part->body);
fwrite($fp,$part->body,$length);
fclose($fp);
$num++;
exec(“/bin/chown -R postfix:postfix “.$tmpName);
exec(“/bin/chmod 666 “.$tmpName);
}
break;
}
}
break;
default:
$body = “”;
}
$log = print_r($mail_data,true);
file_put_contents(‘/home/postfix/shell/log.text’, $log);
?>
最初の一行めの「#! /usr/local/bin/php -q」は、このファイルがphpとして実行する命令分です。よく忘れるので注意してください。ただし、命令文を「aliases」側に記述した場合は削除してください。今回は使っていませんが、メールの本文は、「$body」にあります。
(注意)
今回のメール処理で注意していただきたいことですが、メールの処理は、postfixユーザーが処理をするので、各ファイル、フォルダーのユーザ権限をpostfixユーザが読み書き出きるように設定してください。テスト環境でしたら、権限「777」でも良いかも・・・・
(こんなエラーには)
エイリアスの設定を変更した時に、下記の様なエラーで苦戦しました。
[root@mail ~]# tail -n 100 /var/log/maillog
Mar 9 11:12:45 mail postfix/postfix-script[15596]: warning: /usr/lib/sendmail and /usr/sbin/sendmail differ
Mar 9 11:12:45 mail postfix/postfix-script[15597]: warning: Replace one by a symbolic link to the other
対処方法
[root@mail ~]# mv /usr/sbin/sendmail /usr/sbin/sendmail.bak
[root@mail ~]# ln -s /usr/lib/sendmail /usr/sbin/sendmail
(反省 )
今回は、かなり苦戦しました。上記に書いたようにユーザ権限を間違えていたため、postfixのエイリアスの設定はうまくいっているのに、メールの内容をphpに渡せない状態が続き調べるのに苦労しました。