Coming Up for Air

Filtering Mail using JavaMail

At the Lee House, we have an email problem: there’s just too much of it. Over the years of signing up for contests, coupons, and other things, we seem to have amassed a giant number of subscriptions to various lists, which gives us a lot of (usually) junk email. The simple solution, of course, is just to unsubscribe, but some of those are actually occasionally useful. Throw in a pinch of proscratination and laziness, and, well…​ it all just keeps coming. Email clients can help manage this by providing email filters to move these emails out of the inbox, but, in the case of Thunderbird, there are only so many rules you can add to one filter, so you either create multiple rules, or give up trying. Several months back, I moved these rules to a perl-based system, but, thanks to a hard drive crash, I lost all of those. Rather than rebuild that setup, which had its own limitations, I did what every good geek would do: I wrote my own, and here it is. :)

The system itself is really pretty simple. It’s not pretty, probably not too terribly efficient, and may be, generally speaking, not as flexible as some would like it to be, but, so far, it works well for me, and, to be honest, I had fun writing it, so I’m happy. :) The rules are expressed in a JSON file that might look something like this:

rules.json
1
2
3
4
5
6
7
8
9
10
11
12
13
[
    {
        "serverName": "imap.myserver.com",
        "serverPort": "993",
        "useSsl": true,
        "userName": "[email protected]",
        "password": "mypassword",
        "rules": [
            {"destFolder": "Ads","matchingText": "[email protected]"},
            {"type": "delete", "sourceFolder": "Ads", "olderThan" : 90}
        ]
    }
]

The system knows of two types of objects: Acccount and Rule. Each Account gives the server’s name and port, whether or not to use SSL (though this is currently ignored), and the user name and password. The Account also has a list of Rule objects. Each Rule can have a type (whose default is "move"), a source folder (whose default is "INBOX"), a desination folder, a matching text field, and/or an "olderThan" field. In this example, we have two rules. The first moves all email from "[email protected]" from the inbox to a folder called Ads. The second will delete all emails in Ads that are older than 90 days.

Multiple accounts are supported as well. All you have to do is add a new Account object to the top-level list:

rules.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[
    {
        "serverName": "imap.myserver.com",
        "serverPort": "993",
        "useSsl": true,
        "userName": "[email protected]",
        "password": "mypassword",
        "rules": [
            {"destFolder": "Ads","matchingText": "[email protected]"},
            {"type": "delete", "sourceFolder": "Ads", "olderThan" : 90}
        ]
    },
    {
        "serverName": "imap.myserver.com",
        "serverPort": "993",
        "useSsl": true,
        "userName": "[email protected]",
        "password": "mypassword",
        "rules": [
            // ...
        ]
    }
]

The build generates a fat jar, so running it can be done simply with

1
2
3
$ java -jar /path/to/mailfilter.jar /path/to/rules.json
Deleted 0 message(s) for account [email protected]
Moved   0 message(s) for account [email protected]

Add that to cron, for example, and you’re all set.

As I said, it’s not necessarily pretty, but it works (for me) and I thought someone might like to see the JavaMail API in action (even if amateurishly), so I thought I’d share. You can find the source for this cleverly named project on Bitbucket. Suggestions, critiques, pull requests, etc. are always welcome. :)

tags: JavaMail

Quotes

Sample quote

Quote source