mardi 16 juin 2009

Send mails from EC2 servers using Perl

A more technical post for my geek readers. At Kwaga, we are using a lot of cloud computing, and specifically with the excellent Amazon AWS. Our philosophy is to build stateless processes that can spread across several servers or bundle together on a single instance. We ran recently into a vexing problem: how to send mails from EC2. I'd like to walk you through our solution.


1. Why you need a specific solution ?
You can use sendmail directly, and it often works. But some (a lot in our experience) of the mails will not be delivered. It's probably partly because of the lack of matching reverse DNS records. But spam filters can be a bit arbitrary and the easiest way is to relay outgoing mail through a good smtp provider. (Thanks to Paul Dowman for pointing this to us).

2. authsmtp
We tried a couple of SMTP providers, and finally decided on AuthSMTP. They are reliable, have good service, and our mail that’s delivered through them almost never gets marked as spam. Also, they have monthly quotas rather than daily, so you have a chance to increase it before you hit the limit.

3. net::smtp
Some parts of our process are in Perl so we turned to CPAN and to the Net::SMTP package. Install via cpan, run it... and bang, no way to use the (barely documented) auth call to authorize your mail sender address. It seems the SASL authorization scheme is not supported by authsmtp. So we had to do some poking around with the SMTP protocole to generate a compatible LOGIN AUTH scheme. Here is the full code :


use Net::SMTP;
use MIME::Base64;

sub sendMail {
my $to = shift;
my $subject = shift;
my $body = shift;

my $smtp = Net::SMTP->new('mail.authsmtp.com', Hello => 'the domain you used for authsmtp');
$smtp->datasend("AUTH LOGIN\n");
$smtp->response();$smtp->datasend(encode_base64('your authsmtp username') );
$smtp->response();
$smtp->datasend(encode_base64('your authsmtp password') );
$smtp->response();

$smtp->mail('your authorized authsmtp sender address', AUTH =>'your authorized authsmtp sender address');

$smtp->to($to);
$smtp->data();
$smtp->datasend('To: ' . $to . "\n");
$smtp->datasend('Subject: ' . $subject . "\n");
$smtp->datasend("\n");
$smtp->datasend($body);
$smtp->dataend();
$smtp->quit;
}

Ok, that's all folks, I hope it will save time for some of you!

Aucun commentaire:

Enregistrer un commentaire