1 unstable release
0.3.2 | Nov 20, 2022 |
---|---|
0.3.1 |
|
0.3.0 |
|
#8 in #sieve
29 downloads per month
44KB
944 lines
sieve-generator
This is a CLI used to generate .sieve
email filter allowlist for different folders based on the receiver email address, configured with a JSON
file. I have a catch-all email domain and use it automates the allowlist creating process whenever I use a new email. (e.g. something@domain.com
filtered to something
folder)
Installation
cargo install sieve-generator
or download the binary, only tested on Linux.
Usage
Let say we have JSON
config file like this
{
"domain.com": {
"options": { // global options
// if every folder should be a sub-folder of a domain named folder
"domain-as-first-folder": false,
},
"Newsletter": {
"Software": ["google", "facebook"],
"Business": "wallstreet"
},
"Utilities": {
"self": ["electricity"],
"Grocery": {
"localparts": "market",
// if title or sender contains keyword then go to label
// by default every labeled mail will not be marked read
// even if silent is set
"labels": {
"label": "keyword",
"label2": ["keyword2"]
},
"options": {
// the generic filter here will be grocery.secret and
// not utilities.grocery.secret
"orphan": true,
// mark all email of this folder as read
"silent": true,
// not generate generic filter for this folder
"generic": false
}
}
}
}
}
A .sieve
filter allowlist will be generated in which
- It applies to all email sent to
*@domain.com
wallstreet@domain.com
will be filtered toBusiness
folder ofNewsletter
parent folder and so on.- The filter for a parent folder with children (e.g.
Utilities
) is set usingself
keyword. - There are short form filter (e.g.
Business
folder) and full form (e.g.Grocery
) that allows to specify options and a label rule. - There is a generic filter generated for each in the folder tree, e.g.
newsletter.business.*@domain.com
is filtered toBusiness
folder. - Every mails that are not allowlisted will be put in an
Unknown
folder by default. Unknown
is a special folder, everything go there will be silent, even if explicitly configured.
The JSON
above will produce
# @domain.com
if envelope :domain :is "to" "domain.com" {
# Custom filters
if envelope :localpart :matches "to" ["market"] {
if header :contains ["from","subject"] ["keyword","keyword2"] {
if header :contains ["from","subject"] ["keyword"] {
fileinto "label";
}
if header :contains ["from","subject"] ["keyword2"] {
fileinto "label2";
}
} else {
addflag "\\Seen";
fileinto "unread";
}
fileinto "Utilities";
fileinto "Utilities/Grocery";
} elsif envelope :localpart :matches "to" ["electricity"] {
fileinto "Utilities";
} elsif envelope :localpart :matches "to" ["google","facebook"] {
fileinto "Newsletter";
fileinto "Newsletter/Software";
} elsif envelope :localpart :matches "to" ["wallstreet"] {
fileinto "Newsletter";
fileinto "Newsletter/Business";
}
# Generic filters
elsif envelope :localpart :matches "to" ["utilities","utilities.*"] {
fileinto "Utilities";
} elsif envelope :localpart :matches "to" ["newsletter.software","newsletter.software.*"] {
fileinto "Newsletter";
fileinto "Newsletter/Software";
} elsif envelope :localpart :matches "to" ["newsletter.business","newsletter.business.*"] {
fileinto "Newsletter";
fileinto "Newsletter/Business";
} elsif envelope :localpart :matches "to" ["newsletter","newsletter.*"] {
fileinto "Newsletter";
} else {
addflag "\\Seen";
fileinto "Unknown";
}
}
Dependencies
~3.5–6MB
~104K SLoC