Gmailctl – Declarative Configuration for Gmail Filters
github.com
github.com
I don't ask that to be confrontational; I've successfully managed several email inboxes on several different providers for years with plain old IMAP rules, so I'd like to know if there's anything I'm missing.
- You end up with multiple sources of truth for what's happening to your email. And/or you won't be able to easily edit your filters from multiple machines.
- Either the source code or the generated code ends up being hard to read.
- There's imperative (and sometimes counterintuitive) behavior in Gmail regarding labels, and that can interfere with declarative reasoning.
- Filters have a size limit! So you might need to take that into account if you have complicated filters.
The imperative behavior and filter size limits are still annoying, granted. You can deal with it by staging through multiple labels, but it's not great.
If you're curious, the tool I came up with had a DSL like this:
$excom = from:example.com
$exorg = from:(example.org OR example.net)
if ($excom AND $exorg) AND -(to:me OR in:spam)
archive
if cc:person
label "Person"
end
end
and it'd auto-translate to this: <?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:apps='http://schemas.google.com/apps/2006'>
<entry>
<category term='filter'></category>
<apps:property name='hasTheWord' value='(from:example.com from:{example.org example.net}) -{to:me in:spam}'/>
<apps:property name='shouldArchive' value='true'/>
</entry>
<entry>
<category term='filter'></category>
<apps:property name='hasTheWord' value='(from:example.com from:{example.org example.net}) -{to:me in:spam} cc:person'/>
<apps:property name='label' value='Person'/>
</entry>
</feed>
which it would translate back to this: if (from:example.com from:{example.org example.net}) -{to:me in:spam}
archive
end
if (from:example.com from:{example.org example.net}) -{to:me in:spam} cc:person
label "Person"
end
It didn't treat the filter as a blob (it actually parsed it and removed quotes etc. if appropriate) but it also didn't really change the underlying language either.But it had variable and did let you nest conditions which made it easier to write some things. (Or so I hoped. In the end I didn't feel it was worth it...)
Seems to me, now you've added several more sources of complexity:
- You have to get the JSONnet syntax right and learn about th various functionalities and expressions.
- You have to ensure Jsonnet is correctly translated into the GMail filter chain.
- You still have to ensure the GMail filter chain works correctly - this is one of the original problems this project set out to solve, but I don't understand what additional tools the project gives you to archieve this.
Getting things right is not easy, especially in complex languages like jsonnet. In my own experience though, every time you limit the expressivity of config languages you end up inventing even more complex workarounds in the end (e.g. external templating and things like that).
It's super helpful to get around the way Gmail doesn't really let you order rules.
This helps you generate mutually exclusive rules, so the ordering doesn't matter.
https://github.com/mbrt/gmailctl/blob/master/README.md#chain...
I migrated from self-hosted mail where I had the power of procmail, to gsuite, where I had less flexibility. Making simple filters via the google UI is easy, but it gets complicated when you want to look at both the subject and the sender - to file "Facebook comment replies", "Facebook messages", and "Facebook event invitations" under different labels for example.
It's a pain to authenticate, but once that's done I like my solution. Downside is you need to run it under cron:
https://github.com/skx/labeller/
The appeal of this gmailctl is that it keeps everything native, and doesn't require a server to run a cronjob. Nice work.
It should work without issues, I need to document it though. Let me know if you have some troubles using it.