Generate complex gmail filters via a neat little ruby DSL
Generate complex gmail filters via a neat little ruby DSL
This library helps you generate XML that you can import into gmail's filter settings. It makes it more pleasant to write simple (and even complex) filter chains.
As a user of the internet, you probably use gmail, and you probably get a lot of Email - I do. Just like me, you're also likely to have a lot of filters that were once supposed to keep your inbox clean. But every time you click "Filter messages like this", you remember the enormous list of filters you have and how it is only ever going to make things worse in the long run.
As a programmer, I write code. As a metaprogrammer, I write code that writes code. If only gmail filters could be written by a program. Oh wait, they can. There's an import & export function for gmail filters. These filters are exported as XML, and the import in turn takes XML files. What this library does is generate XML that you can import.
Here are some very simple examples of how gmail-britta can make your life easier:
Imagine you're on a discussion mailing list that you skim from time to time - so you want to label email to that list, and archive email from it so it doesn't clog up your inbox. Now, from time to time someone will Cc: you an important message, and you don't want to miss these - what to do?
Naively, you define a filter like this:
list:[email protected] !to:[email protected]
-> Archive, Label "some-side-project"But this also means email addressed to you but also sent to that list will be missing the "some-side-project" label. This means you need two filters!
list:[email protected] !to:[email protected]
-> Archive
list:[email protected]
-> Label "some-side-project"Now this can get pretty hairy pretty quickly; and if you ever have to change the filter (e.g., the list changes email addresses), you have to change two filters! Ugh.
With gmail-britta, it's just this:
GmailBritta.filterset do
filter {
has %w{list:[email protected]}
label "some-side-project"
}.archive_unless_directed
endThat's it - this little piece of ruby code will generate these two filters; and if the list address changes, you just re-import these filters. Easy.
If you have issued a search for to:me on gmail in the last few
months (and you get Email from iCloud nee MobileMe users), you'll
notice that to:me also matches the "me" in [email protected]. This is
very frustrating mostly because any filter as above that matches on
to:me will now also not archive email sent from a me.com
account. With gmail-britta, you can define a set of emails that are
yours, and archive_unless_directed will generate a filter that
matches on those:
GmailBritta.filterset(:me => ['[email protected]', '[email protected]']) do
filter {
has %w{list:[email protected]}
}.archive_unless_directed
endThere are instances where you can't only match on the mailing list - sometimes interesting stuff will be sent to one list (that you want to read), and lots of unnecessary silliness will be sent there too. So, to put email with a certain subject into one label, and to put all the rest into another, you have to make multiple filters. But gmail lacks if/else in filters - you have to duplicate and correctly negate each filter's condition in the next one. Luckily, you have gmail-britta to help you out there:
GmailBritta.filterset do
filter {
has %w{list:[email protected] subject:Important}
label 'work/robots/important'
# Do not archive
}.otherwise {
has %w{list:[email protected] subject:Chunder}
label 'work/robots/irrelevant'
}.archive_unless_directed(:mark_read => true).otherwise {
has %w{list:[email protected] subject:Semirelevant}
label 'work/robots/meh'
}.archive_unless_directed
endA lot of things going on here! First, I hope you notice that this
looks similar to an if/else-if statement. Second, you may notice the
liberal application of .archive_unless_directed, with an optional
:mark_read parameter. Third, do check out the XML generated by this,
it's pretty horriffic - but the filters do exactly what the code says:
Best to use gmail-britta from a ruby script; but install the gem first:
gem install gmail-brittaOr include it in your Gemfile:
gem 'gmail-britta'This is a simple script that generates filters for you:
#!/bin/env ruby
require 'rubygems'
require 'gmail-britta'
fs = GmailBritta.filterset(:me => ['[email protected]']) do
filter {
has %w{from:[email protected]}
label 'from-the-author-of-gmail-britta'
never_spam
}
end
puts fs.generateRunning this script will write to stdout the filter XML that you need. Redirect that to a file and upload it on the bottom of your gmail filter settings, and you'll label email from me and archive it unless I email you specifically. Not that useful, but with your own filters and the recipes above, you should be able to make it work (-:
Here are some things to note when performing filter-fu with gmail:
archive_unless_directed heavily, you almost certainly want to check the "Don't override filters" box in Gmail's Inbox preferences.A lot of this is a bit hacky (particularly the filter condition merge logic), as it started as a oneoff ruby script - very sorry for any amateurish code you may encounter. There are few tests, but so far, it does work for me. Let me know if this made your life harder or easier! (-:
Copyright (c) 2012 Andreas Fuchs. See LICENSE.txt for further details.
No open issues yet, or sync has not completed.