Sending mail via SMTP in Perl

2019-03-11 05:54发布

I am trying to send mail via SMTP in Perl.

I have written a script for this.

#!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;

When I run this script, my output is like following:

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}

I don't have enough information about Perl and SMTP, so I couldn't understand this error.

How can I solve this?

标签: perl email smtp
6条回答
趁早两清
2楼-- · 2019-03-11 06:23

Sadly, in (very) late 2014, Net::SMTP::SSL fails 1 of 1 installation tests, thus gmail (and any other) web based server is unreachable. Without installing my own mail server, the only way I can find to send email from Perl is to OLE it to Outlook. Outlook will then use its connections to make things happen.

I hope someone can prove me wrong.

查看更多
在下西门庆
3楼-- · 2019-03-11 06:24

Here's an updated version of cjm's script that currently works with Gmail using STARTTLS (not tested with other SMTP services) It uses Email::Sender::Transport::SMTPS instead of Email::Sender::Transport::SMTP

Your gmail account will have to have "Access for less secure apps" allowed ("turned on") -- where "less secure" does not mean unencrypted, it just seems to mean not using 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 });
查看更多
爷、活的狠高调
4楼-- · 2019-03-11 06:31

For email services that use STARTTLS, it's best to use the newer NET::SMTPS module. Try the following code:

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;
查看更多
Ridiculous、
5楼-- · 2019-03-11 06:34

It complains about the lack of a MAIL FROM: SMTP command. Without looking at any documentation, I'd guess it'd look something like $smtp->from('you@example.net') Like @cjm writes, you need $smtp->mail('you@example.net');

Granted, it seems a bit silly to have to supply a user name after you have just authenticated, but it makes sense from a historical and backwards compatibility point of view (the STARTTLS ESMTP spec can simply state what you need to do to authenticate, then the rest of the session happens just like in regular SMTP after the authentication is done). It would make sense for Net::SMTP to shield you from these implementation details, though.

查看更多
够拽才男人
6楼-- · 2019-03-11 06:37

Btw - although a bit late, anyway for future readers, Did you actually recv the mail?

There are no errors in the output attached. You have enabled debug (Debug=>1) in your constructor. These messages will go away once you set that to 0. Advantage of using SMTP is that it is included in stock install. No need to add modules.

查看更多
甜甜的少女心
7楼-- · 2019-03-11 06:43

You have to start a SMTP session (after authorization, if necessary) with a MAIL command giving the sender's email address. That's why the responses say "MAIL first" (5xx is an error response). So:

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

But if you're not a SMTP expert, why not use a higher-level module like Email::Sender instead of the low-level 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 });
查看更多
登录 后发表回答