Offline e-mail in the terminal
I like putting stuff in the terminal. Let’s roll back the clock 30 years and go back to terminal e-mail.
Let’s start with installing an e-mail client.
I like aerc. I also use mac OS,
so it can be installed with a simple brew install aerc.
Setting up Aerc
Here’s another guide for that: Text based gmail
I personally use a gmail, so I had to create a gmail app password to provide to aerc.
On first startup, aerc has a startup wizard that helps you set up your account. Nice! Put in your information and enjoy e-mail in the terminal.
My aerc/accounts.conf looks something like this:
[Personal]
source = imap://me@gmail.com:password@imap.gmail.com:993
outgoing = smtp+plain://me@gmail.com:$APP_PASSWORD_HERE@smtp.gmail.com:587
smtp-starttls = yes
from = Me <me@gmail.com>
copy-to = SentAs well, I wanted to change up some of the defaults:
I set my aerc/aerc.conf like so: this sets my pager to
bat instead of less -R, and prefers to display
the HTML portion of an email first if possible, then falling back to the
plain text version.
To be able to read HTML e-mail, I uncommented the line for text/html,
and use the html filter that’s provided by aerc. This requires
w3m and dante, so I brew installed both:
[viewer]
pager=/usr/local/bin/bat
alternatives=text/html,text/plain
[filters]
subject,~^\[PATCH=awk -f @SHAREDIR@/filters/hldiff
text/html=bash /usr/local/share/aerc/filters/html
text/*=awk -f /usr/local/share/aerc/filters/plaintextGreat! Now we’re all set up with aerc.
Offline Support
This is great and all, but try to run aerc without
internet connection. It hangs. That’s not acceptable! Let’s fix
that.
Drew DeVault, the original author of aerc published a
guide on making aerc work offline https://drewdevault.com/2021/05/17/aerc-with-mbsync-postfix.html.
We’ll follow this guide a bit, but I use gmail instead of
migadu, and ended up using msmtp instead of
postfix, so there’ll be a few changes.
Mbsync for reading e-mail offline
Let’s start off installing mbsync. On Mac OS it is
listed as its previous name, isync. So run
brew install isync to install it.
We’ll then set it up – the config file is at
~/.mbsyncrc, so create that and fill it with this:
IMAPStore gmail-remote
Host imap.gmail.com
AuthMechs LOGIN
User you@gmail.com
Pass $APP_PASSWORD_HERE
SSLType IMAPS
MaildirStore gmail-local
Path ~/mail/gmail/
Inbox ~/mail/gmail/INBOX
Subfolders Verbatim
Channel gmail
Far :gmail-remote:
Near :gmail-local:
Expunge Both
Patterns * !"[Gmail]/All Mail" !"[Gmail]/Important" !"[Gmail]/Starred" !"[Gmail]/Bin"
SyncState *If you don’t already have a ~/mail/gmail/INBOX folder,
create it with mkdir -p ~/mail/gmail/INBOX.
Now, if you run mbsync gmail, all of your e-mail will be
synced to your ~/mail/gmail folder.
Now, we just need aerc to pull locally instead of from gmails servers.
Go back to aerc/accounts.conf, and edit the source under
the [Personal] tag to point to maildir://~/mail. This will
let aerc read your e-mail locally instead of from gmail’s servers.
As well, set the default to gmail/INBOX to land in your
inbox folder on start.
[Personal]
source = maildir://~/mail
outgoing = smtp+plain://me@gmail.com:$APP_PASSWORD_HERE@smtp.gmail.com:587
default = gmail/INBOX
smtp-starttls = yes
from = Me <me@gmail.com>
copy-to = SentTurn off your internet and run aerc. Now you can read
your e-mail offline! We’ll want to always keep our mailbox in sync, so
we’ll want to run mbsync frequently to keep our mailbox in
sync.
First, we’ll need a program called chronic, which is
provided in moreutils. Download it with
brew install moreutils.
Run crontab -e to edit your local crontab, and put this
in it.
This will have cron execute mbsync gmail every minute,
keeping your mailbox in sync with google’s servers.
Sending E-mail offline
If you try to send e-mail while offline on aerc currently, the e-mail will never send. What we’d like is some queue where the e-mail is sent immediately if we’re online, otherwise, to save that message in a queue, and send out all messages immediately as we regain connectivity.
We’ll use msmtp for that.
Install it with brew install msmtp.
msmtp’s config file is called ~/.msmtprc. Fill that file
with this:
defaults
tls on
account gmail
auth on
host smtp.gmail.com
port 587
user me
from me@gmail.com
password APP_PASSWORD_HERE
account default: gmailNow we can send e-mail from the command line. This isn’t super useful
yet, since aerc has this functionality already. Next, we need to
implement the queueing capability we discussed. You’ll want to download
two bash scripts that do this for us: msmtpq and
msmtp-queue. These can be found here: https://github.com/tpn/msmtp/tree/master/scripts/msmtpq.
Make them executable and place them somewhere on your path (I chose
/usr/local/bin). This implements the queueing that be
discussed.
Finally, we’ll have to hook up aerc to use this
capability in accounts.conf.
[Personal]
source = maildir://~/mail
outgoing = /usr/local/bin/msmtpq
default = gmail/INBOX
smtp-starttls = yes
from = Me <me@gmail.com>
copy-to = SentFinally, we’ll want to be able to execute the queueing functionality
of msmtpq every minute as well. Edit your crontab to look
like this:
And with that, we’re done! We can now read e-mail offline, which syncs every minute when online, and send e-mail offline, which will get queued, and sent as soon as we’re back online again.