How I do mail
Posted on 2021-07-21 in misc • 4 min read
Email is one of those "necessary evils" in the world. There is pretty much no way around it, though things like Teams tries (and fails because it's a giant POS). Until Teams, Outlook was my most-hated MS creation. I think it is a jumbled mess of crap that complicates email with a bunch of client-side uselessness and is just really inefficient at actually working with emails. Outlook web is slightly-less horrible than the full-blown app, but like all Microsoft web things, it is extremely slow and is just not pleasant to work with.
For many years I have used Thunderbird with the Enigmail plugin for PGP signing and encrypting. I was mostly happy with it and it still remains one of my favorite email clients. Recently they upgraded and embedded PGP functionality into thunderbird directly and Enigmail no longer works. This ended up being a minor thorn in my side because the way they integrated it didn't allow for use of a Yubikey to keep the PGP private key part. There were ways around it, but ultimately I hit a point where I didn't like the way it was working and I also didn't like how the caching of mail was handled and the overall heaviness of a client like Thunderbird for mail.
Enter the Mutt
So I did what any 20+ year veteran of Linux administration would do, and I went old-school by setting up Mutt as my mail client. Neomutt technically, but its really just a newer development branch of the same thing.
I use TaskWarrior for my task management, and I wanted something I could easily integrate with that by sending an email directly to an actionable task (more on that below). Mutt, being a console-based tool, has all kinds of options to integrate workflows into your email so this looked promising.
As I mentioned before, even though no one else I talk to uses (or has any interest in) signing and encrypting emails, I always sign my email so that anyone who was inclined could verify that it was in fact me that said whatever it was in the email. No one cares, but it still seems kind of important to me. PGP/GPG functionality is easily configured in Mutt.
The whole setup
There are many parts to making all this work, and it seems pretty complicated when I lay it all out here, but most things are commonly-used apps that just happen to chain together to make an actually pretty-awesome email experience.
DAVMail is key to working with Office365 which is what I use for my work email. DAVMail connects to Office365's proprietary shit-fest of services and translates that into standard IMAP, SMTP, CalDAV, and CardDAV so any standard client can interact with it.
OfflineIMAP is what pulls mail from Office365 (via DAVMail) to a Maildir format in my home directory which is ultimately what Mutt is reading from
MSMTP is used for sending mail via SMTP. Initially I just had my laptop setup with Postfix and sent mail directly through it, but that gets more complicated when you add accounts and email verification gets spotty when it sees you are relaying through "randominternetprovider.com" for "myemaildomain.com". So MSMTP is configured to send mail through DAVMail via SMTP.
vdirsyncer does for calendars and contacts what OfflineIMAP does for mail. It connects to DAVmail and syncs calendar objects as .ics files which I then interact with using khal for the calendar and khard.
notmuch Looks pretty amazing, though at this point I am using it for a very tiny piece of information. I want to ultimately make use of it for my mailboxes and tagging, however at this point it is basically just indexing all my email content for searching out details later.
Tasks from Email
Many years ago, I used IQTell for my email/task management. It was great, but sadly the project died. I have never found anything that quite worked the way it did for task management. TaskWarrior is incredible, but one of the things missing is email. I wanted a way to take an email request, and directly send it over to taskwarrior. And with that, I am in the process of creating mutt2tw.
Currently it exists as two parts
- mutt2tw.py - a script which takes stdin and pushes it to taskwarrior
- twmessage.py - a script to search for messages by the task number in taskwarrior
mutt2tw.py is setup as a macro (bound to key 't') which will send the message to mutt2tw, which ultimately pushes it to taskwarrior. Then it moves the message to archive. Effectively getting GTD and inbox zero accomplished. I have the message as a task in my trusted system, and don't need it cluttering up my email anymore.
Later when I'm reviewing my tasks and I see that I have this task which is just titled "Add the website", I can take that task ID and run twmessage <tasknumber> to retrieve the email contents from notmuch and display the message so I know what the whole context of the task was.
That's the rough layout of how I do email. I have most of my configuration and utilities on my github pages for all the details. I am really just starting with Mutt, so there is a lot that I have copied the ideas from others and can't expand on why it works. There are also some limitations that I hope to figure out how to overcome but overall I'm pretty happy with this setup