Systemd Timer for mbsync

Menu

How to setup your environment to periodically retrieve email from the server using systemd.

Introduction

I am reading Email with mu4e. Despite some quirks and oddities, especially when dealing with HTML emails, I have not yet found a more efficient way of managing emails: a keyboard-driven workflow and, more important, a search which actually works (and no, Google mail is not an option for me.)

This post is about setting up a systemd timer to periodically retrieve emails, with the advantage of not having to trigger email download from Emacs, either periodically (with a timer) or manually with the U key.

There are other posts about systemd and mu4e on this website, among which:

  1. Reading IMAP email with Emacs, which describes the configuration. (This is sufficient to become operational with mu4e.)
  2. Secret Tool, which describes how to store password for mbsync securely in Linux. (This secures Email passwords, if needed.)
  3. Systemd as a cron replacement, which is a brief tutorial for systemd. (This simplifies mail retrieval.)

BTW, If you want to get started with mu4e, the order in which I presented the previous posts is the one in which you want to read them.

Notice also that the systemd setup described here is also available on the ArchWiki iSync page, which might provide additional information, if need be.

The Systemd Unit and Timers

Create the following two files in: ~/.local/systemd/user.

The service: mbsync.service

The service starts mbsync and the index emails with mu index.

[Unit]
Description=Mbsync synchronization service

[Service]
Type=oneshot
ExecStart=/usr/bin/mbsync -Va
ExecStartPost=/usr/bin/mu index

The Timer: mbsync.timer

The unit starts the mbsync.service two minutes after startup and every ten minutes and two.

[Unit]
Description=Mysync synchronization timer

[Timer]
OnBootSec=2m
OnUnitActiveSec=10m
Unit=mbsync.service

[Install]
WantedBy=timers.target

Enable and Start the Timer

systemctl enable --user mybsync.timer
systemctl start --user mbsync.timer

Tell Emacs we are retrieving email with an external application

Finally we need to tell Emacs email is retrieved and indexed by an external utility (and not within Emacs). This can be done by setting the variables mu4e-update-interval and mu4e-get-mail-command.

Notice that you still have to tell Emacs to update with the U key, but now the process in nearly instantaenous, since most of the work has already been performed outside Emacs.

As an extra bonus, I defined two simple functions which allow to switch configuration:

(defun av/mu4e-retrieve-from-emacs ()
  (interactive)
  (setq 
    mu4e-update-interval nil
    mu4e-get-mail-command "mbsync -a"))

(defun av/mu4e-retrieve-outside-emacs ()
  (interactive)
  (setq 
    mu4e-update-interval nil
    mu4e-get-mail-command "true"))

(av/mu4e-retrieve-outside-emacs)