メール受信からプログラムを実行し添付ファイル保存する
はじめに
レンタルサーバー(XSERVER)、メール受信をトリガーとし、プログラムを起動します。※Lambda Function的な...。
今回は、特定のアドレスがメール受信した時に、Perl5 のプログラム import_attachment.pl を実行する例を紹介します。
手順
トリガー設定(例)は、
⇒ Xserverレンタルサーバー|サーバーパネルから「メールの振り分け」をクリック
⇒ ドメイン選択画面から「設定対象のドメイン:選択する」をクリック
⇒ メール振り分け設定画面から「メール振り分け設定追加」をクリック
・条件1(キーワード):特定のアドレス
・条件1(場所):あて先
・条件1(一致):内容を含む
・条件1(宛先):| /usr/bin/perl /home/(サーバID)/bin/import_attachment.pl
・処理方法(配送方法):転送
プログラム(import_attachment.pl)
/home/(サーバID)/bin/import_attachment.plを作りパーミッション「700」に設定すれば動くはず。
#!/usr/bin/perl use strict; use warnings; use utf8; use Time::HiRes "gettimeofday"; use MIME::Parser; my @accepts = ('受け付けるメール送信者:メールアドレス'); my $output = '添付ファイル保存先のフルパス'; my $log = '実行ログファイルのフルパス'; my ($es, $ms) = gettimeofday(); my ($S, $M, $H, $d, $m, $y) = localtime; ($y, $m, $d, $H, $M, $S, $ms) = ($y + 1900, sprintf("%02d", ++$m), sprintf("%02d", $d), sprintf("%02d", $H), sprintf("%02d", $M), sprintf("%02d", $S), sprintf("%06d", $ms)); open(LOG, ">>$log") || die; flock(LOG, 2) || die; print LOG "\n[$y/$m/$d $H:$M:$S.$ms] START, "; my $mp= new MIME::Parser; $mp->output_to_core(1); $mp->tmp_to_core(1); $mp->tmp_recycling(1); $mp->use_inner_files(1); my $mail= $mp->parse(\*STDIN); my @from = $mail->head->get('From') =~ /<(.+)>/; print LOG " from=$from[0], "; @from = grep { $_ eq $from[0] } @accepts; if (scalar(@from) > 0 && $mail->is_multipart) { my $count = $mail->parts; for (my $i = 0; $i < $count; $i++) { my $entity = $mail->parts($i); my $mime = $entity->head->mime_type; print LOG " mime=$mime, "; my $name = "$output/$y$m$d$H$M$S$ms".sprintf("%04d", rand(1000)); if ($mime eq "image/jpeg") { $name .= ".jpg" } elsif ($mime eq "application/pdf") { $name .= ".pdf" } else { next; } print LOG " name=$name "; my $body = $entity->bodyhandle; my $IN = $body->open("r") || next; my $data = $IN->getline(); if (defined($data)) { print LOG " (save)"; open(OUT, ">$name") || next; eval { do { print OUT $data; } while (defined($data = $IN->getline())); close(OUT); chmod 0600, $name; }; if (my $e = $@) { print LOG "$e, "; } else { print LOG ", "; } } else { print LOG " (skip), "; } $IN->close; } print LOG " END "; } else { print LOG " IGNORE "; } flock(LOG, 8); close(LOG); 1;
まとめ
プログラムが異常終了したときは、メール送信者にその内容が自動送信されるようでした。。自前でログを書きだしていくのは大変ですね。しみじみ
「perl5」、どうかなって思いつつ、楽なので書き進めましたが、流行的にも気が向いたら同じ処理を「python3」で、書き直したいなとさ。