Gmail in Doom Emacs using mbsync ,mu4e and App Password(not OAuth2)
A personal note documenting how I set up multiple Gmail accounts in Doom Emacs using App Passwords (not OAuth2), mbsync, and mu4e.
Components covered:
- Doom Emacs
- Gmail App Password (no OAuth2)
- mbsync (isync) for local IMAP sync
- mu4e
Read This.
-
Remember:
press
c: lowercase c :cpress
C: uppercase C :shift+cC-c:control+cM-x:alt+x
mv -r ~/.emacs.d ~/.emacs.d-backup
mv -r ~/.emacs ~/.emacs-backup
mv -r ~/.doom.d ~/.doom.d-backup
mv -r ~/.emacs ~/.emacs-backup
mv -r ~/.config/.emacs.d ~/.config/.emacs.d-backup
mv -r ~/.config/.emacs ~/.config/.emacs-backup
mv -r ~/.config/.doom.d ~/.config/.doom.d-backup
mv -r ~/.config/.emacs ~/.config/.emacs-backupgit clone --depth 1 https://github.com/doomemacs/doomemacs ~/.config/emacs
~/.config/emacs/bin/doom install- Also add
$HOME/.config/emacs/bin/to your paths: - I use
fishso just:fish_add_path $HOME/.config/emacs/bin - Using
bash: addexport PATH="$HOME/.config/emacs/bin:$PATH"to~/.bashrc
- mu
- isync
- msmtp
- mbsync
Using
yay? Nice, JUST RUN:yay -S mu isync msmtp mbsync
- DONE.
-
What is APP PASSWORD ? -> https://support.google.com/accounts/answer/185833
-
CREATE APP PASSWORD -> https://myaccount.google.com/apppasswords
1.1. Create n app passwords for your n gmail accounts and save them to some files like these:
- IMAGINE:
account 1 gmail:
acc1@gmail.comaccount 1 app passowrd :
abcd efgh ijklaccount 1 gmail:
acc2@gmail.comaccount 2 app passowrd :
aaaa bbbb cccc dddd
-
THEN:
-
for each acc:
- this example is for
acc1 - Go to a secret directory and create
.mbsyncpass-acc1and put its password (abcd efgh ijkl) into it. - run >>
gpg2 -c .mbsyncpass-acc1. it will ask you a new password to encrypt file, !! REMEMBER IT !!⚠️ .
it will create a new encrypted file (
.mbsyncpass-acc1.gpg),-
remove
.mbsyncpass-acc1file -
-- > > > undo? : >> $
gpg2 -d .mybsyncpass-acc1.gpg>.mbsyncpass-acc1
- this example is for
-
THEN:
- Write
nlines for yournaccounts:
machine smtp.gmail.com port 587 login Acc1@gmail.com password "abcd efgh ijkl"
machine smtp.gmail.com port 587 login Acc2@gmail.com password "aaaa bbbb cccc dddd"
-
Save: press (
spacefs) to save> write~/authinfo.gpg> enter > it will ask you a new passowrd to encrypt file, !! REMEMBER IT !!⚠️ . -
DONE.
- Open Doom Emacs
- Press (
spacefp) - Select
init.el - Enter
- Find
;;(mu4e +org +gmail)
- Uncomment it (remove
;;):
(mu4e +org +gmail)
-
Save it and exit
:wqor (spacefs) -
DONE.
- IMAGINE:
You chose
/home/me/here/there/mails/to store your mailscreate it with:
mkdir -p /home/me/here/there/mails/
⚠️ Replace any[USER_A]to your email name like:acc1
careful ;
[[USER_A]]will be[acc1]
-
⚠️ Replace anypath/to/[USER_A]-gmail/with your owns (for each acc) -
⚠️ Replace anypath/to/.mbsyncpass-[USER_A].gpgwith your owns (for each acc)
# mbsyncrc based on
# http://www.ict4g.net/adolfo/notes/2014/12/27/EmacsIMAP.html
# ACCOUNT INFORMATION
IMAPAccount [USER_A]-gmail
# Address to connect to
# ! ! ! ! ! ! ! ! ! ! !
# [USER_A] ==> MyName
# [[USER_A]] ==> [MyName]
# ! ! ! ! ! ! ! ! ! ! !
Host imap.gmail.com
User [USER_A]@gmail.com
PassCmd "gpg2 -q --for-your-eyes-only --no-tty -d path/to/.mbsyncpass-[USER_A].gpg"
AuthMechs PLAIN
TLSType IMAPS
TLSVersions +1.2 +1.3
CertificateFile /etc/ssl/certs/ca-certificates.crt
# THEN WE SPECIFY THE LOCAL AND REMOTE STORAGE
# - THE REMOTE STORAGE IS WHERE WE GET THE MAIL FROM (E.G., THE
# SPECIFICATION OF AN IMAP ACCOUNT)
# - THE LOCAL STORAGE IS WHERE WE STORE THE EMAIL ON OUR COMPUTER
# REMOTE STORAGE (USE THE IMAP ACCOUNT SPECIFIED ABOVE)
IMAPStore [USER_A]-gmail-remote
Account [USER_A]-gmail
# LOCAL STORAGE (CREATE DIRECTORIES with mkdir -p ~/Maildir/[USER_A]-gmail)
MaildirStore [USER_A]-gmail-local
Path path/to/[USER_A]-gmail/
Inbox path/to/[USER_A]-gmail/INBOX
# REQUIRED ONLY IF YOU WANT TO DOWNLOAD ALL SUBFOLDERS; SYNCING SLOWS DOWN
# SubFolders Verbatim
# CONNECTIONS SPECIFY LINKS BETWEEN REMOTE AND LOCAL FOLDERS
#
# CONNECTIONS ARE SPECIFIED USING PATTERNS, WHICH MATCH REMOTE MAIl
# FOLDERS. SOME COMMONLY USED PATTERS INCLUDE:
#
# 1 "*" TO MATCH EVERYTHING
# 2 "!DIR" TO EXCLUDE "DIR"
# 3 "DIR" TO MATCH DIR
Channel [USER_A]-gmail-inbox
Far :[USER_A]-gmail-remote:
Near :[USER_A]-gmail-local:
Patterns INBOX
Create Both
Expunge Both
SyncState *
MaxMessages 600
ExpireUnread yes
Channel [USER_A]-gmail-trash
Far :[USER_A]-gmail-remote:"[Gmail]/Trash"
Near :[USER_A]-gmail-local:"[[USER_A]].Trash"
Create Both
Expunge Both
SyncState *
MaxMessages 600
ExpireUnread yes
Channel [USER_A]-gmail-sent
Far :[USER_A]-gmail-remote:"[Gmail]/Sent Mail"
Near :[USER_A]-gmail-local:"[[USER_A]].Sent Mail"
Create Both
Expunge Both
SyncState *
MaxMessages 600
ExpireUnread yes
#
# Channel [USER_A]-gmail-all
# Far :[USER_A]-gmail-remote:"[Gmail]/All Mail"
# Near :[USER_A]-gmail-local:"[[USER_A]].All Mail"
# Create Both
# Expunge Both
# SyncState *
# MaxMessages 600
# ExpireUnread yes
# Channel [USER_A]-gmail-starred
# Far :[USER_A]-gmail-remote:"[Gmail]/Starred"
# Near :[USER_A]-gmail-local:"[[USER_A]].Starred"
# Create Both
# Expunge Both
# SyncState *
# MaxMessages 600
# ExpireUnread yes
# GROUPS PUT TOGETHER CHANNELS, SO THAT WE CAN INVOKE
# MBSYNC ON A GROUP TO SYNC ALL CHANNELS
#
# FOR INSTANCE: "mbsync gmail" GETS MAIL FROM
# "gmail-inbox", "gmail-sent", and "gmail-trash"
#
Group [USER_A]-gmail
Channel [USER_A]-gmail-inbox
Channel [USER_A]-gmail-sent
Channel [USER_A]-gmail-trash
# Channel [USER_A]-gmail-all
# Channel [USER_A]-gmail-starred
# ================================================================================
#
# ACCOUNT INFORMATION
IMAPAccount [USER_B]-gmail
# Address to connect to
Host imap.gmail.com
User [USER_B]@gmail.com
PassCmd "gpg2 -q --for-your-eyes-only --no-tty -d path/to/.mbsyncpass-[USER_B].gpg"
AuthMechs PLAIN
TLSType IMAPS
TLSVersions +1.2 +1.3
CertificateFile /etc/ssl/certs/ca-certificates.crt
# THEN WE SPECIFY THE LOCAL AND REMOTE STORAGE
# - THE REMOTE STORAGE IS WHERE WE GET THE MAIL FROM (E.G., THE
# SPECIFICATION OF AN IMAP ACCOUNT)
# - THE LOCAL STORAGE IS WHERE WE STORE THE EMAIL ON OUR COMPUTER
# REMOTE STORAGE (USE THE IMAP ACCOUNT SPECIFIED ABOVE)
IMAPStore [USER_B]-gmail-remote
Account [USER_B]-gmail
# LOCAL STORAGE (CREATE DIRECTORIES with mkdir -p ~/Maildir/[USER_B]-gmail)
MaildirStore [USER_B]-gmail-local
Path path/to/[USER_B]-gmail/
Inbox path/to/[USER_B]-gmail/INBOX
# CONNECTIONS SPECIFY LINKS BETWEEN REMOTE AND LOCAL FOLDERS
#
# CONNECTIONS ARE SPECIFIED USING PATTERNS, WHICH MATCH REMOTE MAIl
# FOLDERS. SOME COMMONLY USED PATTERS INCLUDE:
#
# 1 "*" TO MATCH EVERYTHING
# 2 "!DIR" TO EXCLUDE "DIR"
# 3 "DIR" TO MATCH DIR
Channel [USER_B]-gmail-inbox
Far :[USER_B]-gmail-remote:
Near :[USER_B]-gmail-local:
Patterns INBOX
Create Both
Expunge Both
SyncState *
MaxMessages 600
ExpireUnread yes
Channel [USER_B]-gmail-trash
Far :[USER_B]-gmail-remote:"[Gmail]/Trash"
Near :[USER_B]-gmail-local:"[[USER_B]].Trash"
Create Both
Expunge Both
SyncState *
MaxMessages 600
ExpireUnread yes
Channel [USER_B]-gmail-sent
Far :[USER_B]-gmail-remote:"[Gmail]/Sent Mail"
Near :[USER_B]-gmail-local:"[[USER_B]].Sent Mail"
Create Both
Expunge Both
SyncState *
MaxMessages 600
ExpireUnread yes
#
# Channel [USER_B]-gmail-all
# Far :[USER_B]-gmail-remote:"[Gmail]/All Mail"
# Near :[USER_B]-gmail-local:"[[USER_B]].All Mail"
# Create Both
# Expunge Both
# SyncState *
# MaxMessages 600
# ExpireUnread yes
#
# Channel [USER_B]-gmail-starred
# Far :[USER_B]-gmail-remote:"[Gmail]/Starred"
# Near :[USER_B]-gmail-local:"[[USER_B]].Starred"
# Create Both
# Expunge Both
# SyncState *
# MaxMessages 600
# ExpireUnread yes
# GROUPS PUT TOGETHER CHANNELS, SO THAT WE CAN INVOKE
# MBSYNC ON A GROUP TO SYNC ALL CHANNELS
#
# FOR INSTANCE: "mbsync gmail" GETS MAIL FROM
# "gmail-inbox", "gmail-sent", and "gmail-trash"
#
Group [USER_B]-gmail
Channel [USER_B]-gmail-inbox
Channel [USER_B]-gmail-sent
Channel [USER_B]-gmail-trash
#Channel [USER_B]-gmail-all
#Channel [USER_B]-gmail-starred
You can uncomment any section you want. Just remember to uncomment the related channels too.
- DONE.
⚠️ Replace~/path/to/mail/,~/path/to/.mbsyncrcwith your own⚠️ Replaceaccount1,account2with our own (for each acc)
;;; email.el -*- lexical-binding: t; -*-
(use-package! mu4e
:commands mu4e
:config
;; Maildir root (where mbsync puts emails)
(setq mu4e-root-maildir "~/path/to/mail")
;; Use mbsync with your specific config
(setq mu4e-get-mail-command "mbsync -c ~/path/to/.mbsyncrc -a")
;; Automatically pick the first context if multiple (optional)
(setq mu4e-context-policy 'pick-first)
;; Define contexts for two accounts
(setq mu4e-contexts
`(,(make-mu4e-context
:name "Account1"
:match-func (lambda (msg)
(when msg
(string-prefix-p "/account1" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "account1@gmail.com")
(user-full-name . "Account One")
(mu4e-sent-folder . "/account1/[account1].Sent")
(mu4e-drafts-folder . "/account1/[account1].Drafts")
(mu4e-trash-folder . "/account1/[account1].Trash")
(mu4e-refile-folder . "/account1/[account1].All Mail")
(smtpmail-smtp-server . "smtp.gmail.com")
(smtpmail-smtp-service . 587)
(smtpmail-stream-type . starttls)))
,(make-mu4e-context
:name "Account2"
:match-func (lambda (msg)
(when msg
(string-prefix-p "/account2" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "account2@gmail.com")
(user-full-name . "Account Two")
(mu4e-sent-folder . "/account2/[account2].Sent")
(mu4e-drafts-folder . "/account2/[account2].Drafts")
(mu4e-trash-folder . "/account2/[account2].Trash")
(mu4e-refile-folder . "/account2/[account2].All Mail")
(smtpmail-smtp-server . "smtp.gmail.com")
(smtpmail-smtp-service . 587)
(smtpmail-stream-type . starttls))))))
(setq message-send-mail-function 'message-smtpmail-send-it
smtpmail-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 587
smtpmail-stream-type 'starttls
smtpmail-auth-supported '(login plain)
smtpmail-debug-info nil
smtpmail-debug-verbose nil)
;; Keybinding to open mu4e quickly
(map! :leader
:desc "Open Mail (mu4e)"
"o m" #'mu4e)-
Tip:
You can make another file in your doom config dir like
~/.config/doom/here/there/mail.eland then link it toconfig.elwith:(load! "here/there/mail") ;; no need ".el" at the end
- DONE.
- The
-Vis to see (what's going on), you can remove it if u like less texts.
mbsync -c ~/myworld/secret/emacsSecrets/mu4e/.mbsyncrc -a -V - It will ask you your password for every account
- you can use
account1-gmailinstead of-ato get mails jsut for one acc
⚠️ Replace the path with our own mail directory path
mu init --maildir /home/me/there/here/mail
mu index --lazy-check
- DONE.
- DONE
-
It will ask you your passowrd for
~/.authinfo.gpgfile. -
DONE.
- DONE.
oauth2 is pretty simple with oama:
~/.config/oama/config.yaml~/.config/msmtp/config-passwordeval oama access your.account@gmail.com~/.config/isyncrcyou'll need to do
oama authorize google your.account@gmail.comonce to obtain the token, later onoamawould refresh the token automatically