https://www.erichgrunewald.com/posts/setting-up-gmail-in-doom-emacs-using-mbsync-and-mu4e/ ~ / setting-up-gmail-in-doom-emacs-using-mbsync-and-mu4e posted on 2021-11-06 Setting Up Gmail in Doom Emacs using mbsync and mu4e I can think of far better ways to spend a quiet Sunday afternoon than trying to get Doom Emacs to serve as an email client, but I couldn't at the time. So here I am scanning my inbox in the world's mightiest text editor. I am now able to access my email without an internet connection, although, true, I am never without an internet connection. I am now able to organise my email in neat folders, although, true, I keep everything in the same folder. I am now able to view email from all my accounts in one place, although, true, I really only use one account. Wait, why did I do this again? I must have been under the influence of Drew DeVault. It felt necessary to exorcise this demon by way of a blog post. And who knows? It might even be of use to somebody. In fact, I think I was a bit flippant just now. There are other advantages of using Emacs for email. One is a general advantage of Emacs, namely its enabling tight integration of different tools, in this case for example by linking directly to email from org-mode files. It also gives you a performant keyboard-first interface for reading and writing email, which is nice for those of us who prefer speed over latency and keyboards over mice. The set-up has three main components. First there is a tool for downloading emails, for we shall mirror our inboxes, which are stored in the cloud somewhere, locally. For this we use mbsync. Second, we need to index those locally stored emails so that we can quickly search through them. For this we use mu. Third, we need a way of viewing the emails and maybe even writing and sending new ones. For this we use mu4e, which comes bundled with mu. Two small warnings. First, you are going to need to configure your Gmail account to allow "less secure app access". This allows third parties to access your email even if they are not on Google's list of approved consumers, so long as they have the account's password. Second, depending on the size of your inbox, your emails may take up quite a bit of disk space - around 15 GB for me. Most of this, by the way, is outlined in the relevant Doom docs, though I found it a little hard to follow. Certainly if there are any discrepancies between those docs and my instructions here, I am in the wrong and they are not. I. Configure Gmail # 1. Go to this Google support page and enable "Less secure app access". 2. Go to your Gmail account and open Settings and make sure "Forwarding and POP/IMAP" has these options configured: + For "When I mark a message in IMAP as deleted", choose "Auto-Expunge off - Wait for the client to update the server." + For "When a message is marked as deleted and expunged from the last visible IMAP folder", choose "Move the message to the Bin." II. Install mbsync and mu/mu4e # (I provide installation instructions with Homebrew as I am on Mac, but it should be similar for other Unix-likes.) 1. Install mbsync using brew install isync^[1]. 2. Install mu using brew install mu. 3. Go to your init.el configuration file (you can use M-x doom/ open-private-config which is bound to C-c f P for me). There, you'll want to uncomment (mu4e +gmail) (obviously removing the +gmail part if you are not using Gmail). Now open up your shell and run doom sync, then restart Emacs. III. Configure mbsync # 1. Set up your mbsync configuration file in ~/.mbsyncrc. This one is based on Ben Maughan's file: # imap account information IMAPAccount gmail Host imap.gmail.com User example@gmail.com Pass PutYourPasswordHere AuthMechs LOGIN SSLType IMAPS CertificateFile /usr/local/etc/openssl/cert.pem # remote storage (use the imap account specified above) IMAPStore gmail-remote Account gmail # local storage MaildirStore gmail-local Path ~/.mail/ Inbox ~/.mail/Inbox Subfolders Verbatim # channel to remote storage Channel gmail Far :gmail-remote: Near :gmail-local: Patterns * ![Gmail]* "[Gmail]/Sent Mail" "[Gmail]/Bin" Create Both SyncState * Note: if you haven't installed OpenSSL via homebrew, you may have your cert.pem file stored elsewhere. You may be able to find out where with something like fd "^cert" --extension pem /usr or fd "^ cert" --extension pem /opt (using fd, which you can install with brew install fd). (Optionally) Store Your Password in an Encrypted File # If it feels icky to put down your password in plaintext in .mbsyncrc, you can instead store it in an OpenPGP-encrypted file. 1. Install gpg using brew install gnupg. (Note that Homebrew actually links gpg to gpg2, which is the command you would be using in Linux.) 2. If you haven't already, create a GPG key by typing gpg --gen-key into your terminal and following the steps you're presented with. 3. Generate a nice keyphrase using your password manager. (You are using a password manager, right? If not, I recommend having a look at Bitwarden.) Store the keyphrase in your password manager. 4. Put your email account password in a text file and encrypt that file using the email you used for your GPG key: $ echo "my-password" > ~/.mbsync-pw-mailbox $ gpg --encrypt --recipient "example@gmail.com" ~/.mbsync-pw-mailbox 5. This will generate an encrypted version of that file called ~/ mbsync-pw-mailbox.gpg. If you are curious, as I was, you can have a look at its contents: $ hexdump ~/.mbsync-pw-mailbox.gpg 0000000 84 5e 03 48 75 ee 04 c0 fe 9a e7 12 01 07 40 47 0000010 77 27 84 6f e7 6a bc a4 d5 c1 40 36 b7 5a e7 d3 0000020 c0 25 4c 70 e6 6b 28 b5 f9 6f 90 92 14 56 41 30 0000030 46 5c 2e 9c ad 2f 18 15 83 78 ff 25 b0 a3 39 ff 0000040 d4 77 ef 6c 21 fa fb 9b 87 af 0c 17 e6 e5 ad 6e 0000050 aa e6 3f 5c c3 c1 30 d9 17 44 d5 ae 5d c0 42 f0 0000060 d4 55 01 09 02 15 6d f6 0e 58 f8 6c d3 95 f8 d8 0000070 3b 9f 75 34 35 23 b6 a1 27 7b f5 34 d3 7a 57 61 0000080 0a 16 0c 86 f0 49 c4 6d 07 4c 03 31 af f3 cf 6b 0000090 bf e7 9f fe 5a d5 b2 47 4b 1d 96 86 7a 6a f5 44 00000a0 24 44 1b f4 54 54 8e de 08 e8 04 92 2c 55 2b 16 00000b0 f3 1d e0 1a b3 3a 16 00000b7 6. Delete the file storing your password in plain text: rm ~/ mbsync-pw-mailbox. You now have your email password stored in a safely encrypted file, and can pull it out at any time using your GPG key: gpg --decrypt ~/.mbsync-pw-mailbox.gpg 7. In ~/.mbsyncrc, remove Pass and replace it with PassCmd "gpg --quiet --for-your-eyes-only --no-tty --decrypt \~/.mbsync-pw-mailbox.gpg". (Optionally) Store Your Password in an Obfuscated File # If it feels icky to put down your password in plaintext in .mbsyncrc, you can instead store it with Base64 encoding. Note that this does not really provide more security than storing your password in plaintext. 1. Store the encoded password to a file: echo "my-password" | base64 > ~/.mbsync-pw-mailbox. 2. In ~/.mbsyncrc, remove Pass and replace it with PassCmd "base64 -d ~/.mbsync-pw-mailbox". IV. Sync Your Local Mailbox with Your Remote Mailbox # 1. Create a directory for your local mailbox: mkdir ~/.mail. Then run mbsync -V gmail (and supply your GPG key if you went that route). This will sync your local mailbox with your remote mailbox, which in practice means you will download all of your emails. Note that this can be several gigabytes of data. 2. Run mu init --maildir ~/.mail --my-address example@gmail.com and mu index. This indexes your local mailbox. V. Configure Emacs and Send an Email # 1. Open up your config.el (C-c f P) and add something like this: (set-email-account! "gmail" '((mu4e-sent-folder . "/[Gmail]/Sent Mail") (mu4e-trash-folder . "/[Gmail]/Bin") (smtpmail-smtp-user . "erichgrunewald@gmail.com")) t) (setq mu4e-get-mail-command "mbsync gmail" ;; get emails and index every 5 minutes mu4e-update-interval 300 ;; send emails with format=flowed mu4e-compose-format-flowed t ;; don't need to run cleanup after indexing for gmail mu4e-index-cleanup nil mu4e-index-lazy-check t ;; more sensible date format mu4e-headers-date-format "%d.%m.%y") 2. Restart Emacs with M-x doom/restart (C-c q R). 3. Open up mu4e using M-x =mu4e (C-c M M) and enjoy. Consult the manual for learning the ropes. 4. When sending your first email, you will be prompted for an SMTP host and port. Enter host smtp.gmail.com and port 587. (Here I got an error related to the macOS Keychain. What solved it for me was adding (after! auth-source (setq auth-sources (nreverse auth-sources))) to my config.el as per here.) --------------------------------------------------------------------- 1. The project is called isync although the executable is called mbsync, apparently as part of a migration from the former to the latter. -[?] - Return to home page | Return to top Painting of wooded area by Auguste Louis Lepere. Apropos This is my writing-place. There is no About page. There are just a bunch of articles. If you don't know where to start, try one of the notable posts listed further down. You can subscribe via RSS or join the email newsletter here: [ ] [Subscribe] You can get in touch by writing me at contact AT erichgrunewald DOT com. Notable posts * Can a Vegan Diet Be Healthy? A Literature Review about health effects of plant-based diets * Animal Testing Is Exploitative and Largely Ineffective about animal ethics in research * The Devastating Power and Heartbreaking Pain of Truly Changing Minds about scout mindset among Latter-day Saints * Does It Smell like Pollocks in Here? about bullshit in contemporary art * The American Style of Quotation Mark Punctuation Makes No Sense about the superiority of the British style Programming * Utilitarianism Expressed in Julia about moral systems modelled in code * Four Ways of Not Writing Software Bugs about avoding programming errors * Using Scheme to Find the Median of Two Sorted Integer Lists about a solution to a coding problem * Code Purity and Principles about cleanliness and best practices in programming Philosophy * Interview with Christine M. Korsgaard about animal ethics, Kantianism and utilitarianism * Two Inadequate Arguments against Moral Vegetarianism about considerations on price elasticity and supply chain buffers * Auderico about our duties to inanimate objects, in dialogue form * Paying for a Service, II and III about a Kantian consumer ethics Art * Strictness of Logic versus Openness of Logic about Jean Sibelius, Gustav Mahler and the symphony * How Can One Tell What Is Beautiful? about objectivity and subjectivity in art * Interview with Corentin Boissier about Romanticism, Modernism and composition in music * Mysteries of the Unknown and the Unknowable about conundrums, mysticism and H. P. Lovecraft * Networks of Meaning about meaning in life, in art and in the works of Gerald Murnane Effective Altruism * Why Does the Western Left Worry More about Local Poverty than Global Poverty? about cross-border wealth redistribution * Interview with Lucia Coulter about her work with the Lead Exposure Elimination Project History/society * Problems with "Eating Animals" about veganism and systemic change * Interview with Olle Haggstrom about reason, COVID-19 and academic freedom in Sweden * Two Accounts of the Armenian Genocide about eyewitness reports of the Medz Yeghern This site was created by myself and is licensed under CC BY-SA 4.0. It tracks page views using Plausible, so without collecting any personal data, without cookies and fully anonymously, purely for my own curiosity and in order to improve the site.