Coming Up for Air

Filtering Mail using JavaMail

Wednesday, September 04, 2013 |

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": "myaddress@example.com",
        "password": "mypassword",
        "rules": [
            {"destFolder": "Ads","matchingText": "deals@somesite.com"},
            {"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 "deals@somesite.com" 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": "myaddress@example.com",
        "password": "mypassword",
        "rules": [
            {"destFolder": "Ads","matchingText": "deals@somesite.com"},
            {"type": "delete", "sourceFolder": "Ads", "olderThan" : 90}
        ]
    },
    {
        "serverName": "imap.myserver.com",
        "serverPort": "993",
        "useSsl": true,
        "userName": "mysecondaddress@example.com",
        "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 myaddress@example.com
Moved   0 message(s) for account myaddress@example.com

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. :)

Search

    Quotes

    Sample quote

    Quote source

    About

    My name is Jason Lee. I am a software developer living in the middle of Oklahoma. I’ve been a professional developer since 1997, using a variety of languages, including Java, Javascript, PHP, Python, Delphi, and even a bit of C#. I currently work for Red Hat on the WildFly/EAP team, where, among other things, I maintain integrations for some MicroProfile specs, OpenTelemetry, Micrometer, Jakarta Faces, and Bean Validation. (Full resume here. LinkedIn profile)

    I am the president of the Oklahoma City JUG, and an occasional speaker at the JUG and a variety of technical conferences.

    On the personal side, I’m active in my church, and enjoy bass guitar, running, fishing, and a variety of martial arts. I’m also married to a beautiful woman, and have two boys, who, thankfully, look like their mother.

    My Links

    Publications