1---
2title: "A perfect email setup (for me)"
3author: ["Amolith"]
4lastmod: 2023-01-27T13:00:36-05:00
5tags: ["Email", "Workflow"]
6categories: ["Technology"]
7draft: true
8---
9
10I've never been satisfied with any of the email clients most people use. I've
11tried [Thunderbird,](https://www.thunderbird.net/en-GB/)
12[Evolution,](https://wiki.gnome.org/Apps/Evolution)
13[Mailspring,](https://getmailspring.com/)
14[Mail.app,](https://support.apple.com/mail) [Roundcube,](https://roundcube.net/)
15[SOGo,](https://sogo.nu/) [Geary,](https://wiki.gnome.org/Apps/Geary) and _many_
16more. _None_ of them handle multiple accounts particularly well because all of
17the emails associated with that account are bound within it. Sure, you can make
18a new folder somewhere called `TODO` and move all of your actionable emails to
19that folder but, when you go to move actionable emails from _another_ account
20into that folder, you'll likely find that the client simply doesn't let you. If
21it does, when you reply, it will likely be sent from the wrong account. This is
22a limitation of the IMAP protocol; everything is _managed_ locally but changes
23are pushed to the remote server and mixing things the way I want leads to broken
24setups.
25
26Before I go any further, these are a few characteristics of my ideal email tool.
27
28- Support for multiple accounts (obviously)
29- _Native desktop application_ (**not**
30 [Electron](https://github.com/electron/electron))
31- Has stellar keyboard shortcuts
32- Doesn't require internet connectivity (other than downloading and sending of
33 course)
34- Organisation can be done with tags
35
36## Why tags? {#why-tags}
37
38Because they're better. Hierarchies are useful for prose and code but not for
39files, emails, notes, or anything where an item may fit within multiple
40categories. Imagine you get an email from your Computer Science professor that
41includes test dates, homework, and information about another assignment. In that
42same email, he asks every student to reply with something they learned from the
43previous class as a form of attendance. In a hierarchy, the best place for this
44might just be a `TODO` folder _even though_ it would also fit under `School`,
45`CS`, `Dates`, `To read`, and `Homework`. Maybe you have a few minutes and want
46to clear out some emails that don't require any interaction. In a tag-based
47workflow, this would be a good time to open `To read`, get that email out of the
48way, and remove the `To read` tag. It would still show up under the other tags
49so you can find it later and take the time to fully answer the professor's
50question, add those dates to your calendar, and add the homework assignments to
51your `TODO` list. Hierarchies can be quite cumbersome to work with, especially
52when one folder ends up getting all the data. Tags ensure that you only see what
53you want when you want it. Tags are more efficient and they will remain my
54organisation system of choice.
55
56## The tools {#the-tools}
57
58In short, the tools we will be using are...
59
60- [`mbsync`](https://isync.sourceforge.io/mbsync.html) to download our emails
61- [`notmuch`,](https://notmuchmail.org/) the primary way emails will be
62 organised
63- [`afew`](https://afew.readthedocs.io/en/latest/) to apply initial `notmuch`
64 tags based on subject, sender, recipient, etc.
65- [NeoMutt](https://neomutt.org/) to interact with those emails, reply,
66 compose, add/remove tags, etc.
67- [`msmtp`](https://marlam.de/msmtp/) for relaying our replies and
68 compositions to our mail provider
69
70Yes, it's a lot. Yes, it's time-consuming to set up. Yes, it's worth it (in my
71opinion).
72
73## `mbsync` {#mbsync}
74
75As I said above, IMAP is limiting; we need to use some other method of
76downloading our emails. There's an awesome piece of software called
77[mbsync](https://isync.sourceforge.io/mbsync.html) which is built for exactly
78this purpose. Its configuration can be rather daunting if you have as many
79accounts as I do (19) but it's not _terrible_.
80
81The following sections are named **Near**, **Far**, and **Sync**. Near and Far
82are terms mbsync uses to profile _how_ your emails are stored, _where_ they're
83stored, and how to interact with them. In this guide, Far will our mail
84provider's IMAP server and Near will be our local Maildir.
85
86### Far {#far}
87
88```text
89IMAPAccount amo_ema
90Host imap.nixnet.email
91CertificateFile /etc/ssl/certs/ca-certificates.crt
92SSLType STARTTLS
93User amolith@nixnet.email
94PassCmd "secret-tool lookup Title amolith@nixnet.email"
95
96IMAPStore amo_ema-remote
97Account amo_ema
98```
99
100### Near {#near}
101
102```text
103MaildirStore amo_ema-local
104SubFolders Verbatim
105Path ~/new-mail/amo_ema/
106Inbox ~/new-mail/amo_ema/INBOX/
107```
108
109In the first block, `localrepository` and `remoterepository` tell OfflineIMAP
110where to look for your emails. `use_exa-local` is an arbitrary naming scheme I
111use to differentiate between the various local and remote accounts. It can
112easily be swapped with something else.
113
114### Sync {#sync}
115
116```text
117Channel amo_ema
118Far :amo_ema-remote:
119Near :amo_ema-local:
120SyncState *
121Patterns *
122Create Both
123```
124
125The repository sections describe how the emails are stored or retrieved. In the
126`local` block, you'll notice that the type is `Maildir`. In this format, each
127email is given a unique filename and stored in a hierarchy of folders within
128your account. This is often how your emails are stored on your provider's mail
129server.
130
131`pythonfile` is used here to authenticate with the remote server. This can be
132complicated and depends _entirely_ on how you manage your passwords. I use
133[KeePassXC](https://keepassxc.org/) and love it. When I set OfflineIMAP up,
134however, it didn't have `libsecret` compatibility. This would have made setup
135significantly easier but, as it already just works™, I don't really see a reason
136to change it.
137
138This new feature allows `libresecret`-based applications to query KeePassXC for
139your passwords or store them there on your behalf. CLI/TUI applications that
140need a secure mechanism for background authentication can use `secret-tool
141lookup Title "TITLE_OF_PASSWORD"` as the password command. See [the pull
142request](https://github.com/keepassxreboot/keepassxc/pull/2726) for more
143details. Because this wasn't a feature when I first set it up, I put my
144passwords in plaintext files and encrypted them with the GPG key stored on my
145YubiKey. As long as my key is plugged in, OfflineIMAP can authenticate and
146download all my emails just fine. The process for using a GPG key _not_ stored
147on a hardware token is pretty much the same and I'll talk about that process
148instead.
149
150These are the contents of my `~/.offlineimap.py`.
151
152```python
153 #! /usr/bin/env python2
154 from subprocess import check_output
155 def get_pass(account):
156 return check_output(["gpg", "-dq", f" ~/.mail_pass/{account}.gpg"]).strip("\n")
157```
158
159This runs `gpg -dq ~/.mail_pass/use_exa.gpg` then strips the newline character
160before returning it to OfflineIMAP. `-d` tells GPG that you're passing it a file
161you want decrypted and `-q` tells it not to give any output other than the
162file's contents. For a setup that works with this Python script, put your
163passwords in plaintext files with the account name as the file name (e.g.
164`use_exa`). You'll then encrypt it with `gpg -er <YOUR_KEY_ID> use_exa`. Running
165`gpg -dq use_exa.gpg` should display your password. Repeat for every account and
166store the resulting files in `~/.mail_pass/`.
167
168The other option, `sync_deletes`, is whether or not to delete remote emails that
169have been deleted locally. I enabled that because I want to have easy control
170over how much remote storage is used.
171
172Here's the next block again so you don't have to scroll up:
173
174```text
175[Repository use_exa-remote]
176type = IMAP
177remotehost = imap.example.com
178starttls = yes
179ssl = no
180remoteport = 143
181remoteuser = user@example.com
182remotepasseval = get_pass("use_exa")
183auth_mechanisms = GSSAPI, XOAUTH2, CRAM-MD5, PLAIN, LOGIN
184maxconnections = 1
185createfolders = True
186sync_deletes = yes
187```
188
189This one's pretty self-explanatory. `type`, `remotehost`, `starttls`, `ssl`, and
190`remoteport` should all be somewhere in your provider's documentation.
191`remoteuser` is your email address and `remotepasseval` is the function that
192will return your password and allow OfflineIMAP to authenticate. You'll want
193enter the name of your password file without the `.gpg` extension; the script
194takes care of adding that. Leave `auth_mechanisms` alone and the same for
195`maxconnections` unless you know your provider won't rate limit you or something
196for opening multiple connections. `sync_deletes` is the same as in the previous
197block.
198
199Copy those three blocks for as many accounts as you want emails downloaded from.
200I have 510 lines just for `Account` and `Repository` blocks due to the number of
201address I'm keeping track of.
202
203## `notmuch` {#notmuch}
204
205[`notmuch`](https://notmuchmail.org/) is _a fast, global-search, and tag-based
206email system_. This what does all of our organisation as well as what provides
207the "virtual" mailboxes NeoMutt will display later on. Configuration is
208incredibly simple. This file goes in `~/.notmuch-config`.
209
210```text
211 [database]
212 path=/home/user/mail/
213
214 [user]
215 name=Amolith
216 primary_email=user@example.com
217
218 [new]
219 tags=unread;new;
220 ignore=Trash;
221
222 [search]
223 exclude_tags=deleted;spam;
224
225 [maildir]
226 synchronize_flags=true
227```
228
229First section is the path to where all of your archives are, the `[user]`
230section is where you list all of your accounts, `[new]` adds `tags` to mail
231notmuch hasn't indexed yet and ignores indexing the `Trash` folder, and
232`[search]` ignores mail tagged with `deleted` or `spam`. The final section tells
233`notmuch` to add maildir flags which correspond with `notmuch` tags. These flags
234will be synced to the remote server the next time OfflineIMAP runs and things
235will be somewhat organised in your webmail interface.
236
237After creating the configuration file, run `notmuch new` and wait for all of
238your mail to be indexed. This could take a short amount of time or it could take
239minutes up to an hour, depending on how many emails you have. After it's
240finished, you'll be able to run queries and see matching emails:
241
242```text
243 $ notmuch search from:user@example.com
244 thread:0000000000002e9d December 28 [1/1] Example User; Random subject that means nothing
245```
246
247This is not terribly useful in and of itself because you can't read it or reply
248to it or anything. That's where the Mail User Agent (MUA) comes in.
249
250## `afew` {#afew}
251
252[`afew`](https://afew.readthedocs.io/en/latest/) is _an initial tagging script
253for notmuch_. After calling `notmuch new`, `afew` will add tags based on headers
254such as `From:`, `To:`, `Subject:`, etc. as well as handle killed threads and
255spam. The official [quickstart
256guide](https://afew.readthedocs.io/en/latest/quickstart.html) is probably the
257best resource on getting started but I'll include a few tips here as well.
258
259## NeoMutt {#neomutt}
260
261## `msmtp` {#msmtp}
262
263`msmtp` is what's known as a _Mail Transfer Agent_ (MTA). You throw it an email
264and it will relay that to your mail provider's SMTP server so it can have the
265proper headers attached for authentication, it can be sent from the proper
266domain, etc. All the necessary security measures can be applied that prevent
267your email from going directly to spam or from being rejected outright.
268
269`msmtp`'s configuration is also fairly simple if a bit long, just like
270OfflineIMAP's.
271
272```text
273 # Set default values for all following accounts.
274 defaults
275
276 # Use the mail submission port 587 instead of the SMTP port 25.
277 port 587
278
279 # Always use TLS.
280 tls on
281```
282
283This section just sets the defaults. It uses port 587 (STARTTLS) for all SMTP
284servers unless otherwise specified and enables TLS.
285
286```text
287 account user@example.com
288 host smtp.example.com
289 from user@example.com
290 auth on
291 user user@example.com
292 passwordeval secret-tool lookup Title "user@example.com"
293```
294
295This section is where things get tedious. When passing an email to `msmtp`, it
296looks at the `From:` header and searches for a block with a matching `from`
297line. If it finds one, it will use those configuration options to relay the
298email. `host` is simply the SMTP server of your mail provider, sometimes this is
299`mail.example.com`, `smtp.example.com`, etc. I've already explained `from`,
300`auth` simply says that a username and password will have to be provided, `user`
301is that username, and `passwordeval` is a method to obtain the password.
302
303When I got to configuring `msmtp`, [KeePassXC](https://keepassxc.org/) had just
304released their `libsecret` integration and I wanted to try it. `secret-tool` is
305a command line tool used to store and retrieve passwords from whatever keyring
306you're using. I think KDE has `kwallet` and GNOME has `gnome-keyring` if you
307already have those set up and want to use them; the process should be quite
308similar regardless.
309
310As mentioned above `secret-tool` stores and retrieves passwords. For retrieval,
311it expects the command to look like this.
312
313```text
314secret-tool lookup {attribute} {value} ...
315```
316
317I don't know what `kwallet` and `gnome-keyring`'s attributes are but this can be
318used with KeePassXC by specifying the `Title` attribute. If the password to your
319email account is stored in KeePassXC with the address as the entry title, you
320can retrieve it by simply running...
321
322```text
323secret-tool lookup Title "user@example.com"
324```
325
326If you have a different naming system, you'll have to experiment and try
327different things; I don't know what KeePassXC's other attributes are so I can't
328give other examples.
329
330```text
331passwordeval gpg -dq ~/.mail_pass/use_exa.gpg
332```
333
334Now that the whole block is assembled, copy/paste/edit for as many accounts as
335you want to send email from.
336
337## Summary {#summary}
338
339## <span class="org-todo todo TODO">TODO</span> Pong fluffy when finished {#pong-fluffy-when-finished}