Sending files as MIME attachments

Recently, a client asked us if it was possible to send attachments via SMTP through Iguana.  Even though the net.smtp documentation does not explicitly mention MIME or attachments, sending files as attachments is simply a process of formatting the body of the SMTP message with both MIME headers and encoded attachment contents.  With this information, it is reasonably easy to create a MIME/SMTP module that wraps smtp.send{} so that it takes a table of attachments and sends them off. The following steps summarize this solution: 

  1. Create a channel for the incoming message(s) that contain the attachment data.
  2. Write the attachment data to a scratch directory as separate files.
  3. Use the mime.send{} functionality to format and encode the files as MIME attachments to a message body.

Here is the specific procedure:

  1. Create and configure a new channel with an LLP Listener source component and a To Translator destination component.
  2. Open the script and commit the first milestone.
  3. Copy and paste the following code snippet into your script, or require it as an external module.
  4. Capture the the attachment data and save it to a scratch location as separate files.
  5. Collect the filenames that you want to attach to the message into a single table.
  6. Invoke mime.send with the same parameters as you would for using smtp.send, passing it the filenames via the additional attachments parameter.

Code

Download the code for mime.lua from our code repository

Note: The purpose of each section in this script is identified with notes right in the code.

Here is some sample code for main():

local mime = require 'mime'


function main()
   -- replace this one liner with whatever logic is needed to identify your attachments
   local files  = {'test.txt'} -- attach "test.txt" located in the Iguana install directory
   
   -- Set up the parameters to be used with sending an email
   local smtpparams={
      header = {To = 'sales@interfaceware.com'; 
         From = '<your email name>'; 
         Date = 'Thu, 23 Aug 2001 21:27:04 -0400';
         Subject = 'Test Subject';},
      username = '<your mail username>',
      password = '<your mail password>',
      server = '<your smtp mail server name>', 
      -- note that the "to" param is actually what is used to send the email, 
      -- the entries in header are only used for display. 
      -- For instance, to do Bcc, add the address in the  'to' parameter but 
      -- omit it from the header.
      to = {'sales@interfaceware.com','admin@interfaceware.com'},
      from = 'Test User ',
      body = 'This is the test body of the email',
      use_ssl = 'try',
      attachments = files,
      --live = true -- uncomment to run in the editor
   } 
   
   mime.send(smtpparams)
end

Implementation Notes

Since sending attachments requires modifying the original message body and headers, this script will modify these parameters before passing them onto smtp.send.

Notice that we are making the distinction between binary and non-binary attachment types. This is, primarily, about creating a message that renders nicely in a variety of mailers upon receipt. The notion of what is a binary attachment and what sort of MIME types are supported is implementation-specific. For example, there is nothing that says that you cannot Base64-encode all attachments, or create your own MIME attachment type (usually preceded by “X-“) to suit.

Most mailers and SMTP servers are quite forgiving when it comes to SMTP formatting errors. Unfortunately, many mailers and servers might be strict enough that they will reject sufficiently complicated MIME messages. Some experimentation may be necessary.
Let us know if you find this tip useful!

John Verne
Senior iNTERFACEWARE Developer

Leave A Comment?