Отправка почты через SMTP в Perl
Я пытаюсь отправить почту через SMTP в Perl.
Я написал для этого script.
#!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;
Когда я запускаю этот script, мой вывод выглядит следующим образом:
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, поэтому я не мог понять эту ошибку.
Как я могу это решить?
Ответы
Ответ 1
Вам необходимо запустить SMTP-сессию (после авторизации, если необходимо) командой MAIL, указывающей адрес электронной почты отправителя. Вот почему ответы говорят "MAIL first" (5xx - это ответ об ошибке). Итак:
$smtp->auth($smtpuser, $smtppassword);
$smtp->mail('[email protected]');
$smtp->to('[email protected]');
Но если вы не специалист по SMTP, почему бы не использовать модуль более высокого уровня, например Email::Sender вместо низкоуровневого Net::SMTP?
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 });
Ответ 2
Здесь обновленная версия cjm script, которая в настоящее время работает с Gmail с использованием STARTTLS (не протестирована с другими службами SMTP)
Он использует Email:: Sender:: Transport:: SMTPS вместо Email:: Sender:: Transport:: SMTP
У вашей учетной записи 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 });
Ответ 3
Он жалуется на отсутствие команды MAIL FROM:
SMTP. Не глядя на какую-либо документацию, я бы предположил, что это будет выглядеть как $smtp->from('[email protected]')
Как пишет @cjm, вам нужно $smtp->mail('[email protected]');
Конечно, кажется немного глупым предоставить имя пользователя после того, как вы только что прошли проверку подлинности, но имеет смысл с точки зрения исторической и обратной совместимости (спецификация STARTTLS ESMTP может просто указать, что вам нужно сделать для аутентификация, то остальная часть сеанса происходит точно так же, как в обычном SMTP после завершения проверки подлинности). Было бы разумно, чтобы Net::SMTP
защищал вас от этих деталей реализации.
Ответ 4
Btw - хотя немного поздно, в любом случае для будущих читателей, действительно ли вы отправили почту?
В прилагаемом выводе отсутствуют ошибки. Вы включили debug (Debug = > 1) в свой конструктор. Эти сообщения исчезнут, если вы установите значение 0.
Преимущество использования SMTP заключается в том, что оно включено в комплект поставки. Нет необходимости добавлять модули.
Ответ 5
К сожалению, в (очень) конце 2014 года Net:: SMTP:: SSL завершился неудачей 1 из 1 тестов установки, поэтому gmail (и любой другой) веб-сервер недоступен. Без установки моего собственного почтового сервера единственный способ найти отправку электронной почты с Perl - это OLE его для Outlook. Затем Outlook будет использовать свои подключения, чтобы все произошло.
Я надеюсь, что кто-то может доказать, что я ошибаюсь.
Ответ 6
Для служб электронной почты, использующих 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;