Table of Contents
Motivation
As Emacs user I always want to use Emacs interface to edit documents.
When I write e-mails, I also do, so
I tried to introduce notmuch
, emacs
and offlineimap
.
As a result I feel notmuch
on emacs
is very useful in terms of tagging,
searching, and emacs interface.
Some configurations below were not on the web, so I note here. If you follow my way to handle e-mails, this may help you.
Softwares
- emacs
-
tagging, fast searching available e-mail system
Offlineimap (official, community page)
software to synchronize your local mailbox with the mail server via IMAP
Install
Refer to above links. I think you should use the package system of your OS.
Configurations
My goals are
- Automatically synchronize local mailbox with your gmail server
- Automatically assign the basic tags to some mails like Gmail.
I set up some below configurations referring to Emacs, Notmuch and Offlineimap.
Offlineimap
Offlineimap
Configure offlineimap
to fetch emails from your gmail server.
Copy the default config file
$ cp offlineimap.conf.minimal ~/.offlineimaprc
If you set
$XDG_CONFIG_HOME
, instead you should$ cp offlineimap.conf.minimal $XDG_CONFIG_HOME/offlineimap/config
Edit the config file
My config file
$XDG_CONFIG_HOME/offlineimap/config
is$XDG_CONFIG_HOME/offlineimap/config
[general] accounts = Accountname maxsyncaccounts = 1 [Account Accountname] localrepository = Accountname-Local remoterepository = Accountname-Remote synclabels = yes postsynchook = ~/.config/offlineimap/postsync.sh [Repository Accountname-Local] type = GmailMaildir localfolders = ~/mail/Accountname [Repository Accountname-Remote] type = Gmail remoteuser = Accountname@gmail.com remotepass = yourpassword sslcacertfile = /etc/ssl/certs/ca-certificates.crt folderfilter = lambda foldername: foldername in ['[Gmail]/All Mail'] nametrans = lambda foldername: re.sub('^\[Gmail\]/All Mail$', 'all',foldername)
Note that
- To use this, we should change
Accountname
,yourpassword
appropriately. - We have to change the path of
postsysnchook
,sslcacertfile
to adjust our environment.
Above details
Every time the local mailbox is synchronized, notmuch commands for refreshing and tagging should be executed. So the shell-script
postsync.sh
, which is described later, are hooked.postsynchook = ~/.config/offlineimap/postsync.sh
To synchronize Gmail account, need the certification file due to SSL connection. Put your local SSL certification file to
sslcacertfile
.sslcacertfile = /etc/ssl/certs/ca-certificates.crt
Gmail has many virtual folders linked to its tags and these folders share some e-mails. If all folders are synchronized to the local, the same e-mail is downloaded to multiple folders. Therefore, only "All Mail" on Gmail is synchronized and its local folder name is changed to "all" for simplicity.
folderfilter = lambda foldername: foldername in ['[Gmail]/All Mail'] nametrans = lambda foldername: re.sub('^\[Gmail\]/All Mail$', 'all',foldername)
- Regarding Gmail authentication, since I don't know OAUTH2 well,
I use the app password of Google 2-Step-Verification
(See Sign in using App Passwords).
Subsitute it in
yourpassword
.
- To use this, we should change
To see
offlineimap
to work well, execute$ offlineimap
, and if
~/mail/Accountname/all/
is created and your mails are stored under the folder, it works well.
Systemd service configuration
On above settings offlineimap
can fetch e-mails from your gmail server.
Next offlineimap
is configured to be automatically executed.
I decided to use systemd.timer
, which execute the target
unit file periodically.
The target is one-shot service that execute offlineimap
.
Copy installed
offlineimap.timer
,offlineimap-oneshot.service
andmail.target
to~/.config/systemd/user/
.$ cp offlineimap.timer offlineimap-oneshot.service mail.target ~/.config/systemd/user/
If you don't have
mail.target
, you can create the following.~/.config/systemd/user/mail.target
[Unit] Description=Mail Target [Install] WantedBy=default.target
(Optional) I edited
offlineimap.timer
to executeofflineimap-oneshot.service
soon (1m) after systemd startup and every 5 minutes.~/.config/systemd/user/offlineimap.timer
[Unit] Description=Offlineimap Query Timer [Timer] OnStartupSec=1m OnUnitInactiveSec=5m Unit=offlineimap-oneshot.service [Install] WantedBy=mail.target
On
offlineimap-oneshot.service
, comment out[Install]
section to make it a static service, otherwise this service is executed on every startup and slows its process.~/.config/systemd/user/offlineimap-oneshot.service
[Unit] Description=Offlineimap Service (oneshot) [Service] Type=oneshot ExecStart=/usr/bin/offlineimap -o -u syslog # Give 12 seconds for offlineimap to gracefully stop before hard killing it. TimeoutStopSec=12 # Restart=on-watchdog # WatchdogSec=300 # [Install] # WantedBy=mail.target
Make These files effective.
$ systemctl --user enable mail.target $ systemctl --user enable offlineimap-oneshot.service $ systemctl --user enable offlineimap.timer
By these settings the 1st goal are satisfied.
Notmuch
Notmuch
is an email tag system, it makes very easier to find and arrange
emails. It also provides emacs
interface. In this section, create
its database and the folder which stores it, and configure auto refresh and
auto tagging.
Executing
notmuch
for the first time, interactive setup is appeared. Following the guide input your user name, mail address and local mail folder, which needs to be the upper directory or the same as offlineimap's local directory (I set~/mail/
), and the config file~/.notmuch-config
is created. After configuring, execute$ notmuch new
, then the mail database file is created.
This command also refreshes the notmuch database file.
To refresh the database and tag emails every time
offlineimap
fetches e-mails from the server, editpostsync.sh
described above.~/.config/offlineimap/postsync.sh
notmuch new notmuch tag -inbox +sent from:Accountname@gmail.com
notmuch tag -inbox +sent from:Accountname@gmail.com
means theinbox
tag is removed and thesent
tag is added regarding the e-mails sent fromAccountname@gmail.com
.Another way
If you try to make many tag rules, you should write them in an external file and let
notmuch tag
to read it.~/.config/offlineimap/postsync.sh
notmuch new notmuch tag --batch --input=/home/guest/.config/offlineimap/notmuch_tag
~/.config/offlineimap/notmuch_tags
-inbox +sent from:Accountname@gmail.com -inbox +promotions unsubscribe
emacs
Notmuch emacs interface
Notmuch emacs interface files mostly have already been installed
with Notmuch
. To load the interface files when the emacs command
notmuch
is executed, the following is added to your emacs config file
(~/.emacs
, ~/.emacs.el
, or ~/.emacs.d/init.el
).
~/.emacs, ~/.emacs.el, or ~/.emacs.d/init.el
(autoload 'notmuch "notmuch" "notmuch mail" t)
If you configure more, you should use Emacs customization interface
executing the command M-x customize-group RET notmuch RET
.
Message mode
Using notmuch
on emacs
, you will use message-mode
when
you compose emails. The configuration of message-mode
is
~/.emacs, ~/.emacs.el, or ~/.emacs.d/init.el
;; setup the mail address and use name (setq mail-user-agent 'message-user-agent) (setq user-mail-address "Accountname@gmail.com" user-full-name "Accountname") ;; smtp config (setq smtpmail-smtp-server "smtp.gmail.com" message-send-mail-function 'message-smtpmail-send-it) ;; report problems with the smtp server (setq smtpmail-debug-info t) ;; add Cc and Bcc headers to the message buffer (setq message-default-mail-headers "Cc: \nBcc: \n") ;; postponed message is put in the following draft directory (setq message-auto-save-directory "~/mail/draft") (setq message-kill-buffer-on-exit t) ;; change the directory to store the sent mail (setq message-directory "~/mail/")
On this config the Gmail server is used as smtp server.
But above settings don't provide authentication infomation, so Emacs
looks into ~/.authinfo
or ~/.authinfo.gpg
.
About these files, see Emacs Wiki: Sending Mail.
Sent and draft mails should be put in the directory Notmuch can
read.
offlineimap execution on emacs
Using the notmuch emacs interface, I often refresh my local mail box
from emacs. Followings are the configuration to execute offlineimap
on emacs
.
~/.emacs, ~/.emacs.el, or ~/.emacs.d/init.el
(defun notmuch-exec-offlineimap () "execute offlineimap" (interactive) (set-process-sentinel (start-process-shell-command "offlineimap" "*offlineimap*" "offlineimap -o") '(lambda (process event) (notmuch-refresh-all-buffers) (let ((w (get-buffer-window "*offlineimap*"))) (when w (with-selected-window w (recenter (window-end))))))) (popwin:display-buffer "*offlineimap*")) (add-to-list 'popwin:special-display-config '("*offlineimap*" :dedicated t :position bottom :stick t :height 0.4 :noselect t))
Configuration details
- Used sentinel to refresh all notmuch-related buffers and show the end
of the output of
offlineimap
on*offlineimap*
buffer. *offlineimap*
buffer is shown with a popup window of emacspopwin
package.