Plasma GitLab Archive
Projects Blog Knowledge

Netsendmail_tut



Netsendmail Tutorial

Generating mail messages is a very complicated procedure. Netsendmail provides a comparatively simple interface to accomplish this task without knowing too much about the details of the mail format. Here is a kind of cookbook:

Generate an ASCII Mail

In the simplest case, the mail is an ASCII text. Generate the mail with

 
compose ~from_addr ~to_addrs ~subject main_text

Here, from_addr is the sender's address as pair (name,formal_address), and to_addrs is the list of recipients in the same format. The variable subject contains the subject of the message as string. Finally, main_text is the ASCII text.

Generate an Internationalised Mail

When addresses or the main text contain non-ASCII characters, you should care about the in_charset and out_charset parameters. In general, the strings you pass to compose are encoded as in_charset, and the strings in the generated mail are encoded as out_charset. Usually, it is a good idea to have in_charset = out_charset, or out_charset as a superset of in_charset (otherwise you might get conversion errors).

The default for both parameters is `Enc_iso88591.

Not everything can be internationalised. In particular, the subject, the informal names of mail addresses, the content_description, and the main text can be encoded in a non-ASCII character set. Especially, the formal mail addresses cannot be internationalised. Example:

compose 
  ~in_charset:`Enc_iso885915
  ~out_charset:`Enc_iso885915
  ~from_addr:("Heinz Dräger", "heinz\@draeger.de") 
  ~to_addr:("Marion Schröder", "marion\@irgendwo.de")
  ~subject:"Geschäftlich"
  "Verkaufe Teddy-Bären für 100¤"

Note that when you also pass content_type, the main text is no longer converted according to in_charset and out_charset. It is expected that the main text has already the right encoding, and that the encoding is indicated by the content_type. Example:

compose 
  ~in_charset:`Enc_iso885915
  ~out_charset:`Enc_iso885915
  ~from_addr:("Heinz Dräger", "heinz\@draeger.de") 
  ~to_addr:("Marion Schröder", "marion\@irgendwo.de")
  ~content_type:("text/html", ["charset", Mimestring.mk_param "ISO-8859-1"])
  ~subject:"Geschäftlich"
  "<html><body>Verkaufe Teddy-Bären für 100&euro;</body></html>"
Here, the header fields are encoded in ISO-8859-15, but the main text uses ISO-8859-1.

The function Mimestring.mk_param encapsulates parameter values for several kinds of structured values that may occur in mail headers, here for Content-type. This function takes care of the appropriate representation of the parameter value (e.g. for parameters like "title" that can be internationalised).

Generate a Mail with Attachments

An attachment can simply be passed to compose. For example, to add a file "foo.gif":

compose
  ...
  attachments:[ wrap_attachment
                  ~content_type:("image/gif", [])
                  (new Netmime.file_mime_body "foo.gif") ]
  ...

This creates a multipart/mixed mail. The class Netmime.file_mime_body encapsulates a file as a MIME body that can be attached to the mail (note: The file is not read as a whole into memory, but only chunk by chunk, so you can even attach large files without exhausting memory).

The type multipart/mixed has the special feature that the attached parts can either by displayed "inline" with the other contents, or suggested for saving in a file. This hint is indicated by the Content-disposition header. For example, to have the first attachment "inline", and the second as a file with name "foo.gif", use:

compose
  ...
  attachments:[ wrap_attachment
                  ~content_type:("image/gif", [])
                  ~content_disposition:("inline", [])
                  (new Netmime.file_mime_body "foo.gif");
                wrap_attachment
                  ~content_type:("image/gif", [])
                  ~content_disposition:("attachment", ["filename",
                                                       Mimestring.mk_param "foo.gif"])
                  (new Netmime.file_mime_body "foo.gif") ]
  ...

Generate a Multi-Format Mail

It is possible to generate messages where the main part is available in several formats, e.g. in text/plain and text/html. The mail reader program can select which format can be presented best to the user.

The compose function is not the right means to produce such a mail. It is better to use the more capable functions wrap_parts and wrap_mail for this purpose.

For example, to get a message with the text/plain version s_plain and the text/html version s_html, use:

wrap_mail
   ~from_addr ~to_addrs ~subject
   (wrap_parts
      ~content_type:("multipart/alternative", [])
      [ wrap_attachment
          ~content_type:("text/plain", [])
          (new Netmime.memory_mime_body s_plain);
        wrap_attachment
          ~content_type:("text/html", [])
          (new Netmime.memory_mime_body s_html)
      ])

Here, wrap_attachment is used to encapsulate the two versions of the main text. This works because there is no difference between the format of an attachment and the format of a text part. (Actually, wrap_attachment should be better called wrap_body.) The class Netmime.memory_mime_body encapsulates a string as MIME body.

The function wrap_parts bundles the two versions to the main message, and wrap_mail adds the mail headers necessary to deliver the mail.

Note that the simplest version of the message should be added first, and the fanciest version of the message should be added last.

As a variant, one can also add file attachments. To do so, insert a multipart/mixed container around the multipart/alternative message:

wrap_mail
   ~from_addr ~to_addrs ~subject
   (wrap_parts
      ~content_type:("multipart/mixed", [])
      [ wrap_parts
          ~content_type:("multipart/alternative", [])
          [ wrap_attachment
              ~content_type:("text/plain", [])
              (new Netmime.memory_mime_body s_plain);
            wrap_attachment
              ~content_type:("text/html", [])
              (new Netmime.memory_mime_body s_html)
          ];
        wrap_attachment
          ~content_type:("audio/wav", [])
          (new Netmime.file_mime_body "music.wav")
      ])

Generate an MHTML Message

MHTML is an HTML document with attached resource files like images or style sheets. For example, to have the HTML text s_html bundled with an image and a style sheet, use:

wrap_mail
   ~from_addr ~to_addrs ~subject
   (wrap_parts
      ~content_type:("multipart/related",
                     [ "type", Mimestring.mk_param "text/html" ])
      [ wrap_attachment
          ~content_type:("text/html", [])
          (new Netmime.memory_mime_body s_html);
        wrap_attachment
          ~content_type:("image/gif", [])
          ~content_id:"img1"
          (new Netmime.file_mime_body "my.gif")
        wrap_attachment
          ~content_type:("text/css", [])
          ~content_id:"style1"
          (new Netmime.file_mime_body "style.css")
      ])

Note the content_id arguments that assign names to the individual parts. One can now refer to the parts from the HTML document by cid URLs, e.g. cid:img1 points to the image in the second part.

There is another mechanism using the Content-Location header to resolve hyperlinks to message parts. See RFC 2557 for details.


This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml