2012-04-04 198 views
12

我試圖通過SMTP在Perl中發送郵件。在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('[email protected]'); 
$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:<[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足夠的信息,讓我無法理解這個錯誤。

我該如何解決這個問題?

回答

21

你有(,授權後,如有必要),以啓動一個SMTP會話使用MAIL命令給發件人的電子郵件地址。這就是爲什麼回覆說「MAIL優先」(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 }); 
+0

我相信你的答案將解決我的問題,但我有一個新的問題。我正在研究windows。我試圖安裝電子郵件::發件人到Perl庫。我使用mingw32,但沒有安裝。 – Selin 2012-04-04 10:46:34

+1

用適當的診斷程序發佈一個單獨的問題,也許在SuperUser上。 – tripleee 2012-04-04 11:35:33

+0

如何發送HTML內容而不是純文本? – 2013-03-12 11:13:30

1

它抱怨缺乏MAIL FROM: SMTP命令。 不看任何資料,我猜它會看起來像$smtp->from('[email protected]')像@cjm寫道,你需要$smtp->mail('[email protected]');

誠然,這似乎有點傻必須提供用戶名,你剛纔認證之後,但從歷史和向後兼容的角度來看,它是有意義的(STARTTLS ESMTP規範可以簡單地陳述您需要做什麼來進行身份驗證,然後會話的其餘部分在完成身份驗證後就像常規SMTP一樣發生)。儘管如此,Net::SMTP可以讓你屏蔽這些實現細節。

+2

Net :: SMTP是一個低級模塊;它的目的不是爲了保護你的細節。有更高級別的模塊(如Email :: Sender)可以做到這一點。 – cjm 2012-04-17 22:55:57

0

順便說一句 - 雖然有點晚了,對於未來的讀者來說,你真的收到郵件嗎?

有在連接輸出中沒有錯誤。你已經在你的構造函數中啓用了debug(Debug => 1)。一旦您將其設置爲0,這些消息就會消失。 使用SMTP的優點是它包含在股票安裝中。無需添加模塊。

0

可悲的是,(非常)2014年年底,網:: SMTP :: SSL失敗1 1的安裝測試,因此Gmail中(以及任何其他)基於Web服務器無法訪問。在沒有安裝我自己的郵件服務器的情況下,我可以從Perl發送電子郵件的唯一方法是將其OLE發送到Outlook。然後,Outlook將使用其連接來完成任務。

我希望有人能證明我錯了。

5

以下是當前使用STARTTLS(未與其他SMTP服務一起測試)使用Gmail的cjm腳本的更新版本 它使用電子郵件::發件人::傳輸:: SMTPS代替電子郵件::發件人::傳輸:: 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 }); 
0

對於使用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;