そこで,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 件のコメント:
コメントを投稿