]> git.etc.gen.nz Git - mail-merge.git/commitdiff
Add support for attaching a file to emails.
authorAndrew Ruthven <puck@catalyst.net.nz>
Thu, 6 Mar 2014 10:27:29 +0000 (23:27 +1300)
committerAndrew Ruthven <puck@catalyst.net.nz>
Thu, 6 Mar 2014 10:27:29 +0000 (23:27 +1300)
merge.pl

index 40ba3d81e31e2dd9e6f7bbac9699566314e658c1..9732c6973357be412479f3384bde40e990c24e03 100755 (executable)
--- a/merge.pl
+++ b/merge.pl
@@ -11,6 +11,7 @@ use Getopt::Long;
 
 use Text::CSV_XS;
 use MIME::Entity;
+use MIME::Types;
 
 my $dir = undef;
 my $vars = "";
@@ -21,9 +22,9 @@ my $verbose = 0;
 GetOptions(
   'dir=s'    => \$dir,
   'v|vars=s' => \$vars,
+  'verbose'  => \$verbose,
   't|template=s' => \$template,
-  'verbose' => \$verbose,
-  's|send'      => \$send,
+  's|send'       => \$send,
 );
 
 # If we're given a directory then look for the merge files in there.
@@ -67,6 +68,12 @@ my $headers = $csv->getline($IN);
 die "Nothing in $vars!" unless @$headers;
 $csv->column_names(@$headers);
 
+my $mimetypes;
+if ($tmplData->{'attachment_col'}) {
+  die "You've specified an attachment column, but it isn't present!\n"
+    unless grep {/$tmplData->{'attachment_col'}/} @$headers;
+}
+
 while (my $cols = $csv->getline_hr($IN) ) {
   last unless %$cols;
 
@@ -88,9 +95,29 @@ while (my $cols = $csv->getline_hr($IN) ) {
     next;
   }
 
+  my $file_to_attach;
+  if ($tmplData->{'attachment_col'} || $tmplData->{'attachment'}) {
+    my $source = defined $tmplData->{'attachment_col'}
+               ? $cols->{$tmplData->{'attachment_col'}}
+               : $tmplData->{'attachment'};
+
+    if (! $tt->process(\$source, $cols, \$file_to_attach)) {
+      die "Failed to parse $source.\n";
+    }
+
+    if (! -f $file_to_attach && -f "$dir/$file_to_attach") {
+      $file_to_attach = "$dir/$file_to_attach";
+    }
+
+    if (! -r $file_to_attach) {
+      die "Sorry, I can't find $file_to_attach to attach.\n";
+    }
+  }
+
   if ($verbose) {
     print "Subject: $tmplData->{'subject'}\n";
     print "From: $tmplData->{'from'}\n";
+    print "Attachment: $file_to_attach\n" if defined $file_to_attach;
     print $out;
     print "\n\n";
   }
@@ -103,26 +130,45 @@ while (my $cols = $csv->getline_hr($IN) ) {
     # If we're sending email, then send it, optionally with a BCC.
     print "Sending to $email_address" .
        ($bcc ? "\n  BCC " . (ref($bcc) eq 'ARRAY' ? join(", ", @{$bcc}) : $bcc) . " " : '') .
-       ($cc  ? "\n  cC  " . (ref($cc) eq 'ARRAY' ? join(", ", @{$cc}) : $cc) . " " : '') . "\n";
+       ($cc  ? "\n  cC  " . (ref($cc)  eq 'ARRAY' ? join(", ", @{$cc})  : $cc)  . " " : '') . "\n";
 
     my @emails = ( $email_address );
 
+    my %fields;
+    if ($file_to_attach) {
+      $fields{'Type'}     = "multipart/mixed";
+    } else {
+      $fields{'Encoding'} = "quoted-printable";
+      $fields{'Data'}     = $out;
+    }
+
     my $mail = MIME::Entity->build(
        To      => \@emails,
        From    => $tmplData->{'from'},
        Subject => $tmplData->{'subject'},
        Bcc     => $tmplData->{'bcc'},
        Cc      => $tmplData->{'bc'},
-       Encoding=> "quoted-printable",
-       Data    => $out
+       %fields
     );
 
+    if ($file_to_attach) {
+      $mail->attach( Data => $out );
+
+      $mimetypes ||= MIME::Types->new();
+      my $file_type = $mimetypes->mimeTypeOf($file_to_attach);
+      $mail->attach(
+        Path     => $file_to_attach,
+        Encoding => "base64",
+        Type     => $file_type || 'application/octet-stream',
+      );
+    }
+
     $mail->send('sendmail');
   } else {
     # Say who we want to send to.
     print "Want to send to: $email_address" .
        (defined $bcc ? "\n  BCC " . (ref($bcc) eq 'ARRAY' ? join(", ", @{$bcc}) : $bcc) . " " : '') .
-       (defined $cc  ? "\n  CC  " . (ref($cc) eq 'ARRAY' ? join(", ", @{$cc}) : $cc) . " " : '') . "\n";
+       (defined $cc  ? "\n  CC  " . (ref($cc)  eq 'ARRAY' ? join(", ", @{$cc})  : $cc)  . " " : '') . "\n";
   }
 }