Offline computing: Working with mails

Having for the first time an unlimited access to Internet at home was
really a game changer for me.  But it didn't last.  Indeed, I lived
through different periods, some where I had constant access and others
where it was very sparse.  So I always more or less had the idea that I
needed to keep my data at hand, locally.

That is why, on the mail front, I used for many years the combo
fetchmail(1) / procmail(1) to retrieve and organize my mails on my
computer.  And few years ago, since I was using more and more mails
(newsletters, mailing list, etc.), I switched to maildir format,
dropped my beloved combo, and went with offlineimap(1).

Then the pandemic came.  My wife and I found ourselves confined at
home, without work.  During the first lockdown, she started to plan
what she'll do to earn money when all will open again.  Her idea was to
transform our one-room apartment into a nail art salon.

It turns out it was a great idea and it worked very well for her (and
it still is!).  The downside was that we didn't had anymore a place "to
live" during the day.  Our apartment became a work shop, where it
happened we were sleeping at night.  Among others effects, it meant I
couldn't stay home, on my computer, searching for work, while she was
attending her clients.  I had to get out everyday, to give her space,
hitting the streets to find job opportunities.  And I had to do it
without being online.  Forced disconnection.

***

Nowdays in France, to find a job, you'll need 1) job offers, usually
posted online, 2) the ability to make phone calls, and 3) a way to
receive and send emails.

For the phone calls, I had a phone with a good call plan, and a big
external charger to help me last the day.

The job offers?  During the evening, I could browse Internet at home,
harvest them, saving them into text files on my laptop in order to be
processed correctly the day after.  Plus, many of the web sites
offering job gives the choice to receive them by mail each morning.

So now, to receive mails and store them locally, it was easy thanks to
offlineimap(1).  It is a simple but very efficient python tool, well
documented with great howtos like the one available on Arch Linux's
wiki.

I could have stopped here, but because I was writing my emails and
cover letters during the day, away from Internet, I wanted a way to
send them, even without a connection, or at least to put them in a
queue, ready to be sent as soon as I'd have access to the Network
again.  I didn't want to deal with drafts, I wanted something more
straight forward: I write mails, I "send them", stored in a queue
locally, and once I get home or find a spot at the local library, I
connect the laptop and hit a button to actually send them all without
thinking of it.

This is where msmtp(1) came to the rescue.

***

How does my configuration works?

Along with the rent of my domain name, my registrar gives two
mailboxes, with 3Go of space each.  I have access to POP3, IMAP and
SMTP.  I filter and organize the mails in folders server-side with the
help of the sieve language.  The servers are handled by professionnals. 
They are around since april 2000 and they have a great reputation in
the various french FOSS and hackers communities, so I'm quite
confident.  I pay roughly 15 euros per year for their services and, in
case of legal or technical problems, they are located in my country of
residence so they are easy to contact, even by phone call.

To retrieve my mails (already organized in folders server-side, as
said), I use offlineimap(1) by John Goerzen.  The configuration takes
place in ~/.offlineimaprc and is very easy:

---8<--- $HOME/.offlineimaprc

 ## configured thanks to https://wiki.archlinux.org/index.php/OfflineIMAP
 ## and https://pbrisbin.com/posts/mutt_gmail_offlineimap/

 [general]
 accounts = main
 maxsyncaccounts = 1
 fsync = true

 [Account main]
 localrepository = main-local
 remoterepository = main-remote
 autorefresh = 0.5
 quick = 10

 [Repository main-local]
 type = Maildir
 localfolders = ~/mail/

 [Repository main-remote]
 type = IMAP
 remotehost = host.domain.tld
 remoteuser = username
 keepalive = 60
 holdconnectionopen = yes
 sslcacertfile = /etc/ssl/certs/ca-certificates.crt

--->8---

Once synced locally, mails can then be read with any client which
supports the maildir format.  Personally I use mutt(1) which is also
easy to configure:

---8<--- $HOME/.muttrc (snippet)

 set mbox_type   = Maildir
 set folder      = ~/mail
 set spoolfile = "+INBOX"
 set record = "+Sent"
 set postponed = "+Drafts"

--->8---

Now, the fun part: how to "send" mails in a queue locally.

msmtp(1) is an SMTP client written by Martin Lambers.  It works as any
other SMTP client which means it reads a mail from standard input and
sends it directly to an SMTP server for delivery.  The configuration is
not difficult and takes place in the ~/.msmtprc file.  We define a main
SMTP account and ask msmtp(1) to use it by default:

---8<--- $HOME/.msmtprc

 # Set default values for all following accounts.
 defaults
 port 587
 tls on
 tls_starttls on
 tls_trust_file /etc/ssl/certs/ca-certificates.crt

 # main account
 account main
 host host.domain.tld
 auth on
 user username
 domain laptop.domain.tld

 # Set a default account
 account default : main

--->8---

The magic comes from three shell scripts that can be found in the
"scripts/msmtpqueue" folder in the sources of msmtp(1); check
https://git.marlam.de/gitweb/?p=msmtp.git;a=tree;f=scripts/msmtpqueue
for further details (the README is great).  They are called
msmtp-enqueue.sh, msmtp-runqueue.sh, and msmtp-listqueue.sh.  As the
author says, they are very simple and dumb.

msmtp-enqueue.sh is used to send mails from the mail client into a
queue.  In mutt(1) it means that one just needs to point the variable
"sendmail" to this script like so, along with msmtp(1) options:

---8<--- $HOME/.muttrc (snippet)

 set sendmail = "/path/to/msmtp-enqueue.sh -X /tmp/msmtplog -t"

--->8---

In mutt(1), I write or reply normally to my mails.  The mails to be
sent are automagically stored in a folder.  Each one is separated in
two plain text files, where one is the actual mail and the other
contains the options to pass to msmtp(1).  Once home, and online, I can
see all the mails that are waiting in queue with msmtp-listqueue.sh,
and then launch msmtp-runqueue.sh so msmtp(1) sends all my mails of the
day to the SMTP server for delivery.

Note that there is another version of the scripts (in "scripts/msmtpq"
folder) that will check if an internet connection is available.  If so,
the mail will go directly to the SMTP server; otherwise it will be
saved in the queue locally.  It can be handy for the people who don't
want to always use the queue system.

***

As a conclusion, I would like to say that I have found with these tools
a simple and effective way of working with my emails without
necessarily having to have a constant connection to Internet.  Surely
all this can take a little time to configure and test properly.  But
once done, the workflow with the mails is pretty straight forward:

In the morning, before going out, I run "offlineimap -o" to retrieve
new mails.  During the day, being offline, I normally use mutt(1) to
read and respond to them.  And when I have the chance to wire my laptop
to Internet again (mostly when I get back home at night), I just run
"msmtp-runqueue.sh" to send all the mails I've wrote.