Skip to content

Latest commit

 

History

History
188 lines (150 loc) · 8.48 KB

email.org

File metadata and controls

188 lines (150 loc) · 8.48 KB

my email workflow with notmuch

Tools I used for my workflow

My email workflow mainly consists of the following parts:

  1. Email synchronizer (indexer): mbsync (or isync, they are the same thing)
  2. Email Sender: msmtp
  3. Mail User Agent (MUA): notmuch and emacs
  4. mutt_oauth2.py from neomutt for oauth2 authentication with outlook email.

For how mbsync + notmuch + msmtp above work together, Protesilaos Stavrou provides a great explanation.

I will not delve into the configuration of mbsync and msmtp here, as abundant resources are available across the internet. Instead, I’ll focus on aspects less commonly discussed online: specifically, how to set up notmuch effectively and configure OAuth2 authentication with mbsync.

This guide will address two key areas:

  1. My hacks on notmuch for efficient email management
  2. Configuring OAuth2 authentication for mbsync

Syncing Notmuch Tags with IMAP Folders: Workarounds for Cross-Device Email Management

Notmuch is a tag-centric email client, but its tags don’t usually sync up with IMAP folders. It also can’t move emails between maildir folders (which are basically mailboxes in your email account) out of the box. This setup works fine if you only use Notmuch to read your emails. However, things can get messy if you’re also using other email clients, like on your phone, and want everything to stay in sync across your devices.

This section covers some handy workarounds, mainly focusing on moving emails between maildir folders. These tricks help sync changes with your email mailboxes, making it easier to use Notmuch alongside other email clients on different devices without things getting out of sync.

Configure oauth2 support with outlook

Setup the mutt script for oauth2 authentication

Outlook enforced oauth2 authentication for outlook email. See this news.

I used the script from neomutt for oauth2 authentication, with some modification in the patch below.

diff --git a/mutt_oauth2.py b/bin/mutt_oauth2.py
old mode 100644
new mode 100755
index c973b98..c296dff
--- a/mutt_oauth2.py
+++ b/bin/mutt_oauth2.py
@@ -45,7 +45,7 @@ import readline
 # encryption and decryption pipes you prefer. They should read from standard
 # input and write to standard output. The example values here invoke GPG,
 # although won't work until an appropriate identity appears in the first line.
-ENCRYPTION_PIPE = ['gpg', '--encrypt', '--recipient', 'YOUR_GPG_IDENTITY']
+ENCRYPTION_PIPE = ['gpg', '--encrypt', '--recipient', '<[email protected]>']
 DECRYPTION_PIPE = ['gpg', '--decrypt']

 registrations = {
@@ -66,17 +66,17 @@ registrations = {
         'authorize_endpoint': 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
         'devicecode_endpoint': 'https://login.microsoftonline.com/common/oauth2/v2.0/devicecode',
         'token_endpoint': 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
-        'redirect_uri': 'https://login.microsoftonline.com/common/oauth2/nativeclient',
+        'redirect_uri': 'https://login.live.com/oauth20_desktop.srf', # use the redirect url of outlook instead of office365
         'tenant': 'common',
         'pop_endpoint': 'outlook.office365.com',
-        'smtp_endpoint': 'smtp.office365.com',
+        'smtp_endpoint': 'smtp-mail.outlook.com',  # use the SMTP endpoint of outlook instead of office365
         'sasl_method': 'XOAUTH2',
         'scope': ('offline_access https://outlook.office.com/IMAP.AccessAsUser.All '
                   'https://outlook.office.com/POP.AccessAsUser.All '
                   'https://outlook.office.com/SMTP.Send'),
-        'client_id': '',
-        'client_secret': '',
+        'client_id': 'my app id, see the next section on how to register your own app',
+        'client_secret': ' ',
     },
 }

Set up app registration in Azure

To set up an app to sync emails, follow these steps:

  1. Sign up for an Azure account using your personal Outlook email or preferred email address.
  2. After logging in to your Azure account, switch to the “default directory” as new app registrations are currently restricted to directories only.
  3. Follow the instruction provided by neomutt for your app configuration. During the app configuration process, you’ll find the specified settings under the Manage | Authentication and Manage | API permissions sidebars in your app portal. It’s crucial to enable access for IMAP, SMTP, POP, and other relevant scopes as detailed in the mutt script under the Manage | API permissions sidebar.

Fetch the authentication token with the mutt script

mutt_oauth2.py --verbose --authorize -t your/path/to/the/oauth/file

Upon executing the aforementioned command, a wizard will guide you through the setup process. Follow the on-screen instructions to proceed. I used the ‘devicecode’ authentication flow, although other options should also work. Once the setup is complete, the mutt script will encrypt the OAuth2 token and save it to your/path/to/the/oauth/file.

Please be aware that OAuth2 tokens expire regularly. I recommend familiarize yourself with the concept of refresh tokens and access tokens in the OAuth2 protocol. If you encounter issues with mbsync, consider the possibility of token expiration. In such cases, you may need to execute the command again to obtain a fresh token.

Configure mbsync

Warning: if you are using macOS, the mbsync installed from homebrew does not work with xoauth2, following the instruction at this thread to build the mbsync from source. I took my own hackish approach: I created a Docker container that runs mbsync with xoauth2 support. I then mounted my host machine’s maildir folder to this container, allowing mbsync to access and sync my emails. The Docker container is based on Ubuntu and includes the following installed packages:

isync libsasl2-modules-kdexoauth2 ca-certificates openssl libsasl2-modules python3

In your mbsync config file, configure your outlook email like this:

IMAPAccount myPersonalOutlook
PassCmd "mutt_oauth2.py -t your/path/to/the/outlook/oauth/file"
AuthMechs XOAUTH2
# And your rest configs just works

Configure msmtp

You are lucky that the msmtp installed from homebrew just works, no need to worry about building from source. Changing the following lines should be sufficient.

account outlook
auth xoauth2
passwordeval mutt_oauth2.py -t your/path/to/the/outlook/oauth/file
# And your rest configs just works

From mu4e to notmuch

As someone switching from mu4e to notmuch, I’ve found that the resources I used to set up mu4e are still super helpful for configuring notmuch. It’s great that I can keep using mbsync for syncing my emails and msmtp for sending messages. These tools work just as well with notmuch, making the transition much smoother.

There are two primary reasons for my decision to transition. Firstly, mu4e’s backward compatibility is horrible, with many plugins dependent on mu4e often breaking after major version updates. Secondly, notmuch offers a threaded conversation view, whereas mu4e only provides a threaded tree view. While I had implemented thread-folding in mu4e, it worked but the result was less than ideal. Even the official thread-folding feature introduced in mu4e 1.12 has numerous issues. In contrast, the conversation view in notmuch works great for threads.

Acknowledgement

  1. Protesilaos Stavrou’s notmuch configuration
  2. Doomemacs’s mu4e configuration
  3. Doomemacs’s notmuch configuration
  4. macowner’s blog on mu4e config
  5. Move mail script from notmuch mailing list