Using sieve to filter and organise your mail on arrival
2009-07-31 – 08:00 by Thijs Braem
- Image via Wikipedia
In Thomas A. Limoncelli’s “Time Management for System Administrators” there’s a chapter about how to manage e-mail. When, a couple of years ago, I first read the book, I implemented some of the tips by using simple Thunderbird filters, but after re-reading now I found room for improvement. The improvement is called: “sieve”. Using these filters I now created in Sieve, I can have the benefits of an empty inbox without having too much of a risk of loosing important e-mails that are needed afterwards (yes, Mr. Limoncelli, sometimes I do need old e-mails as reference or “proof”). So how to get this done?
Doing it in Thunderbird
First: how I did it before. Thunderbird allows for creating filters through the “Tools”>”Message filters” menu. Those are executed on arrival of the messages in the e-mail software, and I had lots of them:
- e-mails from specific mailing lists would go to specific folders I created for those mails. The filters were (and are still) very simple: “Match any of the following” would include from-adresses or “to or cc”-conditions, and “perform these actions” would only consist of “move message to” the specific folder I created for the list. Later I added, for the mailing lists that I sometimes read, but shouldn’t disturb me from my work, the “Mark as read” action. That way I wouldn’t see the “new messages” icon for those that I shouldn’t necessarily read.
- e-mails from certain monitoring systems would also go in specific IMAP folders, usually it “is” important to have these disturb me (they would for instance be Nagios messages indicating that a certain service just went down) so no “Mark as read” there.
- recently i added another one, that would allow me to have an empty inbox. I call it the “Auto Archive” filter and it simply consists of checking the date and if the message is from a certain year, then copy it to the archive folder of that year and then mark it as read (this results in the copy being marked as read, and the original staying unread). This way you can always delete any message from the inbox after processing and know that it still exists in the archive.
The only, but still pretty irritating, problem with this is that it would require all your Thunderbird installations to have those filters in place. This is where Sieve jumps to the rescue, it will filter the mails on arrival on the IMAP server. I’m not quite sure how much mail servers support Sieve by default, but I think it’s quite widespread. Using it is actually pretty self-explanatory, and you will find some websites with good explanations and examples as well.
Managing the scripts
There are generally two ways you can upload your scripts: do it the “sieveshell” command-like way, or use the Thunderbird Sieve plugin.
For sieveshell I installed sieve-connect and cyrus-admin-2.2 as packages in Ubuntu, although I guess only one of those is the one you need, I’m too lazy to find out now. Usage is very easy:
thijs@pingu:~$ sieveshell --authname=thijs imap.server.be
connecting to imap.server.be
Please enter your password:
> help
Usage:
sieveshell [-u username] [-a authname] [-r realm]
help - this screen
list - list scripts on server
put
- upload script to server
get
- get script. if no filename display to stdout
delete
activate
deactivate - deactivate all scripts
quit - quit
>
As you can see you can get a list of existing scripts, get one, change it, then put it up there again and activate it.
Or you could also install the Thunderbird Sieve extension. Install it in Thunderbird, enable Sieve for an account using “Tools”>”Sieve Filter Settings”, setting the right properties (you might have to disable TLS, and maybe your server only allows for “plain” authentication – booh!), and you can go on and add your filter in “Tools”>”Sieve Message Filters”.
Making the scripts
All the filters I spoke of before, were translated into Sieve script. Most of it went smoothly, I just had to look some more into the “copying but leaving the original there” bit, but in the end this also worked out very well. I just paste part of the script as reference, read the comments for more explanations.
#
# 2009-7-29
#
# first make sure you "require" certain modules on the IMAP server:
require ["fileinto", "reject", "imapflags"];
# simple moving to another folder if the sender is a specific address
if header :contains ["From"] "otrs@myserver.be" {
fileinto "OTRS"; # This is an existing folder on the IMAP server, in a lot of cases this will be something like "Inbox.OTRS", but on my specific server it isn't
stop;
}
# now continue all the rest with "elsif", I lost some time over looking for an error when I had typed "elseif" (with an extra e) as it is in most languages
elsif header :contains ["From"] "nagios@myserver.be" {
fileinto "Nagios Notifications";
stop;
}
# this is also just moving to another folder, but this sort of mail shouldn't bother me so there's a little extra...
elsif header :contains ["From"]
["root@myserver.be","root@myotherserver.be"] {
addflag "\\Seen"; # this makes sure that the message is marked as "read"
fileinto "System-administration";
stop;
}
# in this one the "from" as well as the "to" and the "cc" headers can contain any of the e-mail adresses listed
elsif header :contains ["From", "To", "cc"]
["debian-security@lists.debian.org","debian-security-announce@lists.debian.org"]{
fileinto "Mailing lists/Debian-security(-announce)";
stop;
}
# a simpler one, message that shouldn't disturb me
elsif header :contains ["to","cc"] "mailman-users@python.org"
{
addflag "\\Seen"; # there are more cool IMAP flags where this came from!
fileinto "Mailing lists/Mailman-Users";
stop;
}
# the "anyof" function serves as a sort of "or"
elsif anyof (
header :contains ["Subject"] "[Security announcements]",
header :contains ["From"] "noreply@drupal.org",
header :contains ["to","cc"] "support@drupal.org" )
{
addflag "\\Seen";
fileinto "Mailing lists/Drupal";
stop;
}
# have mailman moderation messages moved to their specific folder, you can see that the e-mail addresses are not necessarily complete (if you want that, use the :is operator)
elsif header :contains ["to","cc"]
["-owner@myserver.be","mailman-bounces@myserver.be"]
{
fileinto "Mailman moderation";
stop;
}
# and this is my favourite rule, keeping the "delete" message safe in the inbox!
else {
# ARCHIVE THE MESSAGE BUT LEAVE IT IN INBOX
addflag "\\Seen";
fileinto "ARCHIVES/2009"; # copy a "read" message to the archives folder
removeflag "\\Seen"; # but make the one we keep unread
keep; # this results in a copy both in archives and inbox
stop;
}
That’s it! Just upload your filters to the server, activate it and off you go! There are of course a lot more possibilities I don’t use, or need, but you’ll figure those out by yourself of course :p
![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_e.png?x-id=61bf6794-91e8-4a5a-8540-d4348baa356d)
![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_e.png?x-id=abe437c6-5f34-48d7-a893-a60df64f4d97)
![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_e.png?x-id=37d96c42-0b77-454e-aff2-497d9af4a350)
![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_e.png?x-id=2ac25f29-5165-4334-97e8-c5ff1a6e780c)
![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_e.png?x-id=4895f56a-a47c-43c6-8c28-f2888d9538b2)