This spamfilter lets you easily define keyword-based filter rules for each of your email accounts individually. It makes use of Mail.app's scripting interface for Applescript and JXA. Spam messages are marked as Junk and moved to the trash folder.
There are two invokation modes for the spamfilter script that impose different installation tasks. The first mode relies on Mail.app's rule infrastructure to automate handling of new incoming messages dedicated to default inboxes:
- Download
spamfilter.zip
from Releases - Extract zip archive, open Terminal and change working directory to spamfilter directory via
cd path/to/spamfilter
- Run
sh install.sh
- Open Mail.app's preferences pane and go to "Rules"
- Add a new rule with action "Run Applescript" choosing spamfilter.scpt
As rule invokation is restricted to default inboxes it might be desirable to also enable filtering on other mailboxes. The second mode checks all mailboxes in a 15 minutes interval by setting up a launch agent for launchd
daemon:
Perform the steps stated above, except step 3: Run sh install.sh -launchagent
to set up the default launch agent or sh install.sh -launchagent 600
to configure your own interval in seconds, e.g., 600 for 10 minutes.
The configuration of the script as well as your custom rules are stored in spamfilter-rules.json
. Edit this file using the text editor of your choice. A sample might look like this:
{
"shouldAlertMatchDetails": false,
"rulesList": [
{
"email": "me@example.com",
"fromWhitelist": {"shouldTest": false, "list": []},
"senderBlacklist": {"list": ["John Doe", "@evil.org", "GitHub"]},
"subjectBlacklist": {"list": ["50% off", "Account suspended"]},
"contentBlacklist": {"list": ["Dear customer"]},
"headerBlacklist": [{"name": "received", "list": ["from mta.eval.to"]},
{"name": "content-type", "list": ["application/"]}
]
},
{
"email": "foo@bar.com",
"fromWhitelist": {"shouldTest": true, "list": ["GitHub"]},
"senderBlacklist": {"list": ["Jane Doe", "support@evil.org"]},
"subjectBlacklist": {"list": []},
"contentBlacklist": {"list": ["Dear customer"]},
"mailboxList": [{"name": "Another Mailbox",
"fromWhitelist": {"shouldTest": false, "list": []},
"senderBlacklist": {"list": []},
"subjectBlacklist": {"list": ["50% off"]},
"contentBlacklist": {"list": []}
}]
}
]
}
Apart from your account-specific rules the JSON object above comprises general settings like shouldAlertMatchDetails
that always affect the filtering regardless of your rules. shouldAlertMatchDetails set to true (boolean) helps debugging false-positives by telling you which rule has matched.
The rulesList
property contains the array of mail accounts for which you want to enable filtering. Accounts not listed there are not filtered at all. Here's a description of an account rule for its default INBOX:
email
indicates the mail address of your account.fromWhitelist
controls the test wether the sender contains a full name (first name and last name) or just a single word. IfshouldTest
is true, one-word names are considered as spam matches. Whitelist exceptions are likely to be necessary then, e.g., for GitHub in the foo@bar.com rule above.senderBlacklist
compares the "From" header of the message with all items in the corresponding blacklist. Those items can be names, email addresses or only string components of them.subjectBlacklist
compares the "Subject" header of the message with all items in the blacklist.contentBlacklist
compares the message content with all items in the blacklist. Only text content is tested. Binary data is skipped.headerBlacklist
[optional] compares arbitrary message headers defined by thename
property (lower-case) with all items in the corresponding blacklist.mailboxList
[optional] a list of rule objects for additional mailboxes different from the default INBOX. Those rules work analogously to the ones above, but only for a specific mailbox.
All comparisons with list items are case-sensitive.
Unload launch agent in terminal:
launchctl unload -w ~/Library/LaunchAgents/com.github.chsturm.spamfilter.plist
Remove the following files:
~/Library/Application Scripts/com.apple.mail/spamfilter.scpt
~/Library/Application Scripts/com.apple.mail/spamfilter-rules.json
~/Library/LaunchAgents/com.github.chsturm.spamfilter.plist
In addition to your own rules there are some more tests that are always performed and lead to spam matches:
- Self-addressed messages, i.e. sender = receiver, without your full name as sender
- Certain file extensions of binaries sent within messages, e.g., ".exe"
- Certain charsets, e.g., "gb2312" for Chinese
- Zero-width whitespace chars, e.g., "U+FEFF"
There seems to be a bug in Mail.app preventing the correct processing of all messages in case you receive multiple messages at once. A bug circumvention was added to spamfilter.scpt. However, if you still note unprocessed messages, you can trigger the spamfilter by selecting any remaining messages and running Mail.app rules manually via alt+cmd+L
or via its right-click context menu.
Mail only triggers its built-in rule system for new messages stored to the default INBOX, but not in other mailboxes your server may provide. Automatic filtering on all mailboxes is therefore performed as soon as a new message is received in INBOX.