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

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

I have a recent project that requires a potentially large number of emails to be sent out, each with a unique attachment. (A different text body might be nice, but isn't required) Furthermore, the email itself is HTML with embedded images, and to provide more universal email client support, should have a plain text alternate.

A co-worker and I have spent some time looking through the various perl modules, but we have yet to be able to get one to support all of the above in one email. Netscape 4 seems to be able to send mail that is compatible with just about everything, so we have been using its output as a guideline. I've cleaned it up a little, indented it, and included it at the bottom here.

Mail-Sender apparently either does images/HTML or attachments but not both, (no nesting) MIME-Lite, and MIME-Lite-HTML both looked promising, but a few hours of poking still couldn't get the message formatting the same as that Netscape used.

My co-worker has found a PHP solution which we will be using, but it irks me that we couldn't get it working with Perl. Has anyone encountered a need similar to this? Is it just my inability to get the module working properly? I have a feeling more email-tasks will be coming along in the near future, and I'd like to be ready.

<header stuff> Subject: test Content-Type: multipart/mixed; boundary="------------C5E2B1FC8FFADB6068E11254" X-UIDL: p&+!!8",!!(o4"!Q!]"! This is a multi-part message in MIME format. --------------C5E2B1FC8FFADB6068E11254 Content-Type: multipart/alternative; boundary="------------172AC1BCD76027479338C05A" --------------172AC1BCD76027479338C05A Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit [Image] hi --------------172AC1BCD76027479338C05A Content-Type: multipart/related; boundary="------------C08FD7D2A292CEFA0E9B210D" --------------C08FD7D2A292CEFA0E9B210D Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit <!doctype html public "-//w3c//dtd html 4.0 transitional// +en"> <html> <img SRC="cid:<file>" height=75 width=442> <p>hi</html> --------------C08FD7D2A292CEFA0E9B210D Content-Type: image/gif Content-ID: <file> Content-Transfer-Encoding: base64 Content-Disposition: inline; <filename> <DATA> --------------C08FD7D2A292CEFA0E9B210D-- --------------172AC1BCD76027479338C05A-- --------------C5E2B1FC8FFADB6068E11254 Content-Type: application/pdf; name="cert-noname.pdf" Content-Transfer-Encoding: base64 Content-Disposition: inline; filename="cert-noname.pdf" <DATA> --------------C5E2B1FC8FFADB6068E11254--

Replies are listed 'Best First'.
Re: Sending HTML email w/images + attachment
by vagnerr (Prior) on Aug 21, 2002 at 01:06 UTC
    Have you considered MIME::Lite ?

    It has the advantage that you can build up your own mime mail components. I was faced with a similar problem to yours in the past. I didn't need to use multiparts but I did do image inserts I used HTML::LinkExtor to grab all the images in the HTML page. I've included a code snippit if it will help:-

    Notes:
    • my_print() is my "special" debug print statement (only prints if debug enabled)
    • $opts is my command line arguments hash $opts{'d'} was for debug :)
    • $template was an HTML::Template object
    • the script assumes that images to attach are local to its directory
    Hope this helps
    my $msg = MIME::Lite->new( From => $from_address, To => $email_address, Subject => $subject, Type => 'text/html', Data => $template->output() ); #we need to add any images to the mail if they exist my $parser = HTML::LinkExtor->new(); $parser->parse($template->output()); foreach my $link ($parser->links){ if ($link->[0] eq 'img'){ my_print("Image found [".$link->[2]."] "); if ($link->[2] =~ /^https?:\/\//){ my_print("Absolute! Ignored.\n"); }else{ my ($imgtype,$junk) = reverse split '\.',$link->[2]; $imgtype =~ s/^jpg$/jpeg/; #propper mime name? if(open(TEST,"<".$link->[2])){ my_print("Attaching\n"); close(TEST); $msg->attach(Type =>'image/'.$imgtype, Path =>$link->[2], Filename=>$link->[2], #Disposition => 'inline'); Disposition => 'attachment'); }else{ my_print("Not found, Skipped!!\n"); } } } } if($opts{'d'}){ #debug mode my_print($msg->as_string); }else{ $msg->send(); }


    ---If it doesn't fit use a bigger hammer
      Yes, we did look at MIME::Lite, although we didn't do anything as fancy as search the HTML for images. We just had a list of the images necessary, and did something like:
      foreach $image (@htmlimages) { $msg->attach( Type => 'image/gif', Id => $image, Path => "./$image" ); }
      We had no trouble makeing HTML email with images, or email with attachments, or email with a text alternative, I simply couldn't find a way to combine all three.

      The trick is the nesting a multipart/related inside a multipart/alternative inside a multipart/mixed message, while still having content parts outside the innermost section. If I had something like:
      $msg->close(Type => multipart/related);
      I could probably do it.
Re: Sending HTML email w/images + attachment
by bart (Canon) on Aug 21, 2002 at 21:27 UTC
Re: Sending HTML email w/images + attachment
by mattr (Curate) on Aug 22, 2002 at 06:15 UTC
    I remember finding this recently, hope it helps.

    From Mail::Sender pod:

    Please keep in mind though that it's not currently possible to create nested parts with Mail::Sender. If you need that level of control you should try MIME::Lite.

    But, if you click on the Request Tracker icon, you will note in the correspondence that a function to compose multipart messages with attachments will be added in the future and for now is available in the beta version available (click on the attachment download button).

    Hope this helps.