そこで,Net::SMTP,IO::Socket::SSL,Authen::SASL を使って Gmail からメールを送るやり方について書こう,というのが今回のお話しである。
まず,最初に,いつものようにここに書いてある内容は,他の方のブログなどを参考にしている。 つまり私のオリジナルではない。しかし,幾つかのサイトの内容をミックスしているので,全くのコピーでもないのだが…。 今回参考にしたのは,Satoshi Shida さんの「つれづれニッキ」の中の PerlでSMTP over TLSはNet::SMTPだけでOKになっていたである。 他にも,複数の宛て先がある時の処理については,chaichanPaPa さんの「燈明日記」の中の SMTPモジュールでの複数アドレスメールToの罠を参考にした。
さて,肝心の中身だが,以下にスクリプトを載せているので,それを見ながら解説してみよう。
#!/usr/bin/perl
use strict;
use Jcode;
use Net::SMTP; # SMTP接続後、starttls()を使う
use IO::Socket::SSL; # SSLとあるけれどもTLSしか使わない
use Authen::SASL; # SASLはSMTPに認証手順
my $mailhost = 'smtp.gmail.com';
my $mailport = 587;
my $mail_username = 'xxxxx@gmail.com';
my $mail_password = 'PASSWORD';
my $from_mail = 'xxxxx@gmail.com';
my $to_mail = 'first@address.to.send, second@address.to.send';
my $cc_mail = 'carbon_copy@address.to.send';
#
my @mailto = split(',', $to_mail);
my @mailcc = split(',', $cc_mail);
#
my $subject = 'Mail Subject';
my $message = 'This is a test mail'."\n".'from XXX';
my $smtp = Net::SMTP->new(
$mailhost,
Hello => 'mydomain',
Port => $mailport
# Debug => 1
);
die "Error" unless $smtp;
my $r = $smtp->starttls(
SSL_version=>"TLSv12",
SSL_verify_mode=>SSL_VERIFY_PEER,
SSL_ocsp_mode=>SSL_OCSP_TRY_STAPLE,
# SSL_ca_path=>'etc/ssl/certs',
# SSL_ca_file=>'etc/ssl/certs/ca-bundle.crt',
SSL_verifycn_name => $mailhost, # defaults to PeerHost
SSL_verifycn_schema => 'smtp',
SSL_hostname => $mailhost, # SNI support
# SSL_cipher_list =&g; 'PROFILE=SYSTEM',
);
die "Error" unless $r;
$r = $smtp->auth($mail_username, $mail_password);
die "Error" unless $r;
$smtp->mail($from_mail);
$smtp->to(@mailto);
if ($cc_mail ne '') {
$smtp->cc(@mailcc);
}
#
my $header;
$header = "From: ".$from_mail."\n";
$header .= "To: ".$to_mail."\n";
if ($cc_mail ne '') {
$header .= "Cc: ".$cc_mail."\n";
}
$header .= "Subject: ".jcode($subject)->mime_encode . "\n";
$header .= "MIME-Version: 1.0\n";
$header .= "Content-type: text/plain; charset=ISO-2022-JP\n";
$header .= "Content-Transfer-Encoding: 7bit\n\n";
#
$smtp->data();
$smtp->datasend($header);
$smtp->datasend($message);
$smtp->dataend();
$smtp->quit;
スクリプトを見ると,5個のモジュールを使っている。
最初の strict はモジュールというよりは,文法をあまり省略しない,って感じのやつだったと思う。
2個目の Jcode は日本語の文字コードの変換用のものであり,これも確か別のやつを使えってなってたような気もするなぁ…。
残りの3個が,今回のメール送信に必要なモジュールであり,それぞれ,Net::SMTP,IO::Socket::SSL,Authen::SASLである。
やり方としては,Net::SMTP で送信のための変数を作り(もうちょっといい言い方があるはず…),その後,TLS (starttls) で認証してもらってから,Net::SMTP でメールを送る,という感じみたい。この,TLS での認証に IO::Socket::SSL と Authen::SASL が必要(らしい)。スクリプトでは,初めの方に
・メールを実際に送ってくれるサーバー(SMTPサーバー)
・そのサーバーにアクセスするポート番号(587番)
・Gmail でのユーザー名(@gmail.com を含む)
・Gmail のログインパスワード
・送信元アドレス ($from_mail)
・宛て先アドレス ($to_mail)
・Cc: の宛て先 ($cc_mail)
を指定している。 当然,上記の例ではこれらのアドレスは「架空」のものである。
その後,「@mailto」と「@mailcc」とうい配列を作っている。 これは,宛て先のアドレスと Cc: の宛て先が複数あることを前提にしたもので,Net::SMTP を使う際に必要となる。 宛て先が1個だけの場合には配列にしなくてもうまく働く。
「my $smtp = Net::SMTP->new(」で,送信用の変数を用意している。 その中で送信用の SMTP サーバーや,ポート番号を指定している。 また,エラーがあった場合には止まるようになっている。
その次の「my $r = $smtp->starttls(」の所で TLS で認証を受けている。 ここでは,TLSのv1.2を指定したりしているが,実は細かいオプションしてはわかっていない。 ただ,コメントアウトしないとうまく働かなかったものがあったので,それはコメントとして表記しておいた。 そして,「$r = $smtp->auth($mail_username, $mail_password);」の部分で Gmail の認証を受けている。
認証を受けることができれば,いよいよメールの送信となる。
$smtp->mail($from_mail);
$smtp->to(@mailto);
if ($cc_mail ne '') {
$smtp->cc(@mailcc);
}
の部分で,メールのヘッダーパートを指定している。もし宛て先が複数ある場合には,配列を使用しないといけないらしい。
事実,「aaa@example.com, bbb@sample.co.jp」のようにコンマで区切ったままだと送信できなかった。
また,Cc: は指定がある時だけヘッダーに出力するようにしている。その後,メールの中身を書いているが,ここにも「From:」フィールドや「To:」,「Cc:」などのフィールド,MIME のバージョン指定などを記載している。 どうも,こちらはメールと一緒に送られるもので,ここで言うヘッダーは送信サーバーに対する指示を表しているみたい(と勝手に思っている)。 また,ここでは複数の宛て先がある場合には,コンマで区切って並べればよい。
後は,
$smtp->data(); $smtp->datasend($header); $smtp->datasend($message); $smtp->dataend(); $smtp->quit;として,メールを送信している。
できてみると意外と簡単に送信できている。 TLS の認証の部分も言うほど大したことは記載していない。 しかし,これでうまく Gmail から TLS 認証でメールが送信できた。 実際には,Gmail のアカウントで「安全性の低いアプリへのアクセスを有効」にしないといけないので,ご注意を。
0 件のコメント:
コメントを投稿