#!/usr/bin/perl # Simple script to demonstrate sending a csv file to an email # recipient. This script assumes that sendmail (or an equivalent) # is being used to send the mail. It could be modified easily to # use SMTP. # In order to run this, install Email::Send and Email::MIME::Creator # via CPAN. # As is, this will only run on a UNIX system because of the sendmail # dependency. Running on windows would require cygwing perl because # activestate perl doesn't support the Email::* modules in general. # Arguments are: # --to recipient email address # --from sender email address # --file file to send (should be csv as we don't check the type) #  --subject optional subject line for the email (filename will be used by default). use strict; use warnings; use Getopt::Long; use Email::MIME::Creator; # MIME email creation module. use Email::Send; # Email sender module. use File::Spec; # This lets us pull apart directories and paths. # Usage message. 'here' document - content is from line after # <parse returns an array of email addresses - # we only want the first one). my ($from) = Email::Address->parse($args{'from'}); die "$0 $args{'from'} is not a valid email address.\n" unless $from; my ($to) = Email::Address->parse($args{'to'}); die "$0 $args{'to'} is not a valid email address.\n" unless $to; # Check the file. Does it exist? unless (-e $args{'file'}) { die "$0: $args{file} does not exist.\n"; } # Is it a plain file? unless (-f $args{'file'}) { die "$0: $args{file} is not a plain file.\n"; } # Can we read it? unless (-r $args{'file'}) { die "$0: $args{file} is not readable.\n"; } # Read the file into a single string. $! is the operating system error. open CSVFILE, $args{file} or die "$0: Unable to open $args{file} - $!\n"; # We can temporarily localise $/ by putting it inside a block - when the # block exits the original value will be restored. my $csv_data; # put here so it's not localised to the block below. { local $/ = undef; $csv_data = ; } close CSVFILE; # Set the subject to either the subject passed in or the name of the file. my $subject = $args{subject} || $args{file}; # Now we create the MIME email object and set some fields. # We're setting the main body of the email to be the name of the file, # the size of the file and the time that we sent the file. my @lt = localtime(time); my ($day, $month, $year) = @lt[3..5]; my $send_time = sprintf("%02d/%02d/%04d", $day, $month + 1, $year + 1900); my $size = -s $args{file}; # Create the main body using a 'here' document. my $message = <splitpath($args{file}); # Now create the parts of the email. MIME messages are composed of parts which # are also MIME messages... my @parts = ( # First one is the body of the message. We're displaying this inline. Email::MIME->create( attributes => { disposition => 'inline', # Display inline. charset => 'US-ASCII', # This could change if needed. content_type => 'text/plain' # MIME type for plain text. }, body => $message), # Second one is our attached file. Email::MIME->create( attributes => { disposition => "attachment", # As attachment filename => $filename, # Just the name, not the path. content_type => 'text/csv', # MIME type for CSV encoding => 'quoted-printable' # How should this be encoded (the default!) }, body => $csv_data ) ); # Now we can create the email itself... # This uses a list ref not a hash as some headers can occur more than once. my $email = Email::MIME->create( header => [ From => $from, To => $to, Subject => $subject ], parts => [@parts] ); # Now we can try to send it! my $sender = Email::Send->new({mailer => 'Sendmail'}); unless ($sender->send($email)) { die "Error sending email: $!\n"; }