在Perl中通过SMTP发送邮件

zy1mlcev  于 2022-11-24  发布在  Perl
关注(0)|答案(7)|浏览(446)

我正在尝试通过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('mymail@gmail.com');
$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:<mymail@gmail.com>
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: mymail@gmail.com
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的足够信息,所以我不能理解这个错误。
我该如何解决这个问题?

aurhwmvo

aurhwmvo1#

您必须使用MAIL命令启动SMTP会话(如果需要,在授权之后),并提供发件人的电子邮件地址。这就是为什么响应会显示“MAIL first”(5xx是错误响应)。因此:

$smtp->auth($smtpuser, $smtppassword);
$smtp->mail('sender@example.com');
$smtp->to('mymail@gmail.com');

但是,如果您不是SMTPMaven,为什么不使用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      => 'mymail@gmail.com',
    From    => 'sender@example.com',
    Subject => 'Hi!',
  ],
  body => "This is my message\n",
);

sendmail($email, { transport => $transport });
o3imoua4

o3imoua42#

这是cjm脚本的一个更新版本,目前使用STARTTLS(未在其他SMTP服务上测试)与Gmail一起使用。它使用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   = 'user@gmail.com';
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      => 'user@example.com',
    From    => 'whatever@gmail.com',
    Subject => 'Hi!',
  ],
  body => "This is my message\n",
);

sendmail($email, { transport => $transport });
0md85ypi

0md85ypi3#

它抱怨缺少MAIL FROM: SMTP命令。
诚然,在刚刚进行身份验证之后就必须提供用户名似乎有点愚蠢,但从历史和向后兼容性的Angular 来看,这是有意义的(STARTTLSEMTP规范可以简单地说明您需要做什么来进行验证,则在完成身份验证后,会话的其余部分将像在常规SMTP中一样发生)。但是,对于Net::SMTP来说,屏蔽这些实现细节是有意义的。

pnwntuvh

pnwntuvh4#

顺便说一句,虽然有点晚,无论如何对未来的读者,你真的收到邮件了吗?
在附加的输出中没有错误。您已经在构造函数中启用了调试(Debug=〉1)。一旦您将其设置为0,这些消息就会消失。使用SMTP的好处是它包含在库存安装中。无需添加模块。

6ovsh4lw

6ovsh4lw5#

遗憾的是,在2014年末,Net::SMTP::SSL的安装测试失败了1/1,因此gmail(和任何其他)基于Web的服务器无法访问。如果不安装我自己的邮件服务器,我能找到的从Perl发送电子邮件的唯一方法是将其OLE到Outlook。Outlook将使用其连接来实现这些功能。
我希望有人能证明我错了。

pbgvytdp

pbgvytdp6#

对于使用STARTTLS的电子邮件服务,最好使用较新的NET::SMTPS模块。

my $msg = MIME::Lite ->new (  
From => 'from@bellsouth.net',
To => 'to@gmail.com',
Subject => 'Test Message',
Data => 'This is a test',
Type => 'text/html'
);

my $USERNAME = 'from@bellsouth.net';
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('from@bellsouth.net');
$smtps->to('to@gmail.com');
$smtps->data();
$smtps->datasend( $msg->as_string() );  
$smtps->dataend();  
$smtps->quit;
ztmd8pv5

ztmd8pv57#

您可以使用Net::SMTP_auth并使用NTLM作为身份验证方法。我曾使用此方法通过Exchange发送经过身份验证的邮件。请注意,对每个收件人使用一个“to”方法调用。

相关问题