Emails in Perl

Perl is a powerful script language that's been around since the eighties. On Perl modules can be found for almost any task imaginable. Unfortunately some of those modules are poorly maintained, or simply poorly written to begin with.

When you find yourself wanting to send emails in a Perl script, there are lots and lots of different Perl modules to choose from. I recently tried the Email::Sender modules, together with TryCatch for handling any errors. Unfortunately the startup time for my small Perl script increased from milliseconds to several whole seconds when I added usage of those modules, since Perl had to compile the modules every time the script was called. Not ideal for a script that is meant to be called once every minute.

The solution to my problem turned out to be the Unix/Linux command line email client that is simply called mail. Modifying my Perl script to do a system call instead of using any Perl modules caused the startup time for my script to drop down to milliseconds again. Here's my subroutine for sending emails:

use Encode qw/encode decode/;

sub sendMail {
  my ($self, $to, $subject, $message) = @_;

  open(MAIL, '| mail'.
    ' -s "'.encode('MIME-Q', decode('UTF-8', $subject)).'"'.
    ' -a""'.
    ' -a"Content-Type: text/plain; charset=UTF-8"'.
    ' "'.$to.'"')
    || die "Failed to mail: $!\n";
  print MAIL $message;
  close MAIL;
  my $exit = $? >> 8;

  return $exit;

I'm using swedish characters in the mails, therefore I make sure to use UTF-8 encoding. However, standards dictate that no special characters should be used in the subject header of emails, only the lower ASCII characters are allowed. Most servers and clients handle misformed subject headers without problem, but spam filters might downrate non-conformant mails, as can be seen in this excellent mail-tester:

In order to conform to standards regarding the subject header, I use the MIME-Q encoding for the subject string, instead of UTF-8.

The -s argument to mail sets the subject string, and the -a argument sets any header you want. I use -a to change the address displayed in the From field of the email. Otherwise the default address for the user calling the Perl script would be used.

In the end, my subroutine returns the exit value from mail, which is hidden in the variable $? after closing the system call.

Add new comment

By submitting this form, you accept the Mollom privacy policy.