postfixで受信したメールをphpにわたしメールを解析する

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に渡せない状態が続き調べるのに苦労しました。

Leave a comment