It’s weird, I supported a product that implemented sieve some years ago, I use an e-mail platform that uses sieve today, but I’ve never actually written a sieve script. I’ve modified a few in very basic ways, but I didn’t really “get” the syntax intuitively.
Now I made a thing. It’s not a great thing, but it’s a thing.
Fastmail has a neat trick that creates a subdomain per-user automatically, so if your address there is dave@example.com
then *@dave.example.com
will also work. This is great for filtering, but it’s a bit of a pain to maintain. I wanted to create a script that would automatically create a label for each domain, subdomain, mailbox, etc.
It turned into a bit of a beast but it works.
One quirk of Fastmail, internally they use .
as the folder separator and this is exposed in a few places, one of them being sieve rules. If you try to create a folder of “example.com/dave” it will actually create a folder of “example/com/dave”. You can do a literal dot by using ^
instead (this is not an escape sequence, it is an alternate character). So, to create a folder of “example.com/dave” you would use “example^com/dave”. Sounds easy enough, just loop through the mailbox and domain to replace .
with ^
, right?
sieve has no loops. No functions, no recursion. It does have regex, and Fastmail at least does support variables. It turns out nobody can stop me from nesting!
I went up to 6 levels “deep” (6 periods per mailbox name, 6 periods per domain name) and it works. Let’s be honest, if either your domain or your address has more than 6 “.” characters, you’re probably doing something wrong. And I can truncate at that point anyway.
So here it is, a way to label inbound messages automatically based on the mailbox, subdomain (when present) and domain.
And since I am insane, it has a little configuration section at the top so that you can select if you want only the deepest label or all sub-labels as well.
Only the deepest
address | label |
---|---|
dave@example.com | example.com/dave |
test@dave.example.com | example.com/dave/test |
All sub-labels:
address | label |
---|---|
dave@example.com | example.com |
dave@example.com | example.com/dave |
test@dave.example.com | example.com |
test@dave.example.com | example.com/dave |
test@dave.example.com | example.com/dave/test |
But wait, what if I had dave@example.co.uk? Wouldn’t this create a label of co.uk/example/dave
? Yes, yes it would. Given the language limitations I’m not importing the full public suffix list or anything silly, but I did add a couple TLDs as example and you can add more if you like. It only supports up to three levels (2 .
total) as a “root” domain, but that is probably enough and the concept could be extended further. Maybe we could strip the subdomain, domain and suffix separately and make it more generic, but I don’t actually care. If you happen to want that and can’t figure it out, let me know and I’ll bang my head against sieve a bit more.
And so with that, here we are:
It is a work in progress, in that I keep tweaking it a bit, but it’s working well enough for me to share it.