Isync is a command-line utility used for synchronising (downloading) remote and local mailboxes. Isync can be used as part of a tool-chain to be able to retrieve, store and send mail all from the command line.

Benefits

The benefits of using isync combined with neomutt(a command-line mail client) over just neomutt is that isync stores a local cache, so when offline, you can still view your emails. There is also the benefit of increased speed and a reduction in bandwidth usage; as isync only downloads new emails to the local cache. Whereas neomutt, when hooked into IMAP, doesn’t keep a local cache. Therefore it needs to re-download all emails each time; meaning you can’t view your email without an internet connection.

Installation

For Arch Linux isync is in the main repositories and can be installed easily via pacman.

sudo pacman -S isync

Setting up isync

Isync’s configuration file resides in ${HOME}/.mbsyncrc. Within this configuration file, you need to define how to download each mailbox and each ‘channel’ for every email account.

We will start by defining the remote IMAP servers configuration. As an example, I will pretend to be setting up this configuration for a Gmail account.

Note to use isync with Gmail you need to ‘Enable Less Secure Apps’, you can follow the steps here https://www.dev2qa.com/how-do-i-enable-less-secure-apps-on-gmail/.

IMAP setup

# Global Channel configuration.
Create Both
Expunge Both
Remove Both
Sync All
SyncState *

################################
####### example@gmail.com ######
################################
# IMAP setup
IMAPAccount example-gmail
Host imap.gmail.com
User example@gmail.com
PassCmd "pass Communications/Gmail"
SSLType IMAPS

...

The variables under # Global Channel configuration. will be explained later when talking about channel configuration.

################################
####### example@gmail.com ######
################################

Is not required, but I use it to denote the different sections of the configuration file for the various emails; helping me to find what I want quickly.

IMAPAccount example-gmail Denotes the IMAP’s account name, and tells isync the following options are related to IMAP. The name does not affect anything; so you can name it anything you want.

Host imap.gmail.com Denotes the IMAP server’s URL. The IMAP URL is email provider-specific, check your email providers website to find the provider’s specific URL.

User example@gmail.com Is the username to login in as to the IMAP server. This is typically your email, but it can vary depending on the provider.

PassCmd "pass Communications/Gmail" PassCmd tells isync the shell command it can execute to fetch the IMAP servers password for the user. I use the utility ‘pass’ to manage all my passwords, it is a useful utility, and you should check it out.

However, you can do Pass examplePassword if you would prefer to enter the password in plain text. But be warned now anyone who can get hold of your configuration file has YOUR PASSWORD!

Note you don’t need to specify either PassCmd or Pass if the options are missing when executing isync’s command mbsync then you are just prompted for the password.

Local & Remote storage setup

...

# Remote storage setup
IMAPStore example-gmail-remote
Account example-gmail

# Local storage setup
MaildirStore example-gmail-local
Path ~/.neomutt/mail/example-gmail/
Inbox ~/.neomutt/mail/example-gmail/inbox

...

Now that we have set up the IMAP server configuration, we will move on to define the properties of remote and local locations we will be synchronising.

IMAPStore example-gmail-remote Denotes the IMAP’s store name, and tells isync the following configurations are related to the IMAP store. Again the name does not affect anything; so you can name it anything you want.

Account example-gmail Specifies which IMAP configuration to use for the IMAPStore, here we are referencing the IMAPAccount configuration we specified earlier, using the name we gave it.

MaildirStore example-gmail-local Gives your local Maildir Store a name, also informing isync a Maildir Store is about to be configured. As previously stated; the alias can be anything you want.

Path ~/.neomutt/mail/example-gmail/ tells isync the location on the file system to store the local mail cache.

Inbox ~/.neomutt/mail/example-gmail/inbox defines the location to contain the local cache’s inbox folder. Typically it is inside the Path directory defined above.

NOTE - Path needs to end in a / whereas Inbox does not.

Setting up the channels to synchronise

...

# Inbox
Channel example-gmail-inbox
Master :example-gmail-remote:
Slave  :example-gmail-local:inbox

# Sent
Channel example-gmail-sent
Master :example-gmail-remote:"[Gmail]/Sent Mail"
slave  :example-gmail-local:sent

# Drafts
Channel example-gmail-drafts
Master :example-gmail-remote:"[Gmail]/Drafts"
slave  :example-gmail-local:drafts

# Trash
Channel example-gmail-trash
Master :example-gmail-remote:"[Gmail]/Bin"
slave  :example-gmail-local:trash

# Spam
Channel example-gmail-spam
Master :example-gmail-remote:"[Gmail]/Spam"
slave  :example-gmail-local:spam

...

Now we have defined the local/remote storage locations and entered the IMAP credentials; we now need to define which ‘channels’ (folders) we want to synchronise with our local cache. We don’t have to download every remote folder we can be selective, change the folders name and various other custom configurations to meet your needs!

Channel example-gmail-inbox Denotes the channels name and tells isync the following parameters are related to this channel. Again the name does not affect anything; so you can name it anything you want.

Master :example-gmail-remote: Defines the Master folder for the channel as the remote IMAP, from which it will take directions from. We reference the remote IMAPStore by the name we gave it prior. The option follows the format Master :<remote IMAP>:<folder> because we are defining the inbox which is the default we do not need to specify the folder, but for other folders, they will need to be detailed.

Slave :example-gmail-local:inbox Declares the slave repository as the local cache via the naming we gave it. Like Master the format has the format Slave :<local cache name>:<folder>. However, note that even though it is still the inbox channel being defined, you need to give the folder to save it to. The remote host will be synchronised to $PATH/<folder>, i.e. the path we defined earlier for MaildirStore.

Channel example-gmail-sent
Master :example-gmail-remote:"[Gmail]/Sent Mail"
slave  :example-gmail-local:sent

Above is another example of a channel; for this, we are defining the sent channel. Note the remote Master now contains a folder, this is the same naming and structure as on the remote host. The remote data in [Gmail]/Sent Mail is now synchronised to our local cache at $PATH/sent.

Global/Local Channel Configurations

# Global Channel configuration.
Create Both
Expunge Both
Remove Both
Sync All
SyncState *

...

At the beginning of the configuration file, there were the above options which I did not explain. They are configurations for channels, having them at the top of the file makes them global options which apply to every channel.

However, you can override global settings by defining them locally for a channel.

Channel example-gmail-sent
Master :example-gmail-remote:"[Gmail]/Sent Mail"
slave  :example-gmail-local:sent
Create None

...

For the channel above the global setting Create Both has been overridden by Create None, this local option is set for this channel only, and all the other channels use the global setting.

Create Both Tells isync to create missing mailboxes automatically. Create can take the options {None|Master|Slave|Both}.

Expunge Both Permanently deletes all messages marked for deletion. Expunge can take the options {None|Master|Slave|Both}.

Remove Both Notifies isync if it should propagate mailbox deletions. Remove can take the options {None|Master|Slave|Both}.

Sync All Informs isync to synchronise all operations, pull, push, delete etc.

SyncState * Tells isync to keep the channel’s synchronisation state files inside the channel’s local cache of the folder, in the file .mbsyncstate.

Grouping channels


...

Group example-gmail
Channel example-gmail-inbox
Channel example-gmail-sent
Channel example-gmail-drafts
Channel example-gmail-trash
Channel example-gmail-spam

We can group channels into a group. Meaning you can use the command mbsync <group> to synchronise all the channels in that group. So you can only update select email accounts or specific folders across all accounts if we are limited by download speed or size etc.

However you don’t need to define any groups, you can use mbsync -a to synchronise all channels in the mbsync configuration file.

Multiple Email’s

As I previously alluded to when mentioning the inclusion of :

################################
####### example@gmail.com ######
################################

You can configure multiple email accounts from which to synchronise channels. To achieve this, you define them sequentially one after another. I use the header to signify where one email’s configuration stops and another begins. I use it to quickly find my place among a wall of text annotating several account’s configuration and options.

...

################################
####### example@gmail.com ######
################################

...

################################
##### example@outlook.co.uk ####
################################

...

TIP: How to find out remote IMAP folder names

Sometimes you have no idea of the remote IMAP folders naming or the structure, meaning you can not configure the channels for the email address.

To overcome this problem, you can download the whole remote folder, without altering the structure or naming, then using the structure of the unaltered local cache you can work out how to configure the channels you desire.

...

# Local storage
MaildirStore example-gmail-local
Subfolders Verbatim
Path ~/.neomutt/mail/example-gmail/
Inbox ~/.neomutt/mail/example-gmail/inbox

Channel example-gmail-default
Master :example-gmail-remote:
Slave  :example-gmail-local:
# Include everything
Patterns "*"

Subfolders Verbatim specifies that the local cache should use the directory hierarchical structure $PATH/top/sub/subsub. Meaning it will copy the remote structure verbatim.

Patterns "*" is some simple regex telling isync to synchronise every remote folder.

Notice how on the end of the Slave for the channel that there is no directory specified, meaning it will default to the remote naming and structure.

Now you need to synchronise the email then inspect your local cache to know the remote server’s structure and naming conventions.

TIP: Documentation

If you want to know more about a specific configuration and the options available you can read the man page man mbsync and scroll past the command line usage description to get to the configuration file documentation!

References