Using Sieve for server-side mail filtering
If your mail server supports Sieve mail filtering language, you can use a simple text scripts to enable powerful mail filtering and management that is applied directly on server-side. This allows you to create filters that will works client-independenty (a true saviour for those enforced to use Microsoft Outlook).
Sieve has no variables, and no loops (but does have conditionals). Thus, it is limited to simple filtering operations.
But that is enough for:
- developing simple anti-spam system,
- managing and organising mails, but auto-moving incoming messages to corresponding folders,
- rejecting certain e-mails automatically (i.e. if they’re too big or contain invalid attachment).
Here you will find some general info and a few simple script examples.
Sieve’s grammar is limited and has a significant number of restrictions, in order to reduce the complexity of parsing the language and by the same time — to reduce resources eaten by execution of Sieve’s scripts. Sieve is fully Unicode-aware.
Rules
Never forget about these general rules:
- first condition always starts with
if
, - following conditions starts with
elseif
, - last condition always starts with
else
and is mandatory (see below), - script starts with
require
clause which lists all extensions that are used in following filtering rules, - single rules are written directly; multi-conditional rules require
anyof
clause, putting them into brackets and separating them with commas (see examples).
In addition to third rule, the last condition is always mandatory and must contain keep
command in order to deliver all e-mails, that are not filtered out by earlier rules, in an unchanged way.
Examples
Some examples follows.
Example no 1: Automatic rejection of all e-mails that are larger than 10 MB. This covers e-mail size in general — both attachments and in-line media:
# Messages bigger than 10M will be rejected with an error message.
#
if size :over 10M {
reject "E-mails larger than 10 MB in size are automatically rejected
by this system. Please upload larger files to some service or a FTP
server and send the link instead. Thanks.";
}
The require ["reject"];
clause is required in first line — to declare extension used in above script.
Example no 2: Auto-put messages in certain conditions to a selected folder:
# Mailing list-related e-mails will be put into corresponding folder.
#
if address :is ["From", "To"] "training@nobleprog.co.uk" {
fileinto "INBOX.NobleProg";
}
The require ["fileinto"];
clause is required in first line — to declare extension used in above script.
Example no 3: Similar to above, move all e-mails automatically generated by an Atlassian software’s to folders:
# Message contain "JIRA" or "COKS" in subject will put into the "JIRA" folder,
# which is a sub-folder of an "Atlassian" root folder (and not in Inbox).
#
if header :matches "Subject" ["*JIRA*","*COKS*"] {
fileinto "[0] Atlassian.JIRA";
}
or:
# Message contain "Confluence" in subject will put into the "Confluence" folder,
# which is a sub-folder of an "Atlassian" root folder (and not in Inbox).
#
if header :matches "Subject" ["*Confluence*"] {
fileinto "[0] Atlassian.Confluence";
}
Again this require the require ["fileinto"];
clause in first line in order to work.
Example no 4: Simple spam-filtering system:
# Message that does not contain certain (my) address in To:, CC: or BCC: (in
# header) or message with something like "money" or "Viagra" in subject will be
# put automatically to Spam-folder.
#
if anyof (
not address :all :contains ["To", "Cc", "Bcc"] "john.doe@false.server",
header :matches "Subject" ["*money*","*Viagra*"]
) {
fileinto "INBOX.spam";
}
Summary
Don’t forget about:
keep
clause at the end,- declaration of required extensions in the beginning,
- correct usage of
if
,elseif
andelse
, if you have more than one condition.
The whole example Sieve script could look like this:
# Declare the extensions used by this script.
#
require ["fileinto"];
# Message contain "JIRA" or "COKS" in subject will put into the "JIRA" folder.
#
if header :matches "Subject" ["*JIRA*","*COKS*"] {
fileinto "[0] Atlassian.JIRA";
}
# Message contain "Confluence" in subject will put into the "Confluence" folder.
#
elsif header :matches "Subject" ["*Confluence*"] {
fileinto "[0] Atlassian.Confluence";
}
# Keep the rest.
# This is not necessary because there is a "implicit keep" Rule
#
else {
keep;
}
Conclusion
With this simple scripting language and a number of easy-to-learn clauses you can filter-out e-mails (on any mail server supporting Sieve) easily and increase your productivity a little bit.
Blog post based on Wikipedia article and own experience.