http://qs321.pair.com?node_id=1211026

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks,

I'm trying to send pdf files as attachment in emails sent with Net::SMTP. The PDF files reside on my website (like home/mysite/files/PDF_FILES_HERE).

The code I have below is for sending normal emails:

use strict; use Net::SMTP; use MIME::Base64; my $smtphost = 'some_smtp_host'; my $username = 'some_username'; my $password = 'some_password'; my $emailto = 'to@hello.com'; my $emailfrom = 'from@hello.com'; my $subject = 'Hello world'; my $message = 'Test message'; sub date_r { my ($monthday, $mon, $yr, $ time, $hour, $str); my (@lt) = (); @lt = localtime(); $monthday = $lt[3]; $mon = $lt[4]+1; $yr = $lt[5] + 1900; $hour = $lt[2]; $time = sprintf("%02d:%02d:%02d", $hour, $lt[1], $lt[0]); $str = $mon . '/' .$monthday . '/' . $yr . ' ' . $time; return $str; } my $smtp = Net::SMTP->new($smtphost, Debug => 1, Timeout => 5); $smtp->datasend("AUTH LOGIN\n"); $smtp->datasend(encode_base64($username)); $smtp->datasend(encode_base64($password)); $smtp->mail($emailfrom); $smtp->to($emailto); $smtp->data(); $smtp->datasend("MIME-Version: 1.0\n"); $smtp->datasend("From: $emailfrom\n"); $smtp->datasend("To: $emailto\n"); $smtp->datasend("Date: " . date_r() . "\n"); $smtp->datasend("Subject: $subject"); $smtp->datasend("\n\n"); $smtp->datasend($message); $smtp->datasend("\n\n"); $smtp->dataend(); $smtp->quit;

What do I need to change to make so that I can send attachments (pdf files)?

Please enlighten me. Thank you in advance.

Replies are listed 'Best First'.
Re: Using Net::SMTP to send pdf attachment
by Jenda (Abbot) on Mar 16, 2018 at 14:10 UTC

      Thank you Jenda.

      I tried with Mail::Sender and yes, it works :) However, I can't seem to use other email for "from" other than the one I created for my website - maybe it's a restriction from my webhost?

        That's quite possible. What does the SMTP server respond when you try? You can instruct Mail::Sender to write the conversation into a log file.

        Does your webhost specify any credentials you might use to log in to the SMTP server for sending without these restrictions?

        You might try to connect directly the mail server where your mailbox is stored. You may try to

        nslookup set type=MX the.domain.in.your.mail
        and use the mail exchanger this displays as the SMTP server to send to your email with a different "From" address. Though the SMTP port may be blocked by your web host.

        Jenda
        Enoch was right!
        Enjoy the last years of Rome.

Re: Using Net::SMTP to send pdf attachment
by thanos1983 (Parson) on Mar 16, 2018 at 10:36 UTC

      Thank you thanos1983.

      This is what I have tried:

      use strict; use Net::SMTP; use MIME::Base64; my $smtphost = 'some_smtp_host'; my $username = 'some_username'; my $password = 'some_password'; my $emailto = 'to@hello.com'; my $emailfrom = 'from@hello.com'; my $subject = 'Hello world'; my $message = 'Test message'; sub date_r { my ($monthday, $mon, $yr, $ time, $hour, $str); my (@lt) = (); @lt = localtime(); $monthday = $lt[3]; $mon = $lt[4]+1; $yr = $lt[5] + 1900; $hour = $lt[2]; $time = sprintf("%02d:%02d:%02d", $hour, $lt[1], $lt[0]); $str = $mon . '/' .$monthday . '/' . $yr . ' ' . $time; return $str; } my $smtp = Net::SMTP->new($smtphost, Debug => 1, Timeout => 5); $smtp->datasend("AUTH LOGIN\n"); $smtp->datasend(encode_base64($username)); $smtp->datasend(encode_base64($password)); $smtp->mail($emailfrom); $smtp->to($emailto); $smtp->data(); my $boundary = 'frontier'; my $attachBinaryFile = 'helloworld.pdf'; $smtp->datasend("MIME-Version: 1.0\n"); $smtp->datasend("Content-type: multipart/mixed;\n\tboundary=\"$boundar +y\"\n"); $smtp->datasend("--$boundary\n"); $smtp->datasend("Content-type: text/plain;\n"); $smtp->datasend("\nSome plain text here in the body of the email\n"); $smtp->datasend("\n"); $smtp->datasend("--$boundary\n"); $smtp->datasend("Content-Type: application/pdf; charset=utf-8; name=\" +$attachBinaryFile\"\n"); $smtp->datasend("Content-Disposition: attachment; filename=\"$attachBi +naryFile\"\n"); $smtp->datasend("Content-Transfer-Encoding: 8bit\n"); my $pdfbody = do { local $/; open my $fh ,'<', "/path/helloworld.pdf" or die "pdfread: $!"; <>; }; $smtp->datasend("\n"); $smtp->datasend("$pdfbody\n"); $smtp->datasend("--$boundary\n"); $smtp->dataend(); $smtp->quit;

      I do get the email message and the pdf attachment in the email. But I am not able to open the pdf attachment - some sort of data corruption.

      Please help.

        Hello again Anonymous Monk,

        You need to treat the pdf as binary file. For the moment I do not have the time to play with your script to modify it but here is a sample of code that I just tested and works with pdf attachment using MIME::Lite.

        #!/usr/bin/perl use strict; use warnings; use MIME::Lite; use Getopt::Std; my $SMTP_SERVER = '127.0.0.1'; # CHANGE ME my $DEFAULT_SENDER = 'sender@example.com'; # CHANGE ME my $DEFAULT_RECIPIENT = 'recipient@example.com';# CHANGE ME MIME::Lite->send('smtp', $SMTP_SERVER, Timeout=>60); my (%o, $msg); # process options getopts('hf:t:s:', \%o); $o{f} ||= $DEFAULT_SENDER; $o{t} ||= $DEFAULT_RECIPIENT; $o{s} ||= 'Your binary file, sir'; if ($o{h} or !@ARGV) { die "usage:\n\t$0 [-h] [-f from] [-t to] [-s subject] file ...\n"; } # construct and send email $msg = new MIME::Lite( From => $o{f}, To => $o{t}, Subject => $o{s}, Data => "Hi", Type => "multipart/mixed", ); while (@ARGV) { $msg->attach('Type' => 'application/octet-stream', 'Encoding' => 'base64', 'Path' => shift @ARGV); } $msg->send( ); __END__ $ perl client.pl Documentation.pdf

        Hope this helps, BR.

        Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: Using Net::SMTP to send pdf attachment
by eighty-one (Curate) on Mar 16, 2018 at 15:11 UTC

    I just happen to be working on a program that I thought was using Net::SMTP but, when I switched over to my editor, it looks like I was wrong and it's using MIME::Lite

    The MIME::Lite stuff here is a lot clearer than the Net::SMTP stuff from our other scripts if I'm remembering correctly - if you can use it, then I'd recommend that you do.

    If you are stuck using Net::SMTP for whatever reason I would first take a look at this node to see if it's of any help (it has info on installing modules in situations where you may not think you have the ability to do so).

    If that's not helpful, here are a couple of notes you might find useful, dealing with the problem you're running into:

Re: Using Net::SMTP to send pdf attachment
by Anonymous Monk on Mar 16, 2018 at 14:10 UTC
    Being an unabashedly lazy bastard I would just use something like Mail::Builder, Mail::Sender, Mail::Sender::Easy. Why grovel in the bits-and-bytes of SMTP when someone else has done it for you, and done it so very well? (At the very least, look at their source code and steal how they did it.)