Creating emails

The email struct is defined as:

defstruct subject: "", 
  from: "", 
  to: [], 
  cc: [], 
  bcc: [], 
  attachments: [], # This has to be %Mailman.Attachment{}. More about attachments below
  data: %{}, # This is the context for EEx. You put here data for your <%= %> placeholders
  html: "", # Actual html template
  text: "", # Actual plain template
  delivery: nil # If the message was created through parsing of the delivered email - this holds the 'Date' header

CC and BCC

To instruct Mailman to actually send copies of your email to the listed CC and BCC recipients, use Mailman.deliver(email, config, :send_cc_and_bcc). This, unfortunately, goes against the behaviour you are probably used to from end-user email apps, but reflects how SMTP servers work.

The :cc/:bcc fields only add corresponding header lines to the rendered email source. They do not, by themselves, magically effect delivery of actual copies to those recipients – they only change what's written on the envelope, so to speak. By default, Mailman will render the email struct and deliver it to the SMTP server only once, with a single set of recipients – those in the :to list. The :send_cc_and_bcc flag is a shortcut that will cause delivery of multiple emails at once. It returns a list of Tasks you can process.

If you need even more fine-grained control over CC/BCC mechanics, you will be best served by the lower-level gen_smtp functions, e.g.

email_tuple = {
  from_address,
  [to_address],
  rendered_message,
}
result = :gen_smtp_client.send_blocking(email_tuple, %Mailman.SmtpConfig{...})

Attachments

Mailman makes it easy to attach files, whether they're on your hard drive or on the internet.

The standard way to create an attachment is to use the attach! function:

Mailman.Attachment.attach!(file_path_or_url, file_name \\ nil, mime_tuple \\ nil)

Use it when creating your email:

attachments: [
  Mailman.Attachment.attach!("test/data/blank.png")
],

file_path_or_url can be an absolute file path, or one relative to the root of your project. You can also give it a URL, in which case Mailman will download the file for you before wrapping it in the Attachment struct.

file_name (optional) allows you to change the attachment's file name in the email.

mime_tuple (optional) allows you to set the MIME type of your file. This is rarely necessary, as Mailman can often infer this information from your file's extension and an included list of common MIME types. However, if that fails, you may specify the MIME type and subtype in a 2-tuple, e.g. {"application", "vnd.openxmlformats-officedocument.wordprocessingml.document"} for a docx file.

Note that the attach! option will throw an exception if it cannot open the file; use the attach function if you want to match on {:ok, attachment}, or {:err, message} instead.

Inline images

Emails can take inline content – typically, this is used for inlined images in the HTML part of the email. To add an inline image, first attach the file using the inline! function (instead of attach! – the arguments are the same). Then reference the image in your HTML body as follows:

<img alt="foobar" src="cid:<%= URI.encode("your_filename.jpg") %>@mailman.attachment" />

The cid: prefix tells the email client that what follows is the Content-ID of an inlined attachment. The @mailman.attachment suffix is a meaningless dummy string (RFC 2392 requires Content IDs to look like email addresses).

Adding extra headers

The deliver function takes an optional third parameter (or fourth, if you are using :send_cc_and_bcc) for that purpose:

Mailman.deliver(your_email_struct, your_config, [{"X-Test-Header", "123"}])