http://www.perlmonks.org?node_id=19430

Paav has asked for the wisdom of the Perl Monks concerning the following question: (mail and news)

How do I send an email with Perl (including an attachment)?

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: How do I send an email with Perl (including an attachment)?
by lhoward (Vicar) on Jun 22, 2000 at 17:52 UTC
    There are several ways to send e-mails from perl. My favorite for small jobs like this is Mail::Sendmail. This module is very easy to use:
    use Mail::Sendmail; sendmail( From => 'sender@somewhereelse.com', To => 'recipient@somewhere.com', Subject => 'some subject', Message => "body of the message", );
    If you want to send a file as an attachment, that can be easily done with MIME::Lite.
    use MIME::Lite; my $msg = MIME::Lite->new( From => 'me@myhost.com', To => 'you@yourhost.com', Cc => 'some@other.com, some@more.com', Subject => 'A message with 2 parts...', Type => 'multipart/mixed', ); $msg->attach( Type => 'TEXT', Data => "Here's the GIF file you wanted", ); $msg->attach( Type => 'image/gif', Path => 'aaa000123.gif', Filename => 'logo.gif', ); $msg->send;
Re: How do I send an email with Perl (including an attachment)?
by fongsaiyuk (Pilgrim) on Dec 06, 2000 at 19:29 UTC

    I use Mail::Sender pretty extensively. Here's a code snippet to get you started for sending an email with an attachment. (We let the user's email client determine the helper application to execute based on the file extension of the filename we attach to the message.)

    Mail::Sender lets you customize the MIME stuff, but for simple single files you don't need to do that.

    sub send_email { my $sender = new Mail::Sender({ from => $from_address, }); $sender->OpenMultipart({ to => $to_email, subject => $subject, }); $sender->Body; $sender->SendLine( $msg_body ); $sender->SendFile({ description => 'Raw Data File', encoding => '7BIT', file => $tempfile, }); $sender->Close; }

    I really like this module. You should seriously consider installing it if you find that you are doing a lot with emailing attachments. It has saved me tons of time.

Re: How do I send an email with Perl (including an attachment)?
by electrosphere (Beadle) on Feb 01, 2007 at 16:03 UTC

    My solution uses Mail::Send and sendmail only:

    sub sendAttachment { my( $from, $to, $subject, $filename, $type, $data ) = @_; my $boundary = '==' . time . '=='; # untaint stuff for mailing $ENV{'PATH'} = '/bin:/usr/bin'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; my $msg = new Mail::Send; $msg->to($to); $msg->add('From',$from); $msg->subject($subject); $msg->add('Content-Type', qq(multipart/mixed; boundary="$boundary"; +) ); my $fh = $msg->open; print $fh "--$boundary\n"; print $fh "Content-Disposition: attachment; filename=$filename;\n"; print $fh "Content-Type: $type; name=$filename; charset=iso-8859-1; +\n"; print $fh "Content-Transfer-Encoding: 8bit;\n\n"; print $fh $data; print $fh "--$boundary\n"; $fh->close; }
    Used like so:
    sendAttachment( '"Me, Here" <me@here.org>', 'user@foo.com', 'Quarterly Report - Q1 2007', 'report-q12007.csv', 'text/csv', $data );
Re: How do I send an email with Perl (including an attachment)?
by jcwren (Prior) on Jun 22, 2000 at 17:50 UTC
    Here's a basic sample that sends a message, without a file attachment. Net::SMTP is the key.
    #!/usr/local/bin/perl -w use strict; use Net::SMTP; { my $sender = 0; $sender = Net::SMTP->new ('smtp.mailserver.pm'); $sender->mail ('perlmonk@themonastery.org'); $sender->to ('goddesses@themonastery.org'); $sender->data (); $sender->datasend ("From: perlmonk\@themonastery.org\n"); $sender->datasend ("To: goddesses\@themonastery.org\n"); $sender->datasend ("Subject: Promotions\n"); $sender->datasend ("\n"); $sender->datasend ("Please vote my articles up, I need the XP"\n\n") +; $sender->dataend; $sender->quit; }
    I'll have to let other people tell/show you how to send a file attachment, although I would take a look at Mail::Sender. It looks pretty easy to use. I've never had to mess with that.

    --Chris

    Originally posted as a Categorized Answer.

Re: How do I send an email with Perl (including an attachment)?
by Anonymous Monk on Sep 28, 2004 at 04:15 UTC
    #!/usr/bin/perl -w use Getopt::Long; use IO::File; use MIME::QuotedPrint; use MIME::Base64; use Mail::Sendmail; use strict; use warnings; my $cc; my $bcc; GetOptions( 'cc=s' => \$cc, 'bcc=s' => \$bcc, ); my( $from, $to, $subject, $msgbody_file, $attachment_file ) = @ARGV; my $msgbody = read_file( $msgbody_file ); my $attachment_data = encode_base64( read_file( $attachment_file, 1 ) +); my %mail = ( To => $to, From => $from, Subject => $subject ); $mail{Cc} = $cc if $cc; $mail{Bcc} = $bcc if $bcc; my $boundary = "====" . time . "===="; $mail{'content-type'} = qq(multipart/mixed; boundary="$boundary"); $boundary = '--'.$boundary; $mail{body} = <<END_OF_BODY; $boundary Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable $msgbody $boundary Content-Type: application/octet-stream; name="$attachment_file" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="$attachment_file" $attachment_data $boundary-- END_OF_BODY sendmail(%mail) or die $Mail::Sendmail::error; print "Sendmail Log says:\n$Mail::Sendmail::log\n"; sub read_file { my( $filename, $binmode ) = @_; my $fh = new IO::File; $fh->open("< $filename") or die "Error opening $filename for reading - $!\n"; $fh->binmode if $binmode; local $/; <$fh> }
Re: How do I send an email with Perl (including an attachment)?
by Realbot (Scribe) on Jan 13, 2005 at 13:16 UTC
Re: How do I send an email with Perl (including an attachment)?
by Appy16 (Sexton) on Mar 12, 2010 at 07:34 UTC
    You can make use of MIME::Lite Module. It can be used to send single as well as multiple attachments. FOR MULTIPLE ATTACHMENTS :
    #!/usr/bin/perl use MIME::Lite; $from = 'qwerty\@erweer.com'; $to = 'abcd\@efgh.com'; $Subject = 'Hello'; # Part using which the attachment is sent to an email # $msg = MIME::Lite->new( From => $from, To => $to, Subject => $Subject, Type => 'multipart/Mixed', ); $msg->attach( Type => 'Text', Data => "The attachment contains your file" ); $msg->attach( Type => 'Image/gif', Path => "/abcd/M.gif" ); print "Mail Sent\n"; $msg->send; # send via default
    FOR SINGLE ATTACHMENTS :
    #!/usr/bin/perl use MIME::Lite; $from = 'qwerty\@erweer.com'; $to = 'abcd\@efgh.com'; $Subject = 'Hello'; # Part using which the attachment is sent to an email # $msg = MIME::Lite->new( From => $from, To => $to, Subject => $Subject, Type => 'Image/gif', Path => "/abcd/M.gif" ); print "Mail Sent\n"; $msg->send; # send via default
Re: How do I send an email with Perl (including an attachment)?
by skleblan (Sexton) on Mar 03, 2019 at 21:02 UTC

    For my use-case, I’ve never had easy access to a private/internal mail server. I’ve always used SMTP methods to connect to gmail or yahoo. I haven’t ever tried any of the other solutions (MailTools, Mail::Sendmail), so I don’t know if they work for my scenario. It does look like as of now (Feb 2019), MIME::Lite and Mail::Sender are not recommended by their respective maintainers.

    My solution involves 3 modules:

    I’ve tested this on gmail and yahoo. For gmail, I had to go into my account settings and allow less secure apps to access my account. I think this just refers OAuth. You will still use TLS/SSL to talk to Gmail, so you won't be sending your plaintext password over the Internet.

    use MIME::Entity; use Email::Sender::Simple qw( sendmail ); use Email::Sender::Transport::SMTP; $user = "myself\@gmail.com"; #must be a legitimate email account $pass = "mypassword"; $mailhost = "smtp.gmail.com"; #for yahoo, use smtp.mail.yahoo.com $rcpt = other.user@other.com; #could also send it back to myself; $file = "my_picture.jpg"; $debug = 0; #enable by setting to 1 my $transport = Email::Sender::Transport::SMTP->new( host => $mailhost, port => 465, ssl => "ssl", sasl_username => $user, sasl_password => $pass, debug => $debug ); my $mime = MIME::Entity->build( To => $rcpt, From => $user, Subject => "Simple MIME from Perl", Type => "multipart/mixed"); $mime->attach(Data => "Hungry? Eat a Milky Way", Type => "text/plain"); if(defined $file and -e $file) { $mime->attach(Path => $file, Encoding => "base64", Disposition => "attachment"); } sendmail($mime, { transport => $transport });

      Cool!

      Does it cope with unicode on the subject line or in Data?

        I'm not actually sure. I would assume so, since MIME has the ability to specify alternative character encodings. I'll have to test it out and get back to you.