Starting out
As with all perl modules, you will first need to import Net::SMTP into your script, with:
use Net::SMTP;
Also, when you first use the library, you must initialise a connection with the new() constructor:
$smtp = Net::SMTP->new('mailserver.domain.name');
When the above line is executed, it will make a connection to port 25 on the server given in the argument, and then will issue the standard Extended SMTP announcement of
EHLO servername. If the server doesn't speak ESMTP, it will return an error, and Net::SMTP will then try again with the earlier SMTP standard of
HELO.
If the connection cannot be made, then the call to
new() will return 0.
new() has a number of options available to it, the most useful of these are:
Timeout - the amount of time (in seconds), it will wait for a response from the SMTP server. If not specified, it defaults to 120 seconds.
$smtp = Net::SMTP->new("unreachable.server.name", Timeout => 10);
if ( ! $smtp ) {
die "Connection to SMTP server failed\n";
}
Port - quite often, SMTP servers run on ports other than the well-known SMTP standard of port 25; port 587 is becoming increasingly popular for SMTP submission from mail user agents. The Port option allows you to specify a different default:
$smtp = Net::SMTP->new("mailserver.domain.name", Port => 587);
Specifying sender and recipient addresses
To initiate an email, we use the
mail() method, and specify the address of the person sending the message:
$smtp->mail("paul@localhost");
Since the '@' symbol is used by perl to identify arrays, we have to escape it with a backslash when it is inserted into code . This is a very common source of hard-to-spot errors, so if you find that your program isn't sending mail, or you find that the sender or recipient addresses look strange, check that you haven't made this mistake.
Now, we need to specify the addresses of those people who will receive the email. Simply create an array with the email addresses in it (properly escaped, of course) and then pass it to the
recipient() method:
@recipients = (
"paul@localhost",
"root@localhost",
"nobody@localhost"
);
$smtp->recipient(@recipients);
You can call
recipient() multiple times, so if you're reading email addresses from a file, just call recipient on each address in turn:
open(ADDRESSLIST,"/path/to/addresslist");
while() {
chomp;
$smtp->recipient($_);
}
close(ADDRESSLIST);
The above code will read a list of addresses from a file, with one address on each line, such as:
paul@localhost
root@localhost
nobody@localhost
guest@localhost
Sending the email
The
data() method is used for sending the content of the message. You must also remember that the
mail() and
recipient() methods only set the addresses for the envelope of the message, and that you must set the other fields in the message header, such as "From:" and "To:" in the
data() method yourself:
$email = <<"EOF";
From: Paul <paul@localhost>
To: Root <root@localhost>
Subject: This is a test
Date: Sun, 9 Mar 2008 00:03:46 +1100
This is a test.
EOF
$smtp->data($email);
The email will be sent when the call to
data() completes.
If you'd prefer not to first build the message in a string prior to sending it, you can use
datasend() and
dataend() to send it line by line, by first sending an empty call to
data():
$smtp->data();
$smtp->datasend("From: Paul <paul@localhost>\n");
$smtp->datasend("To: Root <root@localhost>\n");
$smtp->datasend("Subject: This is a test\n");
$smtp->datasend("Date: Sun, 9 Mar 2008 00:03:46 +1100\n");
$smtp->datasend("\n");
$smtp->datasend("This is a test\n");
$smtp->dataend();
Closing the connection
Once you've finished sending email, use the
quit() method to close the connection:
$smtp->quit();
You can send multiple messages in the same session, by beginning each new message with a call to the
mail() method, so only call
quit() when you're completely finished with the connection.
Error checking
All of the methods listed above return true on success, and false on failure; once the SMTP connection is successfully created, the
message() method can be used to return the message from the last command, and the three digit code from the last command can be obtained with the
code() method:
if (! $smtp->mail("paul@localhost")) {
die "Error: " $smtp->code() . " " . $smtp->message();
}
Authentication
If your mailserver requires SASL authentication for you to be able to send mail out through it, then you can use Net::SMTP's
auth() method to supply a username and password. For this to work, you must ensure that your system has perl's Authen::SASL module installed.
#!/usr/bin/perl
use Net::SMTP;
$smtp = Net::SMTP->new("localhost", Timeout => 2, Port =>587);
if ( ! $smtp ) {
die "Connection to SMTP server failed\n";
}
$ret = $smtp->auth("paul","mypassword");
if ( ! $ret ) {
printf("Authentication failed\n");
} else {
printf("Authentication succeeded\n");
}
Note that this uses SASL's PLAIN authentication mechanism, so the password sent in plaintext.
Putting it all together
We now know enough about Net::SMTP to put together a working script that will send an email out to a few people. Try this script out, and then make some modifications of your own to make it read the list of addresses from a file:
#!/usr/bin/perl
use Net::SMTP;
$smtp = Net::SMTP->new("server.domain.name", Timeout => 120);
# If new() doesn't return a Net::SMTP object, then the connection failed,
# so we die
if ( ! $smtp ) {
die "Connection to SMTP server failed\n";
}
# Start a new email, and set the From address
$smtp->mail("paul@localhost");
# We're sending this to three people
@recipients = (
"paul@localhost",
"root@localhost",
"nobody@localhost"
);
$smtp->recipient(@recipients);
# Build the mail's headers, including the From: and To: address
$headers = <<"EOH";
From: Paul <paul@localhost>
To: Root <root@localhost>
Subject: This is a test
Date: Sun, 9 Mar 2008 00:03:46 +1100
EOH
# Build the content of the mail:
$message = <<"EOM";
This is a test. Please ignore this message.
EOM
# Now send it out:
$smtp->data($headers . "\n" . $message);
# Close the connection to the SMTP server.
$smtp->quit();