システム管理業務を行っていると、定型メールを送信するスクリプトを記述する必要が頻繁に発生します。その場合、以下の2つの要求を考慮する必要があります。
- 定型メールの雛形は、スクリプト本体のロジックからは分離しておきたい(コード可読性の向上のため)。
- しかし、雛形をスクリプトとは別のファイルに分離することはしたくない(後日の変更時に雛形ファイルを探す労力をかけたくないため)。
Perl スクリプトで、この2つの要求を同時に満たすため、筆者はしばしば「DATA ハンドラを使って雛形を分離する」という手法を使います。サンプルコードは以下の通りです。なお、DATA ハンドラ内に日本語などのマルチバイト文字列を記述する場合は、use utf8;
を指定した上で、スクリプトを UTF-8 で保存する必要があります。
use Encode;
use HTML::Template;
use MIME::Entity;
use Net::SMTP;
use strict;
use warnings;
use utf8;
our $SMTPSERVER = 'localhost';
&sendnotice( 'helpdesk@example.net', 'alice@example.net', "Alice Example" );
sub sendnotice {
my( $sender, $recipient, $name ) = @_;
my $tmpl = HTML::Template->new_filehandle( \*DATA );
$tmpl->param( name => $name, sender => $sender );
my $msg = MIME::Entity->build( From => $sender,
To => $recipient,
Subject => '[NOTICE] Your disk usage',
Type => 'text/plain; charset=utf-8',
Encoding => 'base64',
Data => &encode('utf8', $tmpl->output) );
my $smtp = Net::SMTP->new( $SMTPSERVER );
$smtp->mail( $sender ) &&
$smtp->to( $recipient ) &&
$smtp->data( $msg->as_string ) &&
$smtp->quit;
}
__DATA__
<tmpl_var name="name"> 様
あなたのディスク消費量は、制限の90%を超えています。
至急、不要なファイルを削除してください。
--
<tmpl_var name="sender">
なお、MIME::Entity->build() を呼び出す時の Data パラメータに渡す値に対して encode する処理を忘れると、以下のようなエラーになって異常終了します。エラーメッセージと必要な修正との関係が分かり難くて、私も1時間ほどはまりました。
open body: Invalid argument at /usr/share/perl5/MIME/Entity.pm line 1878.
定形メールを自動返信するスクリプトも書きましたので、必要な方はどうぞ。