月曜日, 9月 06, 2010

Postfix で受けたメールに自動返信 (Perl)

2007/10/26perlfreak.vox.comより転載)

vacationというコマンドがあるようだけど、Red Hat Enterprise Linuxにはパッケージがないみたい。
ソースからインストールして使い方を調べるくらいなら、と書いてしまった。
Postfixのaliasesファイルに

hoge: |"/usr/local/bin/auto_reply.pl /var/local/messages/hoge.txt"

のように記述。
返信メッセージファイルは、文字コードがShift_JIS(MS932)、改行コードがCR+LFで、先頭行が表題、以降が本文という体裁になっていることが前提。

===(auto_reply.pl ここから)===
#!/usr/bin/perl -w

use Net::SMTP;
use Encode qw/ from_to encode /;
use MIME::Parser;
use strict;

my $msg_path = $ARGV[0];

# 引数チェック、存在チェック
if ( !$msg_path or $msg_path eq "" ) {
exit;
}
elsif ( !( -e $msg_path ) ) {
exit;
}

# メールの内容をパース
my $parser = new MIME::Parser;
$parser->output_to_core(1);

my $entity = $parser->parse(\*STDIN) or die;

my $from = $entity->head->get('From');
chomp $from;
if ( $from =~ /(foo\.com|MAILER-DAEMON|Postmaster)/i ) {
exit;
}
elsif ( $from =~ /<.+?\@.+?>/ ) {
$from =~ s/^.+<(.+?\@.+?)>.*$/$1/;
}

# returnメールチェック
if ( $entity->is_multipart ) {
my $count = $entity->parts;

for ( my $i = 1; $i < $count; $i++ ) { my $part_entity = $entity->parts( $i );
my $type = $part_entity->head->mime_type;
my $part_from = $part_entity->head->get('From');

if ( $type eq 'message/rfc822' or $part_from =~ /(foo\.com|MAILER-DAEMON|Postmaster)/i ) {
exit;
}
}
}

# メール送信
&_send_mail( $from, $msg_path );

exit;


sub _send_mail() {

my $MAIL_HOST = 'localhost';
my $FROM = 'hoge@foo.com';
my $to = shift;
my $msg_path = shift;

# ファイルデータを取得
open IN, "< $msg_path" or die "Cannot open file: $!\n"; my $buff = do { local $/; };
close IN;

my @message = split( /\r\n/, $buff );
my $subject = shift @message;
my $body = join( "\n", @message );

from_to( $subject, 'cp932', 'iso-2022-jp' );
encode( 'MIME-Header', $subject );
from_to( $body, 'cp932', 'iso-2022-jp' );

#メールヘッダー
my $header = << "HEADER"; From: $FROM To: $to Subject: $subject Mime-Version: 1.0 Content-Type: text/plain; charset = "ISO-2022-JP" Content-Transfer-Encoding: 7bit HEADER

# メールを送信
my $smtp = Net::SMTP->new( $MAIL_HOST, Debug => 1 );
$smtp->mail( $FROM );
$smtp->to( $to );
$smtp->data();
$smtp->datasend( "$header\n" );
$smtp->datasend( "$body\n" );
$smtp->dataend();
$smtp->quit;

return 1;

}

__END__
===(auto_reply.pl ここまで)===

0 件のコメント: