Module 6 · 6.1
English
How filters work
Module 6: Automatic: filters and out of office · Reading time: 10 minutes
Learning objective: After this lesson you can explain where and when filters run, read a filter script in Sieve and predict which folder an incoming message ends up in.
Key concepts: filter, Sieve, ManageSieve, filter set, rule, condition, action, implicit keep, stop, contains, is equal to, matches expression
Filters run on the server
A filter sorts your email automatically: email with "factuur" (invoice) in the subject goes to the folder Facturen, newsletters go to a folder of their own. The most important thing to know: this sorting does not happen in the webmail but on the mail server, at the moment a message is delivered to your mailbox.
Three things follow from that:
- Filters also work when the webmail is closed. Your laptop can be switched off. Your phone sees the email in the right folder straight away.
- Filters only work on new email. Email that is already in your mailbox stays where it is. If you create a filter today, you move the old messages yourself.
- Filters apply to one mailbox. Each mailbox has its own filters. If you want to arrange something for all mailboxes on your domain, such as blocking a sender, you do that in your hosting control panel.
Filters are written in Sieve, a simple language made especially for filtering email (RFC 5228). The mail server at WebOké uses Dovecot with Pigeonhole, Dovecot's implementation of Sieve. The webmail turns the choices you make in the form into a Sieve script and sends it to the server using the ManageSieve protocol (RFC 5804). You don't have to write Sieve yourself, but if you can read it, you understand exactly what your filters do.
Filter set, rules, conditions and actions
A filter set is the complete script: all the filters of your mailbox in one file. You can have more than one filter set, but only one is ever active.
The filter set contains the filters, which the webmail sometimes also calls rules. Each filter has:
- a name, just for you;
- a scope: the message must match all of the rules, any of the rules, or the filter applies to all messages;
- one or more conditions: where the filter looks (subject, sender, another header), how it compares, and with which text;
- one or more actions: what happens when the conditions are met.
There are three ways to compare:
| In the webmail | In Sieve | Meaning |
|---|---|---|
| contains | :contains | the text appears somewhere in the header |
| is equal to | :is | the header is exactly this text |
| matches expression | :matches | pattern with * (zero or more characters) and ? (exactly one character) |
Capital letters make no difference with any of the three. By default Sieve compares using the rule i;ascii-casemap, which treats upper-case and lower-case letters the same. So "factuur" also finds "FACTUUR" and "Factuur".
What a filter set looks like
In the webmail you can view the filter set as text with Filters > Actions > Edit filter set. An example as the webmail writes it:
require ["fileinto"];
# rule:[Nieuwsbrieven]
if exists "List-Id"
{
fileinto "Nieuwsbrieven";
stop;
}
# rule:[Facturen]
if allof (header :contains "subject" "factuur")
{
fileinto "Facturen";
}
# rule:[Collega Daan]
if false # header :contains "from" "daan@example.com"
{
fileinto "INBOX.Team";
}Line by line:
require ["fileinto"];asks the server for the extension needed to move a message to a folder. The webmail adds this at the top itself, with all the extensions the script uses.# rule:[Nieuwsbrieven]is a comment. The webmail uses it to recognise the name of your filter. The server skips the line.if exists "List-Id"is the condition: the message has a List-Id header. Newsletters and mailing lists have one (RFC 2919).fileinto "Nieuwsbrieven";moves the message to the folder Nieuwsbrieven (newsletters). The folder name is the full name on the server, with the dot as separator (lesson 5.1). So a folder under Inbox is calledINBOX.Team.stop;stops the whole script. Later filters no longer look at this message. In the webmail this action is called Stop evaluating rules.if false # ...is a disabled filter. If you switch off Filter enabled, the webmail turns the condition intofalse: never true. The old condition stays as a comment, so you can switch it back on later.

From top to bottom
The server reads the script from top to bottom and checks every filter. Three rules apply.
1. Without an action, the message stays in Inbox. Sieve has an implicit keep (RFC 5228, section 2.10.2): if no filter does anything, the message simply lands in Inbox.
2. After a move, the message is not also in Inbox. A fileinto cancels the implicit keep. The message goes to the chosen folder and not to Inbox as well. If you do want both, use Copy message to.
3. Without a stop, the next filters also look. If stop is missing, the server carries on with the next filter. If that filter matches too, the server carries out its action as well. Two moves to two folders means the message ends up in both folders. With stop, the first matching filter decides.
That is why the order matters. In the example above, Nieuwsbrieven comes before Facturen (invoices), with a stop. So a newsletter with "Je factuur" in the subject goes to Nieuwsbrieven, not to Facturen. If you reverse the order, that same newsletter lands in Facturen, because that filter has no stop and now comes first. The newsletter would even end up in both folders. So put the most specific filters at the top and give them a stop.
Walking through a message: how to predict it
Take a message and go through the script the way the server does:
- Start with the first filter. Is it disabled (
if false)? Skip it. - Is the condition met? Look closely at the header:
subjectis the subject,fromthe sender with name and address,tothe recipient. - If yes: carry out the actions. If there is a
stop, you are done. - If no, or there is no stop: go to the next filter.
- At the end: if no filter has moved or deleted the message, it is in Inbox (
INBOX).
With these five steps you can read any script, even a long one.
In practice: how it works in the webmail
You will find filters under Settings > Filters. The list shows your filters in the order in which the server runs them; drag them to change the order. Under Actions you will find Edit filter set: there you can view and change the script as text. The steps for a new filter are in the Roundcube manual under Creating a filter. Other webmail works in a similar way: Gmail has filters, Outlook.com has rules. They don't use Sieve, but order and stopping apply there too.
Summary
- Filters run on the mail server at delivery, so also when the webmail is closed, and only on new email.
- The webmail writes your filters as a Sieve script (RFC 5228) and puts it on the server using ManageSieve.
- Contains, is equal to and matches expression are not case-sensitive by default.
- If no filter does anything, the message stays in Inbox; after a move it is not also in Inbox.
- Filters run from top to bottom; stop ends the script, so the order decides the outcome.
Quiz
Exercise
Exercise A6.1: Where does this email end up? Open the material filters-1.txt, a filter set as the webmail writes it, and berichten-1.txt, with the headers of four incoming messages, numbered 1 to 4. Go through each message using the five steps from this lesson: from top to bottom, skip disabled filters, watch out for stop. For each message, enter the name of the folder where it ends up, exactly as it appears in the script; if the message ends up in Inbox, enter INBOX. The program compares your four answers with the answer key and shows for each message which filter made the difference.
Further reading
Where steps in the webmail are described, they apply to the WebOké webmail; other webmail works in a similar way.
- Roundcube Webmail 7.1: Creating a filter
- Roundcube Webmail 7.2: Examples of useful filters
- Server-side email rules (filters on the server)
- RFC 5228, Sieve: An Email Filtering Language: https://www.rfc-editor.org/rfc/rfc5228
- RFC 5804, ManageSieve: https://www.rfc-editor.org/rfc/rfc5804
- RFC 2919, List-Id: https://www.rfc-editor.org/rfc/rfc2919
