2012-04-04 15 views
12

Próbuję wysłać pocztę przez SMTP w Perlu.Wysyłanie poczty przez SMTP w Perlu

Napisałem scenariusz do tego.

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

Kiedy uruchomić ten skrypt, moje wyjście jest jak następuje:

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} 

nie mam wystarczająco dużo informacji na temat Perl i SMTP, więc nie mogłem zrozumieć tego błędu.

Jak mogę to rozwiązać?

Odpowiedz

21

Musisz rozpocząć sesję SMTP (po autoryzacji, jeśli to konieczne) poleceniem MAIL podając adres e-mail nadawcy. Dlatego odpowiedzi mówią "MAIL first" (5xx to odpowiedź błędu). Więc:

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

Ale jeśli nie jesteś ekspertem SMTP, to dlaczego nie wykorzystać moduł wyższego poziomu jak Email::Sender zamiast niskiego poziomu 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 }); 
+0

Jestem pewien, że twoja odpowiedź rozwiąże mój problem, ale mam nowe pytanie. Pracuję nad oknami. próbowałem zainstalować Email :: Sender w bibliotece Perla. Używam mingw32, ale nie zainstalowałem. – Selin

+1

Prześlij osobne pytanie z odpowiednią diagnostyką, być może na SuperUser. – tripleee

+0

Jak mogę wysyłać treści HTML zamiast zwykłego tekstu? –

1

Narzeka na brak polecenia SMTP MAIL FROM:. Nie patrząc na jakiejkolwiek dokumentacji, to myślę, że to wyglądać mniej więcej tak $smtp->from('[email protected]') Jak @cjm pisze, trzeba $smtp->mail('[email protected]');

prawda, wydaje się nieco głupie musiał podać nazwę użytkownika Bezpośrednio po uwierzytelnieniu , ale ma sens z punktu widzenia kompatybilności historycznej i wstecznej (specyfikacja STARTTLS ESMTP może po prostu określać, co należy zrobić, aby uwierzytelnić, następnie reszta sesji odbywa się tak jak w zwykłym SMTP po wykonaniu uwierzytelniania). Dla użytkownika Net::SMTP ma to sens, aby uchronić Cię przed tymi szczegółami implementacji.

+2

Net :: SMTP to moduł niskiego poziomu; nie jest zaprojektowany, aby chronić Cię przed szczegółami. Do tego celu służą moduły wyższego poziomu (np. Email :: Sender). – cjm

0

Btw - choć nieco późno, w każdym razie dla przyszłych czytelników, czy rzeczywiście recv pocztę?

Na dołączonym wyjściu nie ma błędów. Włączono debugowanie (Debug => 1) w swoim konstruktorze. Komunikaty te znikną po ustawieniu wartości na 0. Zaletą korzystania z protokołu SMTP jest to, że jest on dołączony do instalacji w magazynie. Nie ma potrzeby dodawania modułów.

0

Niestety, w (bardzo) pod koniec 2014 r. Net :: SMTP :: SSL nie przejdzie 1 z 1 testów instalacji, w związku z tym serwer sieciowy (i każdy inny) jest nieosiągalny. Bez instalowania mojego własnego serwera pocztowego, jedynym sposobem, jaki mogę znaleźć, aby wysłać pocztę z Perla, jest OLE do Outlooka. Outlook będzie wtedy wykorzystywał swoje połączenia, aby wszystko działało.

Mam nadzieję, że ktoś może mi udowodnić, że się mylę.

5

Oto zaktualizowana wersja skryptu cjm, który aktualnie współpracuje z Gmailem przy użyciu STARTTLS (nie testowany z innymi usługami SMTP) Używa Email :: Sender :: Transport :: SMTPS zamiast Email :: Sender :: Transport :: SMTP

konta Gmail będzie mieć „Dostęp dla mniej bezpiecznych aplikacji” dozwolony („włączony”) - gdzie „mniej bezpieczne” nie znaczy niezaszyfrowane, to po prostu nie wydaje się oznaczać za pomocą 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 }); 
0

W przypadku usług pocztowych korzystających z programu STARTTLS najlepiej jest użyć nowszego modułu NET :: SMTPS.Wypróbuj następujący kod:

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; 
Powiązane problemy