PerlでSMTP経由でメールを送信しようとしています。
このためのスクリプトを作成しました。
#!Perl
use warnings;
use strict;
use Net::SMTP;
my $smtpserver = 'server';
my $smtpport = 25;
my $smtpuser = 'username';
my $smtppassword = 'password';
my $smtp = Net::SMTP->new($smtpserver, Port=>$smtpport, Timeout => 10, Debug => 1);
die "Could not connect to server!\n" unless $smtp;
$smtp->auth($smtpuser, $smtppassword);
$smtp->to('[email protected]');
$smtp->data();
$smtp->datasend("To: mymail\@gmail.com\n");
$smtp->quit;
このスクリプトを実行すると、出力は次のようになります。
Net::SMTP>>> Net::SMTP(2.31)
Net::SMTP>>> Net::Cmd(2.29)
Net::SMTP>>> Exporter(5.65)
Net::SMTP>>> IO::Socket::INET(1.31)
Net::SMTP>>> IO::Socket(1.32)
Net::SMTP>>> IO::Handle(1.31)
Net::SMTP=GLOB(0x273faf0)<<< 220 server GMX Mailservices E
Net::SMTP=GLOB(0x273faf0)>>> EHLO localhost.localdomain
Net::SMTP=GLOB(0x273faf0)<<< 250-server GMX Mailservices
Net::SMTP=GLOB(0x273faf0)<<< 250-8BITMIME
Net::SMTP=GLOB(0x273faf0)<<< 250-ENHANCEDSTATUSCODES
Net::SMTP=GLOB(0x273faf0)<<< 250-SIZE
Net::SMTP=GLOB(0x273faf0)<<< 250-AUTH=LOGIN PLAIN
Net::SMTP=GLOB(0x273faf0)<<< 250-AUTH LOGIN PLAIN
Net::SMTP=GLOB(0x273faf0)<<< 250 STARTTLS
Net::SMTP=GLOB(0x273faf0)>>> RCPT TO:<[email protected]>
Net::SMTP=GLOB(0x273faf0)<<< 503 5.5.1 MAIL first {mp-eu001}
Net::SMTP=GLOB(0x273faf0)>>> DATA
Net::SMTP=GLOB(0x273faf0)<<< 503 5.5.1 MAIL first {mp-eu001}
Net::SMTP=GLOB(0x273faf0)>>> To: [email protected]
Net::SMTP=GLOB(0x273faf0)>>> .
Net::SMTP=GLOB(0x273faf0)<<< 502 5.5.2 Unimplemented {mp-eu001}
Net::SMTP=GLOB(0x273faf0)>>> QUIT
Net::SMTP=GLOB(0x273faf0)<<< 502 5.5.2 Unimplemented {mp-eu001}
PerlとSMTPに関する十分な情報がないため、このエラーを理解できませんでした。
どうすれば解決できますか?
送信者の電子メールアドレスを指定するMAILコマンドを使用して、(必要に応じて承認後に)SMTPセッションを開始する必要があります。そのため、応答に「MAIL first」と表示されます(5xxはエラー応答です)。そう:
$smtp->auth($smtpuser, $smtppassword);
$smtp->mail('[email protected]');
$smtp->to('[email protected]');
ただし、SMTPの専門家でない場合は、低レベルの Net :: SMTP の代わりに Email :: Sender のような高レベルのモジュールを使用してみませんか?
use strict;
use warnings;
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP ();
use Email::Simple ();
use Email::Simple::Creator ();
my $smtpserver = 'server';
my $smtpport = 25;
my $smtpuser = 'username';
my $smtppassword = 'password';
my $transport = Email::Sender::Transport::SMTP->new({
Host => $smtpserver,
port => $smtpport,
sasl_username => $smtpuser,
sasl_password => $smtppassword,
});
my $email = Email::Simple->create(
header => [
To => '[email protected]',
From => '[email protected]',
Subject => 'Hi!',
],
body => "This is my message\n",
);
sendmail($email, { transport => $transport });
以下はSTARTJを使用してGmailで現在動作するcjmのスクリプトの更新バージョンです(他のSMTPサービスではテストされていません)。Email:: Sender :: Transport :: SMTPではなくEmail :: Sender :: Transport :: SMTPSを使用します
Gmailアカウントには、「安全性の低いアプリへのアクセス」を許可(「オン」)する必要があります。「安全性が低い」とは暗号化されていないという意味ではなく、OAuth 2.0
use strict;
use warnings;
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTPS;
use Email::Simple ();
use Email::Simple::Creator ();
my $smtpserver = 'smtp.gmail.com';
my $smtpport = 587;
my $smtpuser = '[email protected]';
my $smtppassword = 'password';
my $transport = Email::Sender::Transport::SMTPS->new({
Host => $smtpserver,
ssl => 'starttls',
port => $smtpport,
sasl_username => $smtpuser,
sasl_password => $smtppassword,
debug => 1,
});
my $email = Email::Simple->create(
header => [
To => '[email protected]',
From => '[email protected]',
Subject => 'Hi!',
],
body => "This is my message\n",
);
sendmail($email, { transport => $transport });
_MAIL FROM:
_ SMTPコマンドの欠如について不平を言っています。 ドキュメントを見なくても、 @cjmの書き込みのように、$smtp->from('[email protected]')
のようなものになると思います。$smtp->mail('[email protected]');
が必要です
確かに、認証した直後にユーザー名を指定する必要があるのは少しばかげているように見えますが、歴史的および後方互換性の観点からは理にかなっています(STARTTLS ESMTP仕様では、認証するために必要なことを単純に記述できますが、セッションの残りの部分は、認証が行われた後の通常のSMTPとまったく同じように発生します)。ただし、これらの実装の詳細から_Net::SMTP
_を保護することは理にかなっています。
残念ながら、2014年後半(非常に)、Net :: SMTP :: SSLはインストールテストの1つに失敗するため、Gmail(およびその他の)Webベースのサーバーに到達できません。自分のメールサーバーをインストールせずに、Perlからメールを送信する唯一の方法は、OLEそれをOutlookに送信することです。Outlookは、接続を使用して処理を行います。
誰かが間違っていることを証明できるといいのですが。
STARTTLSを使用するメールサービスの場合、新しいNET :: SMTPSモジュールを使用するのが最善です。次のコードを試してください:
my $msg = MIME::Lite ->new (
From => '[email protected]',
To => '[email protected]',
Subject => 'Test Message',
Data => 'This is a test',
Type => 'text/html'
);
my $USERNAME = '[email protected]';
my $PASSWORD = 'abc123';
my $smtps = Net::SMTPS->new("smtp.mail.att.net", Port => 587, doSSL => 'starttls', SSL_version=>'TLSv1');
$smtps->auth ( $USERNAME, $PASSWORD ) or die("Could not authenticate with bellsouth.\n");
$smtps ->mail('[email protected]');
$smtps->to('[email protected]');
$smtps->data();
$smtps->datasend( $msg->as_string() );
$smtps->dataend();
$smtps->quit;
ところで-とにかく将来の読者のために、少し遅れましたが、実際にメールを受信しましたか?
接続された出力にエラーはありません。コンストラクターでデバッグを有効にしました(Debug => 1)。これらのメッセージは、0に設定すると消えます。SMTPを使用する利点は、ストックインストールに含まれていることです。モジュールを追加する必要はありません。