Posts Tagged ‘MIME’

Sending mail and attachments from Perl using NET::SMTP

perlnetsmtp

Sending a mail attachment using NET::SMTP is pretty easy, the only really hard bit is making sure the module is installed on your server and that of course you can run Perl. I’ve written this primarily from doing this from a server but you could ust as easily use this on websites etc…

Basically to send an attachment we need to read the file into a string/ array in Perl which in turn MIME will then associate the content of this string to a reserved file to be attached. We also use MIME to send mutipart emails, so we’ll be using boundaries to separate each part, the headers, the message and the attachment. The code is below:

#!/usr/bin/perl
use Net::SMTP;
use strict;
use warnings;

my $from = 'you@yourserver.co.uk';
my $to = 'me@luckylarry.co.uk';
my $to2 = 'someoneelse@luckylarry.co.uk';
my $attachFile = 'myFile.csv';
my $boundary = 'frontier';
my $data_file="/path/to/file/myFile.csv";

open(DATA, $data_file) || die("Could not open the file");
  my @csv = DATA;
close(DATA);

my $smtp = Net::SMTP->new('smtp-out.yourserver.co.uk');

$smtp->mail($from);
$smtp->recipient($to,$to2, { SkipBad => 1 });
$smtp->data();
$smtp->datasend("Subject: Test mail from youn");
$smtp->datasend("MIME-Version: 1.0n");
$smtp->datasend("Content-type: multipart/mixed;ntboundary="$boundary"n");
$smtp->datasend("n");
$smtp->datasend("--$boundaryn");
$smtp->datasend("Content-type: text/plainn");
$smtp->datasend("Content-Disposition: quoted-printablen");
$smtp->datasend("nTest From Youn");
$smtp->datasend("--$boundaryn");
$smtp->datasend("Content-Type: application/text; name="$attachFile"n");
$smtp->datasend("Content-Disposition: attachment; filename="$attachFile"n");
$smtp->datasend("n");
$smtp->datasend("@csvn");
$smtp->datasend("--$boundary--n");
$smtp->dataend();
$smtp->quit;

exit;

So first up we tell our perl script the installation of where Perl should be with the shebang – #!/usr/bin/perl. Next we say we’re going to use strict and warnings which is just good sense when using Perl, it means the program will error if you haven’t referenced your variables properly or got a typo somewhere.

We then define our variables, who the mail is coming from the recipients – this can be an array instead of a variable per user. Next we the file that we want to attach and the MIME boundary, so every time the boundary variable is called this will be the separator between content types. After this we declare where the actual data file is which we’re going to then line read the csv file and write that to an array to store each line – probably not the most efficient way for larger files.

We finally declare the SMTP object which points to your mail server. We follow this with defining the data for the SMTP object.

$smtp->mail($from);
$smtp->recipient($to,$to2, { SkipBad => 1 });

Who is it coming from? Who is it going to? Skip any bad email addresses. You could use $smtp->to(); instead of recipients but I’m not sure that allows multiple mail addresses.

$smtp->data();
$smtp->datasend("Subject: Test mail from youn");
$smtp->datasend("MIME-Version: 1.0n");
$smtp->datasend("Content-type: multipart/mixed;ntboundary="$boundary"n");
$smtp->datasend("n");

Start the building of the data. First the mail subject, the MIME type and the content type – we’re stating that there will be multiple mixed content sections and each section will be split as defined by the boundary section.

$smtp->datasend("--$boundaryn");
$smtp->datasend("Content-type: text/plainn");
$smtp->datasend("Content-Disposition: quoted-printablen");
$smtp->datasend("nTest From Youn");
$smtp->datasend("--$boundaryn");

We separate that section with a boundary and then give the content type and disposition for our message in the email. Finishing with another boundary definition.

$smtp->datasend("Content-Type: application/text; name="$attachFile"n");
$smtp->datasend("Content-Disposition: attachment; filename="$attachFile"n");
$smtp->datasend("n");
$smtp->datasend("@csvn");
$smtp->datasend("--$boundary--n");

We then do the same but this time for the mail attachment giving a content type and disposition. In this section we then read back the contents of our csv file that we read into an array at the start, this content gets then associated to the reserved filename in our mail attachment content type. Finish this with another boundary.

$smtp->dataend();
$smtp->quit;

exit;

The final thing is to end the data stream/ definition for our NET::SMTP object , quit the SMTP object and then finally issue the exit command to exit our Perl script.

In this case I’m going to be calling my perl script from my bash script on the server, hence why I’m using exit as I really don’t want to keep this open!. And that’s it.

Perl documentation on NET::SMTP is here
More information for the MIME type for Email can be found here