filter emails in IMAP accounts
Mailfilters are possible on the server-side and on the client-side.
Client-side filters are usually built-in into your MUA, and only runs when your client program is running, and your computer is online. That is a problem if you use multiple clients (like on your computer and your mobile device).
Server-side filters are built-in into the MTA, and run when the email arrives and before it is delivered to the users mailbox. One example is Sieve.
And then there are email hosting solutions which do not allow server-side mailfilters, and running a client-side filter is not always feasible. There are solutions out there which run on a server somewhere else, one example is lefcha - however lefcha requires you to write Lua code for your filters.
Something more easy is required.
IMAP Mailfilter requires Python3 installed, and a number of additional modules (yaml, sqlite3, imaplib, email, smtplib, urllib). No coding knowledge is required for the configuration.
./imap-mailfilter.py -v -c test.yaml
A configuration file is requires, and is specified using the -c option. Additionally, more verbose output can be enabled using -v, or the program can be more quiet using -q.
The file format for the configuration file is YAML.
config:
database:
accounts:
# every IMAP account starts with a name
Test Account 1:
# the following fields must be provided:
# imap_server
# username
# password
enabled: true
imap_server: imap.gmail.com
smtp_server: smtp.gmail.com
smtp_port: 465
username: <IMAP username>
password: <IMAP password>
ssl: true
Multiple accounts can be specified, every account must have a unique name, and provide:
- enabled: flag, set to true or false
- imap_server: the Hostname or IP-address of the IMAP server
- password: IMAP password
- ssl: flag, set to true or false
Additionally, for the forward rule a SMTP server can be specified:
- smtp_server: the Hostname or IP-address of the SMTP server
- smtp_port: TCP port
Credentials are taken from IMAP server.
The mail rules are nested under the rules section.
rules:
# every rule must have a name
# only use [a-zA-Z0-9 @], end the name with a :
Forward Test:
enabled: true
Every rule must provide a unique name, filter definitions, and actions.
Forward Test:
enabled: true
filter:
folder: "Inbox"
subject: "'Test 123'"
Every filter must provide a folder (actions on IMAP servers are run on the selected folder). In terms of select, the choice is between:
- subject
- from
- to
- body
The filter clauses should be YAML-escaped: "' ... '". The "" are for YAML itself, the '' are for the lexer in Python.
Every filter clause is run through a lexer, this allows usage of AND and OR keywords.
This will search for emails with both Auto and Car inside.
"'Auto' AND 'Car'"
This will search for emails with have either Auto or Car inside.
"'Auto' OR 'Car'"
Filters like subject and from can be used together, and will form an AND search by default. OR can be used as well.
After a rule matches emails, defined actions will be run on the emails.
action:
action-type: delete
Only for debugging purposes.
action:
action-type: test
This one is easy, it will just delete the email.
action:
action-type: delete
Forwards the email to a specific recipient.
action:
action-type: forward
recipient: recipient@address
The forward address must be defined, and in addition the account configuration must have smtp_server and smtp_port specified.
Note: some email providers like Google do not let you change the sender of the email, unless you verify the email address in your account. The tool will try to set the from address to the original from address in the email, but this might be overridden by Google.
This handles mails from Mailman2 which request specific actions.
action-type: mailman2
mailman-password: thelistpassword
mailman-action: discard
mailman-subject: Test
The list password must be specified, in order to let the tool handle the email. Also the action must be defined, and can be one of:
- defer
- approve
- reject
- discard
Because of the way Mailman2 works, you have to specify new search rules for the listed mails. The info email does not direct to a specific email which must be handled, but only let's you login into the administration interface, and there you will find all pending emails. Therefore either mailman-subject or mailman-from must be specified to identify the emails which needs to be handled.
This handles mails from Majordomo which request specific actions.
action:
action-type: majordomo
action-url: https://listserver/mj/mj_confirm/domain
majordomo-action: reject-quiet
The action-url part is the URL to the list server, and will be used to identify the full link in the email. The majordomo-action part can be one of:
- accept
- accept-archive
- accept-hide
- reject
- reject-quiet
This handles moderation mails from the PostgreSQL Maílinglist system which request specific actions.
action:
action-type: pglister
pglister-action: approve
pglister-subject: Test
pglister-from: sender@address
The pglister-action part can be one of:
- approve
- whitelist
- discard
- reject
- cleanup
Where the first four are know actions to the Mailinglist system, and the last is an internal action.
Except for the cleanup action, either pglister-subject or pglister-from, or both, must be specified.
The cleanup action will delete old moderation emails, where the token is expired (because someone else might have moderated the email). Make sure that delete-after is set to false for this rule!
There are two additional options which can be applied to every email which is found by the filters:
This will delete the email once the action part is completed.
delete-after: true
This will remember if an email was processed before, and not repeat the action. Useful for forward rules.
remember: false