04 June 2018

(Perl) Net::SMTPSを使ってメール送信

Net::SMTPSを用いてメール送信する。

メール本文の作成は次の3通りの方法で

 ・全て手動で作成する
 ・Email::MIMEを使う
 ・MIME::Entityを使う

また、添付ファイルがある場合も考察する。

※ Net::SMTPSではなく、Email::Sender を使うサンプルは『(Perl) Email::Senderを使ってメール送信』を参照。

メール本文の手動作成、添付ファイル無し

最も基本的な例

#!/usr/bin/perl
 
use warnings;
use strict;
use utf8;
use Encode qw(encode);
use Net::SMTPS;
 
my $from      = 'sender@gmail.com';
my $from_name = '差出人の名前';
my $to        = 'recipient@example.com';
my $to_name   = 'あて先の名前';
my $subject   = 'test テスト';
my $body =
    "年齢からいえば、関羽がいちばん年上であり、次が劉備、"
  . "その次が張飛という順になるのであるが、"
  . "義約のうえの義兄弟だから年順をふむ必要はないとあって、"
  . "「長兄には、どうか、あなたがなって下さい。\n"
  . "それでないと、張飛の我ままにも、おさえが利きませんから」と、関羽がいった。";
 
my $smtp = Net::SMTPS->new(
                            'smtp.gmail.com',
                            Port  => 587,
                            doSSL => 'starttls',
                            Debug => 1
);
 
$smtp->auth( 'sender@gmail.com', 'My_Password', 'CRAM-MD5' );
$smtp->mail($from);
$smtp->recipient( $to, SkipBad => 1 );
$smtp->data();
 
my $header_str =
    "From: " . encode( 'MIME-Header-ISO_2022_JP', $from_name ) . "<$from>\n"
  . "To: " . encode( 'MIME-Header-ISO_2022_JP', $to_name ) . "<$to>\n"
  . "Subject:" . encode( 'MIME-Header-ISO_2022_JP', $subject ) . "\n"
  . "Mime-Version: 1.0\n"
  . "Content-Type: text/plain; charset = \"ISO-2022-JP\"\n"
  . "Content-Trensfer-Encoding: 7bit\n\n";
 
$smtp->datasend($header_str);
$smtp->datasend( encode( 'iso-2022-jp', $body ) );
$smtp->dataend();
$smtp->quit;

STARTTLSではなく、SSLを用いる場合は、赤で着色した部分を次のように書き換える

                                Port  => 465,
                                doSSL => 'ssl',

また、デバッグ表示を行うために青で着色した部分を記述している。

Email::MIMEを使用、添付ファイル無し

#!/usr/bin/perl
 
use warnings;
use strict;
use utf8;
use Encode qw(encode);
use Net::SMTPS;
use Email::MIME;
use Email::MIME::Creator;
use Path::Class;
 
my $from    = '差出人の名前 <sender@gmail.com>';
my $to      = 'あて先の名前 <recipient@example.com>';
my $subject = 'test テスト';
my $body =
    "年齢からいえば、関羽がいちばん年上であり、次が劉備、"
  . "その次が張飛という順になるのであるが、"
  . "義約のうえの義兄弟だから年順をふむ必要はないとあって、"
  . "「長兄には、どうか、あなたがなって下さい。\n"
  . "それでないと、張飛の我ままにも、おさえが利きませんから」と、関羽がいった。";
 
my $mail = Email::MIME->create(
    'header' => [
        'From'    => encode( 'MIME-Header-ISO_2022_JP', $from ),
        'To'      => encode( 'MIME-Header-ISO_2022_JP', $to ),
        'Subject' => encode( 'MIME-Header-ISO_2022_JP', $subject ),
    ],
    'attributes' => {
                      'content_type' => 'text/plain',
                      'charset'      => 'ISO-2022-JP',
                      'encoding'     => '7bit',
    },
    'body' => encode( 'iso-2022-jp', $body ),
);
 
eval {
    my $smtp = Net::SMTPS->new(
                                'smtp.gmail.com',
                                Port  => 587,
                                doSSL => 'starttls',
                                Debug => 1
    );
 
    $smtp->auth( 'sender@gmail.com', 'My_Password', 'CRAM-MD5' );
    $smtp->mail($from);
    $smtp->recipient( $to, { SkipBad => 1 } );
    $smtp->data();
    $smtp->datasend( $mail->as_string() );
    $smtp->dataend();
    $smtp->quit;
};
if ($@) {
    die "ERROR : $@\n";
}

Email::MIMEを使用、添付ファイル有り

一つ上の例で、メール本文を構築している部分を次のように書き換える

my $mail = Email::MIME->create(
    'header' => [
        'From'    => encode( 'MIME-Header-ISO_2022_JP', $from ),
        'To'      => encode( 'MIME-Header-ISO_2022_JP', $to ),
        'Subject' => encode( 'MIME-Header-ISO_2022_JP', $subject ),
    ],
    parts => [
               Email::MIME->create(
                                    'attributes' => {
                                                 'content_type' => 'text/plain',
                                                 'charset'  => 'ISO-2022-JP',
                                                 'encoding' => '7bit',
                                    },
                                    'body' => encode( 'iso-2022-jp', $body ),
               ),
               Email::MIME->create(
                        'attributes' => {
                                          'content_type' => 'text/plain',
                                          'name'         => 'attached image name',
                                          'filename'     => 'test01.jpg',
                                          'encoding'     => 'base64',
                                          'disposition'  => 'attachment',
                        },
                        'body' => scalar Path::Class::file('test01.jpg')->slurp,
               ),
    ],
);

緑で着色した部分で添付ファイルを処理している

MIME::Entityを使用、添付ファイル無し

#!/usr/bin/perl
 
use warnings;
use strict;
use utf8;
use Encode qw(encode);
use Net::SMTPS;
use MIME::Entity;
 
my $from    = '差出人の名前 <sender@gmail.com>';
my $to      = 'あて先の名前 <recipient@example.com>';
my $subject = 'test テスト';
my $body =
    "年齢からいえば、関羽がいちばん年上であり、次が劉備、"
  . "その次が張飛という順になるのであるが、"
  . "義約のうえの義兄弟だから年順をふむ必要はないとあって、"
  . "「長兄には、どうか、あなたがなって下さい。\n"
  . "それでないと、張飛の我ままにも、おさえが利きませんから」と、関羽がいった。";
 
my $mail = MIME::Entity->build(
        'From'    => encode( 'MIME-Header-ISO_2022_JP', $from ),
        'To'      => encode( 'MIME-Header-ISO_2022_JP', $to ),
        'Subject' => encode( 'MIME-Header-ISO_2022_JP', $subject ),
        'Type'    => 'text/plain;charset="iso-2022-jp"',
        'Encoding'=> '7bit',
        'Data'    => encode( 'iso-2022-jp', $body ),
        );
 
eval {
    my $smtp = Net::SMTPS->new(
                                'smtp.gmail.com',
                                Port  => 587,
                                doSSL => 'starttls',
                                Debug => 1
    );
     
    $smtp->auth( 'sender@gmail.com', 'My_Password', 'CRAM-MD5' );
    $smtp->mail($from);
    $smtp->recipient( $to, { SkipBad => 1 } );
    $smtp->data();
    $smtp->datasend($mail->stringify());
    $smtp->dataend();
    $smtp->quit;
};
if ($@) {
    die "ERROR : $@\n";
}

MIME::Entityを使用、添付ファイル有り

一つ上の例で、メール本文を構築している部分を次のように書き換える

my $mail = MIME::Entity->build(
        'From'    => encode( 'MIME-Header-ISO_2022_JP', $from ),
        'To'      => encode( 'MIME-Header-ISO_2022_JP', $to ),
        'Subject' => encode( 'MIME-Header-ISO_2022_JP', $subject ),
        'Type'    => 'text/plain;charset="iso-2022-jp"',
        'Encoding'=> '7bit',
        'Data'    => encode( 'iso-2022-jp', $body ),
        );
 
$mail->attach(
        'Description' => 'attached image name',
        'Type'        => 'image/jpeg',
        'Encoding'    => 'base64',
        'Path'        => 'test01.jpg'
);