web-dev-qa-db-fra.com

Envoi de courrier via SMTP en Perl

J'essaie d'envoyer un courrier via SMTP en Perl. 

J'ai écrit un script pour cela. 

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

Lorsque je lance ce script, mon résultat est le suivant:

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}

Je n'ai pas assez d'informations sur Perl et SMTP, je ne pouvais donc pas comprendre cette erreur.

Comment puis-je résoudre ça?

17
Selin

Vous devez démarrer une session SMTP (après autorisation, si nécessaire) avec une commande MAIL indiquant l'adresse électronique de l'expéditeur. C'est pourquoi les réponses disent "MAIL en premier" (5xx est une réponse d'erreur). Alors:

$smtp->auth($smtpuser, $smtppassword);
$smtp->mail('[email protected]');
$smtp->to('[email protected]');

Mais si vous n'êtes pas un expert SMTP, pourquoi ne pas utiliser un module de niveau supérieur tel que Email :: Sender au lieu du bas niveau 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 });
26
cjm

Voici une version mise à jour du script de cjm qui fonctionne actuellement avec Gmail avec STARTTLS (non testé avec d'autres services SMTP) Il utilise Email :: Sender :: Transport :: SMTPS au lieu de Email :: Sender :: Transport :: SMTP

Votre compte gmail devra avoir "Accès pour les applications moins sécurisées" autorisé ("activé") - où "moins sécurisé" ne signifie pas non crypté, cela semble simplement signifier que vous n'utilisez pas 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 });
6
Michael Johnson

Il se plaint de l'absence d'une commande MAIL FROM: SMTP. Sans regarder la documentation, je suppose que cela ressemblerait à quelque chose comme $smtp->from('[email protected]') Comme @cjm écrit, vous avez besoin de $smtp->mail('[email protected]');

Certes, il semble un peu ridicule de devoir fournir un nom d’utilisateur après l’authentification, mais cela a du sens d’un point de vue historique et rétro-compatible (la spécification STARTTLS ESMTP peut simplement indiquer ce que vous devez faire pour authentifier, puis le reste de la session se déroule comme dans SMTP normal après l’authentification). Cependant, il serait logique que Net::SMTP vous protège de ces détails d’implémentation.

1
tripleee

Malheureusement, à la fin de l'année 2014, Net :: SMTP :: SSL échoue à l'un des 1 tests d'installation. Par conséquent, le serveur Web gmail (et tous les autres) est inaccessible. Sans installer mon propre serveur de messagerie, le seul moyen que je puisse trouver pour envoyer un courrier électronique à partir de Perl consiste à OLE l’envoyer à Outlook. Outlook utilisera ensuite ses connexions pour faire avancer les choses.

J'espère que quelqu'un pourra me prouver le contraire. 

0
Mike

Pour les services de messagerie utilisant STARTTLS, il est préférable d'utiliser le module NET :: SMTPS, plus récent. Essayez le code suivant:

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;
0
Morey

Btw - bien qu'un peu tard, en tout cas pour les futurs lecteurs, avez-vous reçu le courrier?

Il n'y a pas d'erreur dans la sortie jointe. Vous avez activé le débogage (Debug => 1) dans votre constructeur. Ces messages disparaîtront une fois que vous aurez défini ce paramètre sur 0. L'avantage d'utiliser SMTP est qu'il est inclus dans l'installation standard. Pas besoin d'ajouter de modules. 

0
RB1987