モダンPerlの世界へようこそ

第20回 Email::Sender:メールを送信する

この記事を読むのに必要な時間:およそ 5.5 分

Email::MIMEで添付ファイル付きのメールを作成する

添付ファイル付きのメールを用意する場合は,bodyではなくpartsに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,
    ),
  ],
);

ただし,この場合,現在はEmail::MIMEが各パーツについてもDateヘッダやMIME-Versionヘッダを自動的に追加してしまうため,気になる場合はオブジェクト生成後にパーツを取り出して該当のヘッダを上書き/削除してください。

my @parts = $email->parts;
for my $part (@parts) {
  $part->header_set(Date => ());
  $part->header_set('MIME-Version' => ());
}
$email->parts_set(\@parts);

なお,HTMLメールの場合は上記のやり方のほか,専用のEmail::MIME::CreateHTMLというモジュールを使うこともできます(本稿執筆時点では依存モジュールの指定とPODの表記に問題があるためテストに失敗することがありますが,インストール後の動作には特に問題ないようです)⁠これを使うと,HTML部分に外部のCSSや画像が指定されている場合はネット上からダウンロードしたものを埋め込んでくれるようになります。各パーツに余分なヘッダがついてしまう問題の対処法は素のEmail::MIMEを使う場合と同じです(埋め込み機能を有効にしている場合は埋め込まれたパーツに対しても同様の処理を実行する必要があります)⁠

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があれば十分ですが,場合によってはいっしょに使うモジュールの都合で,どうしてもほかの形式のオブジェクトを用意しなければならないこともあります。そのような場合はEmail::Abstractを使うと,Email::MIMEのオブジェクトから適切な形式のオブジェクトを生成できます。

たとえば,メールボックスの管理を行うときに便利なMail::Boxで使われているMail::Message形式に変換する場合はこのようになります。

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の送信用モジュールとしては,ケーシー・ウェストCasey West氏が2004年に書いたEmail::Sendが長らく使われてきました。このモジュールを使うと,先ほどのEmail::MIMEオブジェクトはこのように送信できます。

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を使って送信しましたが,Windows環境のようにsendmailが入っていない場合はNet::SMTPを使って送信することもできます。

my $sender = Email::Send->new({
  mailer      => 'SMTP',
  mailer_args => [ Host => 'smtp.example.com:587' ],
});
my $ret = $sender->send($email);
die "$ret" unless $ret;

また,all_mailersのようなメソッドを使えば,送信に成功するまでありとあらゆる手段を使ってメールの送信を試みることもできます。

my $sender = Email::Send->new;
for my $mailer ($sender->all_mailers) {
  $sender->mailer($mailer);
  my $ret = $sender->send($email);
  last if $ret;
}

単純な使い方をする分には十分だったため,Email::Sendはそれまでよく使われていたMIME::Liteなどを押しのけ,CatalystJiftyなどの標準的なメーラとして採用されるようになりました。

著者プロフィール

石垣憲一(いしがきけんいち)

あるときは翻訳家。あるときはPerlプログラマ。先日『カクテルホントのうんちく話』(柴田書店)を上梓。最新刊は『ガリア戦記』(平凡社ライブラリー)。

URLhttp://d.hatena.ne.jp/charsbar/

コメント

コメントの記入