エラーメールの処理


MTAなどからキックしたエラーメールを、phpで標準入力から受け取って、メールアドレスを抽出して、emailリストから削除したりする際の処理のサンプル。

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";

$structure = Mail_mimeDecode::decode($params);
if( !count($structure->headers) ){
  trigger_error('invalid email format');
  exit;
}

$body = array();
if( isset($structure->parts) &&  is_array($structure->parts) ){
  foreach($structure->parts as $part){
    if(!isset($part->body) || !$part->body){
      continue;
    }
    if(isset($part->ctype_parameters['charset']) && $part->ctype_parameters['charset']){
      $body[] = mb_convert_encoding(
        $part->body,
        "UTF-8",
        $part->ctype_parameters['charset']
      );
    }else{
      $body[] = $part->body;
    }
  }
}else{
  $body[] = mb_convert_encoding(
    $structure->body,
    "UTF-8",
    $structure->ctype_parameters['charset']
  );
  $body[] = $structure->body;
}

$email = false;
foreach($body as $b){
  if($str = getemail($b)){
    $email = $str;
  }
}

if($email){
 // エラーメールアドレス$emailに対する処理
}

exit;

function getemail($body){
  $email = false;
  $regex  = "[-!#$%&\'*+\\./0-9A-Z^_`a-z{|}~]";
  $regex .= "+@[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]";
  $regex .= "+\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]";
  $regex .= "+";
  switch (true) {
    case (eregi("To:[ \t]*([^\n]+)",                      $body, $lineMatch)):
    case (eregi("Final-Recipient: RFC822;[ \t]*([^\n]+)", $body, $lineMatch)):
    case (eregi("<[ \t]*([^\n]+)>: user unknown",         $body, $lineMatch)):
      eregi($regex, $lineMatch[1], $strMatch);
      $email = $strMatch[0];
      break;
    case (eregi("次のあて先へのメッセージはエラーのため送信できませんでした", $body, $lineMatch)):
      eregi("<[ \t]*([^\n]+)>", $body, $regs);
      eregi($regex, $lineMatch[1], $strMatch);
      $email = $strMatch[0];
      break;
    default:
      break;
  }
  return $email;
}

関連する記事

7 thoughts on “エラーメールの処理

  1. Pingback: 空メールを実装する « Ks web Design

  2. はじめまして。
    試行錯誤中、こちらのサンプルを試させてもらったら、問題なく動作しました。

    MYSQL に接続して、エラーメール回数のフラグテーブルを+1処理し、
    5回で削除あるいは送信リストから除外されるフラグ付加という事を考えています。

    すばらしいです。
    本当にありがとうございました。

  3. お世話になります。
    PHPの初心者です。
    この情報を大変参考になりました。ありがとうございます。
    一つを聞きしたいんですが、switch文の中の4つのcase文についてちょっと分かりませんが、ご説明頂ければ幸いです。
    宜しくお願いします。

  4. @pisces

    はじめまして、pisces様

    以下かなり省略した説明になりますが(笑)
    このサンプルはエラーメールをPHPでうけとって、データベース(メルマガの配信リストなど)から、エラーがあったメールアドレスを削除するためのものです。

    エラーメールのフォーマットは、メールサーバーによって違うため、メールアドレスを抽出するためにこのswitch文のような処理をしています。
    たぶん、疑問に思われたのは4つ目のcaseあたりだと思うのですが、これはauに対応するためのものです。

  5. お世話になります。
    PHPを初めてまだ1週間の初心者で申し訳ないのですが、
    勉強のため上記のプログラムを実行してみると、下記のメッセージが出力されるのですが、
    どういった理由なのでしょうか、、、

    [01-Jul-2011 01:45:29] PHP Notice: Undefined property: stdClass::$ctype_parameters in /var/www/errorMailCheck.php on line 38
    [01-Jul-2011 01:45:29] PHP Warning: mb_convert_encoding(): Illegal character encoding specified in /var/www/errorMailCheck.php on line 39

    該当メッセージの箇所は以下のところだと思います。
    }else{
    $body[] = mb_convert_encoding(
    $structure->body,
    “UTF-8″,
    $structure->ctype_parameters['charset']
    );
    $body[] = $structure->body;
    }

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>