メール送信のあれこれ
たとえばウェブアプリケーションでなにかの注文を受け取ったとき、
とはいえ、
そこで今回はPerl Email Projectというコミュニティがおすすめするモジュールを中心に、
Perl Email Projectとは?
PEPことPerl Email Projectは、
Perl Email Projectが管理しているモジュールは、
> cpan Task::Email::PEP::NoStore
また、
Email::MIMEを使ってメールを作成する
さて、
Email::MIMEを使ってISO-2022-JPベースのごく一般的なメールを作成する場合はこのようになります。
use strict;
use warnings;
use utf8;
use Email::MIME;
use Email::MIME::Creator;
use Encode;
# use Encode::compat::MIME::Header::ISO_2022_JP; # perl < 5.8.8
my $email = Email::MIME->create(
header => [
From => encode('MIME-Header-ISO_2022_JP' => '"F.U." <foo@example.com>'),
To => encode('MIME-Header-ISO_2022_JP' => '"B.A." <bar@example.jp>'),
Subject => encode('MIME-Header-ISO_2022_JP' => 'タイトル'),
],
attributes => {
content_type => 'text/plain',
charset => 'ISO-2022-JP',
encoding => '7bit',
},
body => encode('iso-2022-jp' => '本文'),
);
# print $email->as_string;
headerには追加したいヘッダのフィールド名とその内容の組を列挙します。このフィールド名はそのままメールヘッダに流用されます
use Email::Date::Format 'email_date'
my $email = Email::MIME->create(
header => [
Date => email_date( time - 60 * 60 ),
...,
],
body => '...',
);
また、
単純な用途では特に指定する必要はありませんが、
bodyにはメール本文をスカラー、
なお、
use utf8;
my $email = Email::MIME->create(
header_str => [
From => '"F.U." <foo@example.com>',
To => '"B.A." <bar@example.jp>',
Subject => 'タイトル',
],
attributes => {
content_type => 'text/plain',
charset => 'UTF-8',
encoding => 'base64',
},
body_str => '本文',
);
ただし、
Email::MIMEで添付ファイル付きのメールを作成する
添付ファイル付きのメールを用意する場合は、
use Path::Class;
my $email = Email::MIME->create(
header => [ ... ],
parts => [
Email::MIME->create(
attributes => {
content_type => 'text/plain',
charset => 'ISO-2022-JP',
encoding => '7bit',
},
body => encode(jis => '本文'),
),
Email::MIME->create(
attributes => {
content_type => 'application/msword',
name => 'myword.doc',
filename => 'myword.doc',
encoding => 'base64',
disposition => 'attachment',
},
body => scalar file('myword.doc')->slurp,
),
],
);
ただし、
my @parts = $email->parts;
for my $part (@parts) {
$part->header_set(Date => ());
$part->header_set('MIME-Version' => ());
}
$email->parts_set(\@parts);
なお、
use strict;
use warnings;
use Email::MIME::CreateHTML;
use Template;
my $vars = {};
my $tt = Template->new({...});
$tt->process('html_mail.tt2', $vars, \my $html);
$tt->process('text_mail.tt2', $vars, \my $text);
my $email = Email::MIME->create_html(
header => [ ... ],
body_attributes => {
content_type => 'text/html',
charset => 'UTF-8',
},
body => $html,
text_body_attributes => {
content_type => 'text/plain',
charset => 'UTF-8',
},
text_body => $text,
);
その他の形式のオブジェクトに変換する
日常的な用途ではEmail::MIMEがあれば十分ですが、
たとえば、
use Email::Abstract;
use Email::MIME;
use Email::MIME::Creator;
my $email_mime_obj = Email::MIME->create(...);
my $mail_message_obj = Email::Abstract->new($email_mime_obj)
->cast('Mail::Message');
Email::Sendでメールを送信する
メールオブジェクトができたので、
Perl Email Projectの送信用モジュールとしては、
use strict;
use warnings;
use Email::MIME;
use Email::Send;
my $email = Email::MIME->create(...);
my $ret = Email::Send->new({ mailer => 'Sendmail' })->send($email);
die "$ret" unless $ret;
ここではシステム標準のsendmailを使って送信しましたが、
my $sender = Email::Send->new({
mailer => 'SMTP',
mailer_args => [ Host => 'smtp.example.com:587' ],
});
my $ret = $sender->send($email);
die "$ret" unless $ret;
また、
my $sender = Email::Send->new;
for my $mailer ($sender->all_mailers) {
$sender->mailer($mailer);
my $ret = $sender->send($email);
last if $ret;
}
単純な使い方をする分には十分だったため、
Email::Sendの問題点
ところが、
たとえば、
そのような実装面の問題だけでなく、
そのため、
Email::Senderの使い方
Email::Senderを使うと、
use strict;
use warnings;
use Email::Sender::Simple 'sendmail';
use Email::MIME;
my $email = Email::MIME->create(...);
sendmail($email);
これで、
外部のSMTPサーバを利用したい場合などは、
use Email::Sender::Transport::SMTP;
my $transport = Email::Sender::Transport::SMTP->new(
host => 'smtp.example.com',
port => 587,
);
sendmail($email, { transport => $transport });
具体的に送信先を指定したい場合はこのようにします
sendmail($email, { to => [qw( other@example.com )] });
エラーが発生した場合、
use Try::Tiny;
try { sendmail($email) }
catch { my $error = $_; warn $error->message };
特にエラーの内容を気にしない場合は、
try_to_sendmail($email) or die "sendmail error!";
その他の使い方についてはEmail::Sender::Manual::QuickStartをご覧ください。
移行状況
Email::Senderの登場以降、