前回、postfixのaliasを設定して、rootレベルで自動処理する方法を書いた。
→http://www.igreks.jp/dev/2008/11/postfix2.html
→http://www.igreks.jp/dev/2008/11/post.html
しかし、この方法はpostfixのconfigファイルを書き換えたり、エイリアス設定をしたりしなくてはならないので、root権限を持たないレンタルサーバの1ユーザレベルでは、かなり敷居が高い。
というわけで、少し自動処理の正確性は落ちるけれども、もっと簡単な方法を紹介。
おそらく「N●O」とかはこのやり方じゃないかと思われる。
「N●O」はPHPみたいだけど、私はPHPあまり得意じゃないのでPerlで。
[動作条件]
・perl5以上(確認した環境はは5.10)かつMail::POP3Clientモジュールがインストールされていること。
・POPアクセスにSSLを用いる場合(Gmailなど)は、さらにIO::Socket::SSLモジュール(要コンパイラ)が必要。
・あらかじめエラーメール受信専用のアドレスを作っておいて、メール送信する時にエンペロープFROMをそのアドレスに指定しておく。
・CRONなどで以下のスクリプトを実行する。
-------------------------------------------------------------------
#/usr/bin/perl -w
use strict;
use Mail::POP3Client;
my $log = "POPサーバに接続中・・・\n";
#コンストラクタ
my $pop = new Mail::POP3Client(
USER => 'pop_user', #popサーバのユーザ名
PASSWORD => 'pop_pwd', #同パスワード
HOST => 'pop.gmail.com', #popサーバ名
AUTH_MODE => 'BEST', #認証モード(たいていはBESTでOK)
DEBUG => 0, #デバッグ有無(正の整数を指定すると、プロンプトにサーバとのやりとりが表示される)
TIMEOUT => 10, #接続タイムアウト秒(デフォルトは60)
USESSL => 'true' #SSLを使わない場合は0(Gmailは使う)
);
if($pop->Count < 0){ #接続に失敗すると-1が返るらしい
$log .= "POPサーバに接続できませんでした";
}
else{
$log .= "ID[$id]のエラーメールアドレスを調査中・・・\n";
if($pop->Count != 0){
my @err = ();
my $suc = 0;
$log .= $pop->Count."件のエラーメールアドレスを処理中・・・\n";
#サーバにある数だけ読み込む
for(my $i=1; $i <= $pop->Count; $i++){
#本文を1行ずつ取得
foreach($pop->Body($i)){
#予めbase64エンコードしておいて「名前<メールアドレス>」の形にしておくとToヘッダのパースが楽ちん。
if($_ =~ /To:\s=\?iso-2022-jp\?B\?.+?\?=<(.+\@.+(\..+)+)>/i){
push(@err,$1);
$suc++;
#パースに成功したらサーバのメッセージ削除フラグを立てる
$pop->Delete($i);
last;
}
}
}
if(@err){
####ここらでエラーアドレスをDBから削除する処理など
foreach(@err){
&db::query("DELETE FROM usertable WHERE email='$_'");
}
$log .= "$suc件のエラーメールアドレスをデータベースから削除しました\n";
}
#相手先MTAによっては、パースに失敗することもあるでしょう。
if($pop->Count - $suc > 0){
$log .= "※".$pop->Count - $suc."件のエラーメールアドレスを削除できませんでした\n";
}
}
else{
$log .= "エラーメールアドレスはありませんでした\n";
}
}
#接続終了(このときメールがサーバから削除される)
$pop->Close;
print $log;
------------------------------------------------------------------------
※Mail::POP3ClientモジュールはPurePerlなのでなければCPANからダウンロードして、同じフォルダに置けば使える。
※IO::Socket::SSLが使えなければ、POPサーバをYahooとかの110番を使えばOK。
※SSL未対応でもよければNet::POP3モジュールとか使ってもOK。
追記:このスクリプトの発展形はこちら→http://www.igreks.jp/dev/2010/04/post-6.html
→http://www.igreks.jp/dev/2008/11/postfix2.html
→http://www.igreks.jp/dev/2008/11/post.html
しかし、この方法はpostfixのconfigファイルを書き換えたり、エイリアス設定をしたりしなくてはならないので、root権限を持たないレンタルサーバの1ユーザレベルでは、かなり敷居が高い。
というわけで、少し自動処理の正確性は落ちるけれども、もっと簡単な方法を紹介。
おそらく「N●O」とかはこのやり方じゃないかと思われる。
「N●O」はPHPみたいだけど、私はPHPあまり得意じゃないのでPerlで。
[動作条件]
・perl5以上(確認した環境はは5.10)かつMail::POP3Clientモジュールがインストールされていること。
・POPアクセスにSSLを用いる場合(Gmailなど)は、さらにIO::Socket::SSLモジュール(要コンパイラ)が必要。
・あらかじめエラーメール受信専用のアドレスを作っておいて、メール送信する時にエンペロープFROMをそのアドレスに指定しておく。
・CRONなどで以下のスクリプトを実行する。
-------------------------------------------------------------------
#/usr/bin/perl -w
use strict;
use Mail::POP3Client;
my $log = "POPサーバに接続中・・・\n";
#コンストラクタ
my $pop = new Mail::POP3Client(
USER => 'pop_user', #popサーバのユーザ名
PASSWORD => 'pop_pwd', #同パスワード
HOST => 'pop.gmail.com', #popサーバ名
AUTH_MODE => 'BEST', #認証モード(たいていはBESTでOK)
DEBUG => 0, #デバッグ有無(正の整数を指定すると、プロンプトにサーバとのやりとりが表示される)
TIMEOUT => 10, #接続タイムアウト秒(デフォルトは60)
USESSL => 'true' #SSLを使わない場合は0(Gmailは使う)
);
if($pop->Count < 0){ #接続に失敗すると-1が返るらしい
$log .= "POPサーバに接続できませんでした";
}
else{
$log .= "ID[$id]のエラーメールアドレスを調査中・・・\n";
if($pop->Count != 0){
my @err = ();
my $suc = 0;
$log .= $pop->Count."件のエラーメールアドレスを処理中・・・\n";
#サーバにある数だけ読み込む
for(my $i=1; $i <= $pop->Count; $i++){
#本文を1行ずつ取得
foreach($pop->Body($i)){
#予めbase64エンコードしておいて「名前<メールアドレス>」の形にしておくとToヘッダのパースが楽ちん。
if($_ =~ /To:\s=\?iso-2022-jp\?B\?.+?\?=<(.+\@.+(\..+)+)>/i){
push(@err,$1);
$suc++;
#パースに成功したらサーバのメッセージ削除フラグを立てる
$pop->Delete($i);
last;
}
}
}
if(@err){
####ここらでエラーアドレスをDBから削除する処理など
foreach(@err){
&db::query("DELETE FROM usertable WHERE email='$_'");
}
$log .= "$suc件のエラーメールアドレスをデータベースから削除しました\n";
}
#相手先MTAによっては、パースに失敗することもあるでしょう。
if($pop->Count - $suc > 0){
$log .= "※".$pop->Count - $suc."件のエラーメールアドレスを削除できませんでした\n";
}
}
else{
$log .= "エラーメールアドレスはありませんでした\n";
}
}
#接続終了(このときメールがサーバから削除される)
$pop->Close;
print $log;
------------------------------------------------------------------------
※Mail::POP3ClientモジュールはPurePerlなのでなければCPANからダウンロードして、同じフォルダに置けば使える。
※IO::Socket::SSLが使えなければ、POPサーバをYahooとかの110番を使えばOK。
※SSL未対応でもよければNet::POP3モジュールとか使ってもOK。
追記:このスクリプトの発展形はこちら→http://www.igreks.jp/dev/2010/04/post-6.html
