PHP-MLでも議論されていたけど、バウンスメール処理をPHPでやる場合、どうやったらできるのか考えてみた。
まぐまぐのメールを見てみると、ヘッダにはReturn-Pathにバウンスメールの送信先が指定されて
いる。これはSMTP MAIL FROM(エンベロープ送信者)へReturn-Pathに入れたいアドレスを指定すればよさげだ。このアドレスには送信した各メールにつき一意に決まるID(実装の問題だと思うので別に一意じゃなくてもいいけど)を埋め込めば、「どのアドレス宛てに送ったどのメールがバウンスされたのか」が判断できそうな希ガス。
メール送信にPEAR::Mail_smtpを利用する場合は、send()に渡す$headers['From']がSMTP MAIL FROMになると思うけど、ソースを見たところ$headers['Return-Path']にバウンス受け用アドレスを入れておけばそのアドレスがSMTP MAIL FROMに設定されるみたいなのでどうにかなりそうだ。あとはPEAR::Mail_Queueで定期的に発信する体制を整えれば、発信側はできたっぽい。
じゃあ、今度は受信側。
メールごとに一意に決まっているバウンス受け用メールをどう受け取るか。Postfixでいくと仮定したら、virtual_alias_maps(virtual_maps)に正規表現用のVirtualを追記する。
virtual_alias_maps = hash:/etc/postfix/virtual
regexp:/etc/postfix/virtual_regexp ←これ
xxxxx_error@example.comをバウンス受け用アドレスとすると、/etc/postfix/virtual_regexpには
/^.+_error@example\.com$/ [受け取るユーザ]
とか書いておけば受け取るユーザ宛てに配信されるようになるはずだ。
ユーザ宛てに配信されたメールの処理については、procmailを使う。/home/[受け取るユーザ]/.procmailrcに
:0
| /usr/bin/php /path/to/phpscript.php
とでも書いておけばPHPスクリプト側にSTDIN(標準入力)経由でメール本文を渡せるだろう。
実際の解析処理は、PEAR::Mail_mimeDecodeをかませばヘッダと本文の分離はできろうだろうから、後はヘッダのX-Original-Toに格納されたアドレスを見て、「どのアドレス宛てに送ったどのメールがバウンスされたのか」を判断し、本文を解析してバウンスの理由を特定したらDBに書き込む、と。
これでとりあえず動くものは作れそうだけれども、やはり本文解析には根気が必要そうだなあ。解析部分をベイジアンフィルタで実装するようにすれば、メンテはお客さんまかせ(解析失敗したら「あーそうですか、じゃまた学習させといてくださいねー」とか言っちゃって)だからラクだし安く作れるかも?(なんて投げやりな...)
この記事を見た人は以下のエントリも見ています
- symfonyでカスタムバリデータを使ってフィルタを実装する
- PHP5.2.8 で Mojavi3 を動作させた際に出るWarning対処方法まとめ
- jpMailPluginをsymfony1.1.5に対応してみた(暫定)
- ロリポップで拡張子htmlのままSSIを使う方法
- VistaPrintの無料名刺作成サービスとバックエンド商品について
- mantisのメール文字化け対策
- 小さい会社だからこそ、無料で使える情報共有ツールを徹底活用するべきだと思う
- GMailをSPAM(スパム)フィルタにしたSMTPサーバの構築
- PHPプロヘッショナル向け書籍とか
- 「Google アプリ 独自ドメイン向け」を正式導入した件について