My mutt & Gmail Setup

So you want quick offline access to your mails using mutt to fully exploit your SSD and yet still have everything nicely working in Google’s web interface? Additionally, you would like to have access to your Google Contacts just like in your phone and everywhere else? I’ll show you how!

To be honest, I’ve stolen lots of ideas presented here from Steve Losh. Yet I’d like to make a nice coherent summary, so there’s everything in one place.

This guide assumes you are running Ubuntu Linux (the version du jour being Natty Narwhal as of writing this) but it shouldn’t be hard to adapt it for other distributions, Mac OS X or any other UNIX.

I won’t go through all mutt options that would be necessary to fully configure a mutt client as that would lengthen this article beyond readability. I’ll just point out peculiarities that are specific for Gmail. General hints for configuring mutt are more than numerous on the web.

Let’s start by laying some groundwork.

Sending

Of course, you can use a real MTA like sendmail, postfix or exim. However, I prefer to go lightweight and use a simple and dedicated tool called msmtp which is just a sudo apt-get install msmtp away.

I happen to use Gmail’s SMTP server because the mails are archived for me for free if sent throught it, so I don’t have to upload my mails twice. Add the following lines in your ~/.mstmprc:

account default
host smtp.gmail.com
user yourusername@gmail.com
password yourpassword
auth
maildomain your.domain.if.applicable
auto_from off
from your@from.address
logfile ~/path/to/logfile
tls on
tls_fingerprint DB:A0:2A:07:00:F9:E3:23:7D:07:E7:52:3C:95:9D:E6:7E:12:54:3F

These few lines are enough to send out your mails and archive them in “Sent Mail”. In my case, these mails also landed in my inbox and were unread. Therefore I added a filter that marks mails sent by me unread and skip the inbox in Gmail’s web interface.

Receiving

For receiving we use the fantastic offlineimap. Essentially, it synchronizes local mail directories – which can be accessed very quickly – with an IMAP server and even has dedicated support for Gmail. Again, a simple apt-get install offlineimap is all it takes.

The cool part is that you can “translate” folder names. Yours truly prefers to rename “Sent Mail” to just “sent” for example. All the action happens inside of your ~/.offlineimaprc:

[general]
ui=Curses.Blinkenlights
accounts = private

[Account private]
localrepository = hs-Local
remoterepository = hs-Remote

[Repository hs-Local]
type = Maildir
localfolders = ~/.mail/private

[Repository hs-Remote]
type = Gmail
remoteuser = yourusername
remotepass = yourpassword
realdelete = no

nametrans = lambda folder: re.sub('.*Spam$', 'spam', 
	re.sub('.*Drafts$', 'drafts', 
    re.sub('.*Sent Mail$', 'sent', 
	re.sub('.*Starred$', 'flagged', 
    re.sub('.*Trash$', 'trash', 
	re.sub('.*All Mail$', 'archive', folder))))))

If you start a plain offlineimap now, you’ll get a nice GUI showing off what’s happening. Afterwards, all your mails from Gmail should be inside of ~/.mail/private, neatly sorted into Maildirs. If your computer is permanently connected to the internet, you may want to add something like

*/15 * * * * offlineimap -u Noninteractive.Quiet

to your crontab. If you need more or less frequent checks than every 15 minutes, just adjust the cron settings.

This setup leaves space for adding more than one account, for example your work email.

Up to this point, we haven’t done anything mutt specific yet. So all from above might also be useful to someone setting up Emacs with Gnus or any other Maildir capable mail agent.

Reading & Writing

Now, let’s get to the mutt specific parts! I suggest you create a directory called ~/.mutt/ and put all of your mutt related stuff inside instead of a single ~/.muttrc/. The central configuration file is ~/.mutt/muttrc and if you use multiple accounts, I suggest to add additional account specific config files that get sourced once you enter a folder of the account in question:

folder-hook private/* source ~/.mutt/private.muttrc

First of all, let’s make sure we can read and send mails. Sending is trivial, just add a set sendmail="/usr/bin/msmtp". Be aware, that a set sendmail_wait=0 together with msmtp will lead to the problem that you won’t notice if sending mails failed unless you look into the logs.

Reading mail is no rocket science neither:

set mbox_type = Maildir
set folder = ~/.mail/
set spoolfile = +private/INBOX
mailboxes = +private/INBOX +private/flagged +private/drafts +private/sent +private/trash \
	+private/spam +private/archive /var/log/mail/hynek

You have to add all your labels/folders to mailboxes of course.

The only essential part we’re missing here is how to search the archive and archive, delete and mark as spam single mails:

macro index E "<change-folder>+private/archive<enter><limit>~B " "search everything"
macro index,pager A "<save-message>+private/archive<enter>" "move message to the archive"
macro index D "<save-message>+private/trash<enter>" "move message to the trash"
macro index S "<save-message>+private/spam<enter>" "mark message as spam"

These settings are obviously account specific, that’s why they reside inside of my private.muttrc.

At this point, you can send, receive, read and write mails. Hooray!

There’s one blemish left: Reading mails in the respective folders doesn’t mark them read in the archive. Also, you have to start using Gmail’s labels as folders again for the same reason: One mail with three labels means three folders with an unread mail. I haven’t found a way to mitigate it but ignoring it and catch up from time to time. Let me know if you have found a cure!

Address Book

One of the most compelling features of using Gmail and an Android phone is the omnipresence of my contacts. Luckily, there’s a way to have these very contacts also inside of mutt: goobook.

Unfortunately, you can’t install goobook directly using apt-get. But it’s a neatly packaged python module, so after a sudo apt-get install python-pip you can install it using sudo pip install goobook.

Configure it as following in ~/.goobookrc:

email: you@gmail.com
password: yourgooglepassword

Integrating it with mutt is a simple matter of:

set query_command="goobook query %s"
macro index,pager a "<pipe-message>goobook add<return>" "add sender to google contacts"
bind editor <Tab> complete-query

From now on, pressing tab on in address fields queries your Google contacts and you can also use Q to query the address book.

At this point I’ll leave you to your curiosity. If you need inspiration, have a look at Steve’s dotfiles mentioned above (mine are very similar). If something’s unclear, feel free to leave a comment or to contact me.

Update: Please note that I don’t use Gmail anymore and that Steve Losh wrote an even more better summary.