Tuffmail & Sieve

April 11, 2007

One of the reasons I used to run my own mail server was so I could do server-side mail filtering of messages into various folders depending on their content. I’d normally reach for procmail for this but with Tuffmail, which I’ve recently started using, server-side mail filtering is provided by way of Sieve filters.

Writing Sieve filters isn’t particularly hard, but here’s a few things worth noting (I believe them to be Tuffmail-specific):

  • Most tutorials and examples on the ‘Net use ‘.‘ as the mailbox separator, while Tuffmail use ‘/‘. Your Sieve rules must use slashes as mailbox separators if you want to file mail into nested folders (e.g. INBOX/Lists instead of INBOX.list). (Alternatively, you can change the separator back to being a ‘.‘)
  • Folders are not created automatically. If you configure Sieve to deliver mail into a folder that doesn’t exist your mail will just go to INBOX instead.
  • The ANS (Alternate Name Space) setting must be taken into account when filing mail into subfolders. (If it is off, you’ll want to file into INBOX/Lists/Doxygen; if it is on, use Lists/Doxygen.)

In addition to these caveats I found the Sieve documentation to be rather impenetrable. To help you get started using it, here’s a snippet that files Svk and Doxygen mailing list messages into their own folders and all other list messages into a third:

require "fileinto";

if header :contains ["List-Id"] "doxygen" {
    fileinto "INBOX/Lists/Doxygen";

} elsif header :contains ["List-Id"] "svk" {
    fileinto "INBOX/Lists/Svk";

} elsif exists ["List-Id"] {
    fileinto "INBOX/Lists/Misc";
}

The “List-Id” header is an RFC<mumble> header used by well-behaving mailing lists to identify themselves, so it’s a great header to filter on. The last clause is a catch-all—it just checks if the List-Id header exists at all.

Leave a Reply