Skip to content
Benny Kjær Nielsen edited this page Nov 28, 2017 · 13 revisions

This is incomplete and work in progress

Bundle Documentation

Background

MailMate has a plugin system known as bundles. A bundle is a collection of files which can be used to extend the functionality of MailMate, in particular, to provide new commands in the “Command” menu. Most of the existing bundles can be found in the Bundles preferences pane.

Originally, MailMate was supposed to include a graphical user interface (GUI) for creating and editing bundles and therefore it was not documented how to create bundles manually. This was a mistake because the GUI still does not exist and without documentation it has been very hard for users to create new bundles. Hopefully, the following documentation can help some MailMate users in the future.

If you prefer to learn by example then skip ahead to the “Example” section. Also note that all of the bundles available in the Bundles preferences pane are also available on GitHub. In any case, you should make sure that you read about the script, input, output, and environment keywords.

Bundle Locations

Currently, MailMate looks for bundles in the following 3 locations:

~/Library/Application Support/MailMate/Bundles/
~/Library/Application Support/MailMate/Managed/Bundles/
MailMate.app/Contents/SharedSupport/Bundles/

Only the first one is relevant for users wanting to create their own bundles. The second one is used by MailMate to store the bundles enabled in the Bundles preferences pane and the last one contains some bundles distributed with MailMate.

Anatomy of a Bundle

A bundle is a folder containing an info.plist file and one or more folders:

Example.mmBundle/
	Commands/
		Example.mmCommand
	Filters/
		Example.mmFilter
	Themes/
		Example.mmTheme
	Support/
		bin/
			helper_script
	info.plist

The Support folder can be used to contain anything needed for the commands or filters declared in the .mmCommand and .mmFilter files. This could be scripts like the helper_script above or it could be data files needed in the bundle. Anything but the files in the Support foldes has to be so-called property lists. Most of the current bundles use the old-style ASCII format.

ToDo: Support JSON format for property lists.

The info.plist file

This file identifies the bundle with a few key/value pairs.

name

A descriptive name for the bundle, e.g., the name of the application if the bundle provides integration with another application. Currently displayed in the “Command” menu and in the Bundles preferences pane.

description

A short description of the bundle. Currently displayed in the Bundles preferences pane.

contactEmailRot13

An email address for the creator of the bundle after applying the ROT13 algorithm. The following is an example of how to do that in a Terminal window: printf "user@example.com" | tr '[A-Za-z]' '[N-ZA-Mn-za-m]'. This is currently not used anywhere.

uuid

A UUID which uniquely identifies the bundle.

Note that all property list files in a bundle has its own UUID. It is very important that these are never reused. For convenience, a UUID can be put on the pasteboard using the following commands in a Terminal window:

uuidgen | tr -d "\n" | pbcopy

General Keywords

Commands, filters and themes have a few keywords in common.

name

The name is used in the user interface whenever it is needed. Examples include the Command menu for commands and the theme popup menus in the Preferences.

uuid

It's the UUID which uniquely identifies any command, filter or theme. This should always be unique and it should never be changed.

disabled

Some times it is useful to be able to disable something temporarily. This can be done with the disabled keyword like this:

disabled = 1;

Commands and Filters

Commands and filters are very different things, but they do share some keywords. We describe these first and then go into the keywords only relevant for commands or filters.

script

This is the most important key and it should be used in all commands/filters. It provides the script to be executed. This script can be written in any scripting language you like as long as it uses a so-called “shebang” to specify the interpreter. The type of input (on stdin) is defined using the input keyword and the type of output (on stdout) is defined using the output keyword. In addition to this, it's possible to define some environment variables using the environment keyword.

input

Parsing emails is really hard. You need to handle MIME parts, encrypted parts, various encodings like quoted-printable, base64, format=flowed, header encoded words, and various non- or semi-standard formats like tnef. But much worse, you have to work around numerous bugs and legacy types of behavior. Ideally, you need to be able to parse any email created by any version of any email client since the early 1970s.

If MailMate only allowed you to get the raw data of an email then it would be very hard to do anything useful and it would be close to impossible to make it robust. Fortunately, MailMate allows you to get the data you need after it has been decoded and after MailMate has worked around all the bugs and legacy stuff of the past.

On a more philosophical note, the main goal of MailMate is to provide input which takes care of as many of the existing email intricacies as possible before handing over data to commands or other parts of the interface. The many problems concerning the conversion of headers and bodies to any kind of canonical data should be handled by MailMate to keep everything else as simple as possible. In other words, canonicalization is to be MailMate's side of the fence.

The main input needed by a command is defined using the input keyword. This input is then provided on stdin. Unless something else is explicitly specified then the input uses the UTF-8 character encoding. The following options are currently available:

Yes, the current input types are:

  • none (the default)

    No input

  • raw

    The message in its original raw format. This is, for example, suitable for moving messages into other email-capable applications. The character encoding can be anything and there might even be a combination of different encodings in different MIME parts.

  • decoded (commands only)

    The MIME part is decoded if it is, for example, encoded using quoted-printable or base64. This is primarily useful if sending specific MIME parts to a command. For example, an image could be given to the command in its raw (original) binary format. This is not currently used by any of the included commands.

    ToDo: Complete implementation.

  • canonical

    This is equivalent to the text displayed in MailMate when using the “Prefer Plain Text” option. It is, most often, based on the text/plain MIME part. The text is decoded (quoted-printable/base64), deflowed (format=flowed), and converted to UTF-8.

  • html

    This is equivalent to what happens before MailMate displays a message in its message view which means that even a plain text message is converted to HTML. This is probably mainly useful for display purposes.

FIXME: Is this correct????????? Which commands exist which uses this now?

  • selection (commands only)

    The currently selected text in the message view.

  • formatted (commands only)

    This requires an additional formatString key/value pair for the command which is described further below.

environment

A bundle command or filter can also be configured to receive more information via the use of environment variables. Reading environment variables is supported by most scripting languages. Here's a very simple example:

environment = "DEBUG_ENABLED=1";

The script can then use the DEBUG_ENABLED environment variable to change its behavior.

You can specify multiple environment variables using newlines and you can query the headers of the message involved using format strings and specifiers. Here's an example getting the type and subtype of the Content-Type header while defaulting to text/plain:

environment = 'MM_CONTENT_TYPE=${content-type.type:text}\nMM_CONTENT_SUBTYPE=${content-type.subtype:plain}';

...

This is incomplete and work in progress

Developer Documentation

Bundles

Troubleshooting

Microsoft Exchange

Yahoo

Clone this wiki locally