エラーメールの処理

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

関連記事

お問い合わせ

システム開発に関するお問い合わせをお待ちしています。
お急ぎの方は、Twitterでどうぞ。
もちろん、このページへのコメントも大歓迎です!


6 Comments

  1. [...] 理由によって送信エラーが戻ってきた場合の処理に役立つ情報がありました。 http://firegoby.theta.ne.jp/archives/18 実際こちらのソースを参考にして送信エラーが返ってくるメールアドレスを抽 [...]

  2. しおん より:

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

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

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

  3. miya より:

    しおん様はじめまして

    お役にたてて何よりです。
    ちなみに
    http://firegoby.theta.ne.jp/archives/392
    と組み合わせていただくとさらに幸せになれると思います。

  4. pisces より:

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

  5. miya より:

    @pisces

    はじめまして、pisces様

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

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

  6. pisces より:

    miya様
    ご親切な説明ありがとうございます。
    分かりました。
    本当にありがとうございました。

Leave a Reply

Additional comments powered by BackType