monotux.tech

Notes from setting up mu4e again

emacs, mu4e

Below are some notes from me setting up mu4e again. I used to run it on my laptop but that consumed too much space on my tiny drive, so I’m currently setting it up on my home server.

Table of Contents

e-mail fetching & sending #

I’m using mbsync to fetch my e-mail from my different providers, and msmtp to send e-mails. I use pass for managing secrets.

secrets management #

I was initially planning to use age with ssh keys, and use ssh-agent forwarding for the key required to decode the age secret – but decided I wanted this working at all1 (and Soon™) so I went with pass instead.

Below is just the commands I ran, not a tutorial.

gpg --full-generate-key
gpg --list-secret-keys --keyid-format LONG
pass init "<nameofgpgkey>"
pass insert email/gmail/foo@gmail.com
pass insert email/provider/bar@example.com
pass insert email/provider/baz@example.net

I’ve used the MacOS keychain for storing and fetching2 these passwords before, but this is a headless Ubuntu machine (so no gnome-keyring either).

mbsync #

There are many great tutorials for mbsync, below is just the outline of one of my accounts (the rest is copy-pasta):

IMAPAccount examplecom
Host imap.example.com
User bar@example.com
PassCmd "pass email/provider/bar@example.com"
Port 993
SSLType IMAPS
AuthMechs Login

IMAPStore examplecom-remote
Account examplecom

MaildirStore examplecom-local
SubFolders Verbatim
Path ~/mail/example.com/
Inbox ~/mail/example.com/INBOX

Channel examplecom
Far :examplecom-remote:
Near :examplecom-local:
Patterns *
Create Both
Sync All
Expunge Both
SyncState *

msmtp #

Below outlines two accounts, setting examplecom as the default. We are using pass to decrypt the password necessary for each account.

defaults

account examplecom
auth on
host smtp.example.com
port 465
protocol smtp
from bar@example.com
user bar@example.com
passwordeval pass email/provider/bar@example.com
tls on
tls_starttls off

account examplenet
auth on
host smtp.example.net
port 465
protocol smtp
from baz@example.net
user baz@example.net
passwordeval pass email/provider/baz@example.net
tls on
tls_starttls off

account default : examplecom

mu #

I use my domains in a catch-all setup, and it’s trivial to make mu know of this (relevant documentation) in it’s indexing:

mu init -m ~/mail --my-address=foo@gmail.com '--my-address=/.*@example\.com/' \
'--my-address=/.*@example\.net/'

Then, of course, index it:

mu index

My first index run took quite some time, approx. 2 hours!

emacs #

Setting up mu4e is documented in great detail in multiple places, and I won’t bother rewriting this myself here. One guide I liked is Caches to Caches guide to mu4e, from where I stole the dynamic refiling idea from. The official documentation on contexts is pretty relevant as well.

One of many things I appreciate with mu4e is that it’s configured in elisp, and the flexibility this enables.

dynamic refiling #

I mainly use refiling in mu4e to archive e-mails into yearly folders, plus refiling frequent e-mails I should have fixed in mailsieve instead. :-)

;; Refile based on year (default) or if matching some other criteria
(defun monotux/refile-examplecom (msg)
  (cond
   ((mu4e-message-contact-field-matches msg :from "noreply@bandcamp.com")
    "/examplecom/bandcamp")
   (t (concat "/examplecom/Archive/" (format-time-string "%Y" (plist-get msg :date)) "/"))))

;; Obviously not a complete mu4e-contexts definition
(setq mu4e-contexts
        `(,(make-mu4e-context
            :name "examplecom"
            :match-func
            (lambda (msg)
              (when msg
                (or (mu4e-message-contact-field-matches msg :to "bar@example.com")
                    (string-match-p "^/examplecom" (mu4e-message-field msg :maildir)))))
            :vars '((user-mail-address . "bar@example.com")
                    (user-full-name . "monotux")
                    (mu4e-drafts-folder . "/examplecom/Drafts")
                    ;; refile will call the function
                    (mu4e-refile-folder . monotux/refile-examplecom)))))

  1. I typically use mosh to connect to remote machines, and ssh-agent forwarding isn’t supported (see this closed GitHub issue), and I haven’t read up on using guardian-agent yet, due to reasons ↩︎

  2. Fetching the password on MacOS could be run like this: security find-generic-password -s mu4e-examplecom -a bar@example.com -w ↩︎