"Fossies" - the Fresh Open Source Software Archive 
Member "dovecot-2.3.21/doc/wiki/Pigeonhole.Sieve.Examples.txt" (19 Jun 2019, 15518 Bytes) of package /linux/misc/dovecot-2.3.21.tar.gz:
As a special service "Fossies" has tried to format the requested text file into HTML format (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
1 Pigeonhole Sieve examples
2 =========================
3
4 Contents
5
6
7 1. Pigeonhole Sieve examples
8
9 1. Mail filtering by various headers
10
11 2. Flagging or Highlighting your mail
12
13 3. Spam/Virus rules
14
15 1. Direct filtering using message header
16
17 2. Filtering using the spamtest and virustest extensions
18
19 4. Plus Addressed mail filtering
20
21 5. Vacation auto-reply
22
23 6. Include scripts
24
25 7. Archiving a Mailinglist by Date
26
27 8. Emulating lmtp_save_to_detail_mailbox=yes
28
29 9. Translation from Procmail
30
31 Below are some simple Sieve code examples, more can be found at
32 http://sieve.info/examplescripts.
33
34 Mail filtering by various headers
35 ---------------------------------
36
37 Use if/elsif/else to store messages into various folders/subfolders:
38
39 * ---%<----------------------------------------------------------------------
40 require ["fileinto", "envelope"];
41 if address :is "to" "dovecot@dovecot.org" {
42 fileinto "Dovecot-list";
43 } elsif envelope :is "from" "owner-cipe-l@inka.de" {
44 fileinto "lists.cipe";
45 } elsif anyof (header :contains "X-listname" "lugog@cip.rz.fh-offenburg.de",
46 header :contains "List-Id" "Linux User Group Offenburg") {
47 fileinto "ml.lugog";
48 } else {
49 # The rest goes into INBOX
50 # default is "implicit keep", we do it explicitly here
51 keep;
52 }
53 ---%<----------------------------------------------------------------------
54
55 "anyof" means logical OR, "allof" is AND.
56
57 Forward mails with "order" or "buy" in their subject to another address:
58
59 * ---%<----------------------------------------------------------------------
60 if header :contains "subject" ["order", "buy"] {
61 redirect "orders@company.dom";
62 }
63 ---%<----------------------------------------------------------------------
64
65 Message-ID and recipient of forwarded message are stored in a
66 '.dovecot.lda-dupes' at users home directory to prevent mail loops.
67
68 Flagging or Highlighting your mail
69 ----------------------------------
70
71 Some mail readers use these flags:
72
73 ---%<-------------------------------------------------------------------------
74 require "imap4flags";
75 require "regex";
76 if anyof (exists "X-Cron-Env",
77 header :regex ["subject"] [".* security run output",
78 ".* monthly run output",
79 ".* daily run output",
80 ".* weekly run output"]) {
81 addflag "$label1"; # ie 'Important'/red label within Thunderbird
82
83 # Other flags:
84 # addflag "$label1"; # Important: #ff0000 => red
85 # addflag "$label2"; # Work: #ff9900 => orange
86 # addflag "$label3"; # personal: #009900 => green
87 # addflag "$label4"; # todo: #3333ff => blue
88 # addflag "$label5"; # later: #993399 => violet
89 #
90 }
91 ---%<-------------------------------------------------------------------------
92
93 Local copy of your emails:
94
95 ---%<-------------------------------------------------------------------------
96 require ["envelope", "imap4flags"];
97 if envelope "from" "my_address@my_domain.com"
98 {
99 setflag "\\seen";
100 }
101 ---%<-------------------------------------------------------------------------
102
103 /Useful, when you want sieve to manage your incoming *and* outgoing email (you
104 must ask your mail reader to Bcc your mail to your dovecot in this case)./
105
106 Spam/Virus rules
107 ----------------
108
109 Most spam and virus scanners add a special header to mail messages, so that
110 users can apply filtering accordingly. Depending on how the Sieve interpreter
111 is configured, filtering can either be performed by evaluating these headers
112 directly, or using the spamtest and virustest extensions.
113
114 Direct filtering using message header
115 -------------------------------------
116
117 Evaluating the headers directly is always possible as long as the headers are
118 actually added to the messages by the scanner software. For example, to
119 fileSpamAssassin-tagged mails into a folder called "Spam":
120
121 ---%<-------------------------------------------------------------------------
122 require "fileinto";
123 if header :contains "X-Spam-Flag" "YES" {
124 fileinto "Spam";
125 }
126 ---%<-------------------------------------------------------------------------
127
128 The following example discards SpamAssassin-tagged mails with level higher than
129 or equal to 10:
130
131 ---%<-------------------------------------------------------------------------
132 if header :contains "X-Spam-Level" "**********" {
133 discard;
134 stop;
135 }
136 ---%<-------------------------------------------------------------------------
137
138 Some spam scanners only produce a numeric score in a header. Then, the test
139 becomes more involved:
140
141 ---%<-------------------------------------------------------------------------
142 require ["comparator-i;ascii-numeric","relational"];
143 if allof (
144 not header :matches "x-spam-score" "-*",
145 header :value "ge" :comparator "i;ascii-numeric" "x-spam-score" "10" )
146 {
147 discard;
148 stop;
149 }
150 ---%<-------------------------------------------------------------------------
151
152 *NOTE:* Be very careful when matching against spam score headers using the
153 relational extension and the i;ascii-numeric comparator. This comparator can
154 only be used to match unsigned integers. Strings that do not begin with a digit
155 character represent positive infinity and will therefore always be larger than
156 any score mentioned in your rule! That is why the above example first checks
157 the minus sign explicitly.
158
159 Filtering using the spamtest and virustest extensions
160 -----------------------------------------------------
161
162 When the spamtest [http://tools.ietf.org/html/rfc5235#section-3.2] and
163 virustest [http://tools.ietf.org/html/rfc5235#section-3.3] extensions are
164 configured on the server ( <here>
165 [Pigeonhole.Sieve.Extensions.SpamtestVirustest.txt] is explained how), users
166 (and GUIs) can have a much easier way to filter spam and virus messages
167 respectively. To filter spam, the spamtest extension can for example be used as
168 follows:
169
170 ---%<-------------------------------------------------------------------------
171 require "spamtestplus";
172 require "fileinto";
173 require "relational";
174 require "comparator-i;ascii-numeric";
175
176 /* If the spamtest fails for some reason, e.g. spam header is missing, file
177 * file it in a special folder.
178 */
179 if spamtest :value "eq" :comparator "i;ascii-numeric" "0" {
180 fileinto "Unclassified";
181
182 /* If the spamtest score (in the range 1-10) is larger than or equal to 3,
183 * file it into the spam folder:
184 */
185 } elsif spamtest :value "ge" :comparator "i;ascii-numeric" "3" {
186 fileinto "Spam";
187
188 /* For more fine-grained score evaluation, the :percent tag can be used. The
189 * following rule discards all messages with a percent score
190 * (relative to maximum) of more than 85 %:
191 */
192 } elsif spamtest :value "gt" :comparator "i;ascii-numeric" :percent "85" {
193 discard;
194 }
195
196 /* Other messages get filed into INBOX */
197 ---%<-------------------------------------------------------------------------
198
199 The virustest extension can be used in a similar manner:
200
201 ---%<-------------------------------------------------------------------------
202 require "virustest";
203 require "fileinto";
204 require "relational";
205 require "comparator-i;ascii-numeric";
206
207 /* Not scanned ? */
208 if virustest :value "eq" :comparator "i;ascii-numeric" "0" {
209 fileinto "Unscanned";
210
211 /* Infected with high probability (value range in 1-5) */
212 } if virustest :value "eq" :comparator "i;ascii-numeric" "4" {
213 /* Quarantine it in special folder (still somewhat dangerous) */
214 fileinto "Quarantine";
215
216 /* Definitely infected */
217 } elsif virustest :value "eq" :comparator "i;ascii-numeric" "5" {
218 /* Just get rid of it */
219 discard;
220 }
221 ---%<-------------------------------------------------------------------------
222
223 Plus Addressed mail filtering
224 -----------------------------
225
226 Using the subaddress [http://tools.ietf.org/html/rfc5233/] extension, it is
227 possible to match against the 'detail' part of an e-mail address, e.g. a
228 ''+tag'' suffix to the local part of the address. This is for example useful
229 when you don't want just any +tag to create a directory, but you want to use
230 tagged addresses such as with amavisd-new. This example would place email
231 addressed to user+spam@example.com into user's Spam folder.
232
233 ---%<-------------------------------------------------------------------------
234 require ["fileinto", "envelope", "subaddress"];
235 if envelope :detail "to" "spam"{
236 fileinto "Spam";
237 }
238 ---%<-------------------------------------------------------------------------
239
240 The following more advanced example uses the subaddress
241 [http://tools.ietf.org/html/rfc5233/] extension to handle recipient addresses
242 structured as 'sales+<name>@company.com' in a special way. The '<name>' part is
243 extracted from the address using variables
244 [http://tools.ietf.org/html/rfc5229/] extension, transformed into a format with
245 the first letter in upper case and subsequently used to create the folder name
246 where the message is stored. The folder name is structured as 'users/<name>'.
247 If the '+<name>' detail is omitted from the recipient address, the message is
248 filed in the 'sales' folder.
249
250 ---%<-------------------------------------------------------------------------
251 require ["variables", "envelope", "fileinto", "subaddress"];
252
253 if envelope :is :user "to" "sales" {
254 if envelope :matches :detail "to" "*" {
255 /* Save name in ${name} in all lowercase except for the first letter.
256 * Joe, joe, jOe thus all become 'Joe'.
257 */
258 set :lower :upperfirst "name" "${1}";
259 }
260
261 if string :is "${name}" "" {
262 /* Default case if no detail is specified */
263 fileinto "sales";
264 } else {
265 /* For sales+joe@ this will become users/Joe */
266 fileinto "users/${name}";
267 }
268 }
269 ---%<-------------------------------------------------------------------------
270
271 To work with Postfix, this requires that the envelope "to" still contains the
272 full address, so pass it with the -a flag.
273
274 ---%<-------------------------------------------------------------------------
275 dovecot unix - n n - - pipe
276 flags=DRhu user=mail:mail argv=/usr/local/libexec/dovecot/dovecot-lda
277 -f ${sender} -d ${user}@${nexthop} -a ${original_recipient}
278 ---%<-------------------------------------------------------------------------
279
280 or
281
282 ---%<-------------------------------------------------------------------------
283 mailbox_command = /usr/lib/dovecot/dovecot-lda -a "$RECIPIENT"
284 ---%<-------------------------------------------------------------------------
285
286 Vacation auto-reply
287 -------------------
288
289 Auto-responder functionality is implemented using the vacation
290 [http://tools.ietf.org/html/rfc5230/] extension. The following script sends
291 out-of-office replies when the message is not spam:
292
293 ---%<-------------------------------------------------------------------------
294 require ["fileinto", "vacation"];
295 # Move spam to spam folder
296 if header :contains "X-Spam-Flag" "YES" {
297 fileinto "spam";
298 # Stop here so that we do not reply on spams
299 stop;
300 }
301 vacation
302 # Reply at most once a day to a same sender
303 :days 1
304 :subject "Out of office reply"
305 # List of additional recipient addresses which are included in the auto
306 replying.
307 # If a mail's recipient is not the envelope recipient and it's not on this
308 list,
309 # no vacation reply is sent for it.
310 :addresses ["j.doe@company.dom", "john.doe@company.dom"]
311 "I'm out of office, please contact Joan Doe instead.
312 Best regards
313 John Doe";
314 ---%<-------------------------------------------------------------------------
315
316 It's also possible to include the original subject using the variables
317 [http://tools.ietf.org/html/rfc5229/] extension:
318
319 ---%<-------------------------------------------------------------------------
320 require ["variables", "vacation"];
321 # Store old Subject line so it can be used in vacation message
322 if header :matches "Subject" "*" {
323 set "subjwas" ": ${1}";
324 }
325 vacation
326 :days 1
327 :subject "Out of office reply${subjwas}"
328 :addresses ["j.doe@company.dom", "john.doe@company.dom"]
329 "I'm out of office, please contact Joan Doe instead.
330 Best regards
331 John Doe";
332 ---%<-------------------------------------------------------------------------
333
334 Include scripts
335 ---------------
336
337 It's possible to include other Sieve scripts in your script:
338
339 ---%<-------------------------------------------------------------------------
340 require ["include"];
341 include :global "global-spam";
342 include :personal "my-own-spam";
343 ---%<-------------------------------------------------------------------------
344
345 The lookup directories can be specified with:
346
347 ---%<-------------------------------------------------------------------------
348 plugin {
349 # Directory for :personal include scripts. The default is to use home
350 directory.
351 sieve_dir = %h/sieve
352
353 # Directory for :global include scripts (not to be confused with
354 sieve_global_path).
355 # If unset, the include fails.
356 sieve_global_dir = /etc/dovecot/sieve/
357 }
358 ---%<-------------------------------------------------------------------------
359
360 Both 'sieve_dir' and 'sieve_global_dir' may also be overridden by <userdb extra
361 fields> [UserDatabase.ExtraFields.txt].
362
363 It's not currently possible to use subdirectories for the scripts. Having a '/'
364 character in the script name always fails the include. This is just an extra
365 check to avoid potential problems with including scripts within mail
366 directories.
367
368 Archiving a Mailinglist by Date
369 -------------------------------
370
371 You can archive messages from mailing lists in a date-structured folder tree as
372 follows:
373
374 ---%<-------------------------------------------------------------------------
375 require ["variables","date","fileinto","mailbox"];
376
377 # Extract date info
378 if currentdate :matches "year" "*" { set "year" "${1}"; }
379 if currentdate :matches "month" "*" { set "month" "${1}"; }
380
381 # Archive Dovecot mailing list items by year and month.
382 # Create folder when it does not exist.
383 if header :is "list-id" "dovecot.dovecot.org" {
384 fileinto :create "INBOX.Lists.${year}.${month}.dovecot";
385 }
386 ---%<-------------------------------------------------------------------------
387
388 For example, in March 2013 this puts messages from the Dovecot mailing list in
389 a folder called 'INBOX.Lists.2013.03.dovecot'. It combines the date
390 [http://tools.ietf.org/html/rfc5260#section-4] and variables
391 [http://tools.ietf.org/html/rfc5229/] extensions to extract the required date
392 strings. Using the ':create' argument for the 'fileinto' command, the indicated
393 folder is created automatically if it doesn't exist. The ':create' argument is
394 provided by the mailbox [http://tools.ietf.org/html/rfc5490#section-3]
395 extension.
396
397 Emulating lmtp_save_to_detail_mailbox=yes
398 -----------------------------------------
399
400 If you can't turn this option on, you can emulate the behaviour to some extent
401 with following code.
402
403 ---%<-------------------------------------------------------------------------
404 require ["variables", "fileinto", "envelope", "subaddress", "mailbox"];
405
406 if envelope :matches :detail "to" "*" {
407 # you can prefix with INBOX/ or INBOX. if necessary
408 # remove :create if you want to permit only existing mailboxes
409 fileinto :create "${1}";
410 }
411 ---%<-------------------------------------------------------------------------
412
413 Translation from Procmail
414 -------------------------
415
416 There exists a script which attempts to translate simple Procmail rules into
417 Sieve rules:http://www.earth.ox.ac.uk/~steve/sieve/procmail2sieve.pl
418 (dovecot.org mirror [http://dovecot.org/tools/procmail2sieve.pl])
419
420 Here's the original post announcing it:
421 http://dovecot.org/list/dovecot/2007-March/020895.html
422
423 (This file was created from the wiki on 2019-06-19 12:42)