Auto Syncing Mail for Neomutt

I have recently started to use the terminal based email client Neomutt. More specifically Muttwizard by Luke Smith. It is a great tool, which basically sets up your mail box and creates all the required configuration files for the various programs curated for use with Neomutt. It also provides some macros, for example you can press ‘o’ within Neomutt to manually sync mail via the mailsync script which comes with Muttwizard.

One of the recommended ways of facilitating automatic mail syncing is to set a cronjob. Looking at the mailsync script, it is even stated that parts of the script have to be ugly in order to pass environment variables to your cron manager.

On my personal machines, I have never really ever felt the need to use a cron manager. When I moved over to Arch it never occurred to me to even install a cron manager and so I was kind of loathed to install one now, only to sync mail. So, I decided to create my own solution.

Simple “checkmail” Script

At first I thought I could just alter the existing mailsync script that comes with Muttwizard. However considering it was also made with the intention of being used with a cron manager, and can also be called via a shortcut within Neomutt, I thought it best to leave it alone and just run the appropriate commands in their own in a separate scripts instead.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/sh

if [ $1 -lt 5 ] ; then
	echo "Error! Please use a number greater than 5"
else	
	while true; do 
	mbsync -c ~/.config/mbsync/config -a > /dev/null 2>&1
	notmuch new > /dev/null 2>&1
	sleep $1
	done
fi

All the script does is check if the argument given is less than 5 (seconds). If the argument given is less than 5 seconds it will quit with the error message. If the value is 5 or greater the while loop will kick in, syncing the mail via mbsync and indexing the mail via notmuch, according to the number of seconds you specified when running the command checkmail 60, for example.

The output of the mbsync and notmuch commands is sent to /dev/null making the script silent. This is important for the next script, as without it the syncing and indexing would otherwise print the information on top of Neomutt, which makes Neomutt look a mess!

Output of mbsync and notmuch printed on the top of Neomutt

That’s no beuno.

I decided to keep this in it’s own dedicated script in case I wanted to call it without running Neomutt, for example when the system boots. However, I wouldn’t necessarily recommend running this script on it’s own, once started it will continue to run until it is manually killed or the system is restarted - which will be an issue if you use the next script, I’ll explain in a moment.

Note: If you set up Neomutt on your own, you may be using other programs to sync and index mail, so you would need to change the commands to suit your needs.

Wrapper for Neomutt

Secondly, I made another very simple wrapper script, to call both the previous script and Neomutt at the same time. I called it cmutt on my system, for ‘check mutt’ but you could call it anything.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/sh

killall checkmail > /dev/null 2>&1
if [ $1 -lt 5 ] ; then
	echo "Error! Please use a number greater than 5"
else
	checkmail $1 &
	neomutt
	killall checkmail > /dev/null 2>&1
fi

All this script is doing is checking again the number of seconds given is no less than 5, then exiting any running instance of the checkmail script, opening Neomutt and once exited, killing all instances of checkmail. This script is useful if you only want your mail to be synced when actually using Neomutt and all syncing to be stopped when you exit, i.e. checkmail won’t be running all the time in the background.

The reason I wouldn’t recommend using the checkmail script on it’s own if you plan on using this script is because cmutt will kill any previously ran instance of checkmail. Of course whilst cmutt will create a new instance of checkmail that too will be terminated once you quit the instance of Neomutt spawned with cmutt.

So, really it depends on your use case. You could start checkmail when your system boots and use the regular neomutt command. Or you could just use cmutt to spawn both checkmail and neomutt instead.

Tweak Neomutt for Notifications

There are a couple of tweaks needed to allow these scripts to send notifications and it’s important to remember the notification will only be received for as long as Neomutt is open. These changes need to be applied to your account’s muttrc file, if you also used Muttwizard, the file can be found here: ~/.config/mutt/accounts/your@email.com.muttrc.

1
2
set mail_check = 5
set new_mail_command = 'notify-send "New Mail\!" "%?n?%n new mail(s) in your@email.com account.?"'

Muttwizard sets the global mail_check option in Neomutt to 60 seconds, this is noted to help some email accounts experiencing lag such as those on Yahoo. If you have issues with lag, this option probably shouldn’t be changed. I haven’t experienced any issues myself so I put it back to Neomutt’s default setting of 5 seconds. The only other thing needed to be done is to tell Neomutt which command to execute when it has found new emails.

One other setting I also added which also makes these scripts nice to use is, and it’s nice in general if you are not using the recommended GPG agent.

1
set pgp_timeout = 3600

This setting means that once you have given you GPG password to pass it will wait 3600 second (or 1 hour) before requiring the password again.

Shortcomings and Benefits

There is one disadvantage that I can think of with my method. For example, checkmail doesn’t send notifications when it is running on it’s own in the background, unlike Muttwizard’s mailsync command. I guess this is also why Muttwizard doesn’t set the new_mail_command parameter either, as I presume you are expected to use the included mailsync command which provides the notification instead of Neomutt. I’m sure implementing notifications within my checkmail script is easy enough, but for now I am happy with the way things are… To be honest, I disable most notifications in any case (at the very minimum I always have everything on silent. I cannot stand those stomach dropping bell sounds!) I hate being bombarded! If being notified is super important to you and I imagine it will be for many, it may very well be better to use Muttwizard’s included tools and run a cron manager instead.

I think the advantages for me with my method (but hey, I’m biased) is you can bind cmutt to a keyboard shortcut, Neomutt opens and you are instantly prompted for your GPG password. You can leave Neomutt open in a spare workspace and you’ll be notifed of new emails, if you go over the hour’s GPG timeout you are automatically prompted for your password again and can carry on as you were. Once you are finished, you can close Neomutt and there is nothing left running in the background! Additionally rather than using a dedicated keybinding, you can call cmutt from the terminal and specify how often you’d like to check for mail per session. However, I do generally prefer to use a dedicated keybinding, currently I have it set to check for new emails every 10 seconds and so far it has worked really well.