Emacs: Saving Sent Emails to IMAP


Emacs mail composer limitations

Emacs offers two easy-to-use methods for composing emails:

  • mail - a simple method for plain text email messages
  • message-mail - a more sophisticated option that supports multipart MIME messages

I will intentionally skip the GNUS and MH-E modes here.

Both of these email composers open a buffer with an email template, allowing for quick composition and sending with a single keystroke. They are ideal for sending a quick message while working on other tasks.

However, there is one notable shortcoming of these methods: sent emails are not stored anywhere, similar to the "Sent" mailbox you might find in mainstream MUAs.

Although Emacs provides the Fcc header to save messages into a local mailbox, this solution does not work if you keep your emails on a remote IMAP server that needs to be shared among multiple devices.

In this note, I will address this issue server-side through a clever application of the Bcc header and a Sieve filter.

The result: ad-hoc emails composed in Emacs will automatically land in your remote IMAP Sent folder.

Sub-addressing

Many email services support a tagging system within the local part of the address, allowing multiple variations to route to the same inbox. Typically, this involves adding characters after a plus. For example, addresses john+bar@example.com and john+foo@example.com can all be directed to the same inbox as john@example.com.

Sub-addressing is described in RFC 5233 and this is the first element of our puzzle.

We're going to append a +sent tag to our e-mail address and add it to the Bcc header. My e-mail headers will look something like:

From: john@example.com
To: jane@example.com
Bcc: john+sent@example.com
Subject: Pancakes!

In plain words, I'm going to loopback this e-mail to myself.

Server side filtering

My email server uses Sieve, so all I need to do is instruct it to store loopbacked emails in the Sent folder. I can identify these by checking the Bcc header. This filter should be placed early in the rules chain to avoid messages being caught by other rules:

  if envelope :contains "to" "john+sent@example.com" {
    setflag "\\seen";
    fileinto "Sent";
    stop;
  }

The exact tag used can be chosen to be difficult to guess, in order to avoid potential DoS attacks. I'm using +sent here for brevity.

Unfortunately, filtering by Bcc requires access to the mail envelope, which may not be supported by all email providers.

Gmail filters do support this method under delivered-to: name, while Outlook uses something like X-MS-Exchange-Organization-Recipient-P2-Type. Your mileage may vary.

Emacs configuration

We need to add default Bcc header to our composer template:

  (setq mail-default-headers "Bcc: john+sent@example.com\nX-Motto: Unix - live free() or die()\n")
  (setq message-default-headers "Bcc: john+sent@example.com\nX-Motto: Unix - live free() or die()\n")

Now, when launching mail or message-mail, the template will contain Bcc:

From: John Doe <john@example.com>
To: 
Subject: 
Bcc: john+sent@example.com
X-Motto: Unix - live free() or die()
--text follows this line--

Sent e-mail should automatically land in your Sent folder.