sieve-delay tool: delay email delivery Michael Ernst I find it distracting to frequently receive new email. sieve-delay delays mail delivery: instead of a steady stream throughout the day, you will periodically receive a batch of messages. (If you have the willpower to simply not check your email, and you don't need to have your mailbox open for other reasons, then you don't need the sieve-delay tool!) For example, I filter my mail into multiple IMAP folders, containing mail that should be delivered to me * immediately (only urgent mail) * on the hour (the default) * once a day (mailing lists) * etc. There are three parts to the sieve-delay tool: 1. A standard sieve script that indicates what mailbox each message should be filed into. These can be ordinary IMAP mailboxes. For documentation of sieve, see RFC3028, "Sieve: A Mail Filtering Language". You will have to decide how to categorize your mail. (I used to do all this via procmail, but sieve is much cleaner.) For example, here are excerpts from my sieve rules (which are actually much larger and better documented): ## Mail rules -*- sieve -*- require ["fileinto", "reject", "vacation"]; ### Resends from me with mail drop specified if header :contains "Resent-Comment" "maildrop-daily" { fileinto "INBOX.delay-daily"; stop; } if header :contains "Resent-Comment" "maildrop-hourly" { fileinto "INBOX.delay-hourly"; stop; } ### Spam and junk mail if header :contains "X-Spam-Flag" "YES" { fileinto "INBOX.Spam"; stop; } ### Immediate delivery if header :contains "From" ["mernst@csail.mit.edu", "mernst@alum.mit.edu"] { fileinto "INBOX"; stop; } if allof ( header :contains "To" ["mernst@csail.mit.edu", "mernst@alum.mit.edu"], header :contains "Subject" "urgent") { fileinto "INBOX"; stop; } ### Daily mail (delivered once per day) if header :contains "Sender" [ "rre@lists.gseis.ucla.edu" ] { fileinto "INBOX.delay-daily"; stop; } ### Hourly mail (all other mail) fileinto "INBOX.delay-hourly"; stop; ### End of file 2. Cron jobs that indicate when it is time to read particular mailboxes. For instance, my cron file includes: ### ### Maildrops ### 01 * * * * touch $HOME/.mail/.time-to-read-hourly 25 4 * * * touch $HOME/.mail/.time-to-read-daily 26 4 * * Mon touch $HOME/.mail/.time-to-read-weekly 27 4 1 * * touch $HOME/.mail/.time-to-read-monthly 3. Code to tell your mail reader when to use those extra mailboxes -- namely, exactly when the above files exist. Here is code for the VM mailreader (which runs under Emacs): ;; ;; Extra spool files (for delayed mail) ;; (defun csail-imap-spool-file (folder) "Returns a spool file descriptor for the given folder." ;; CSAIL IMAP ;; (concat "imap:imap.csail.mit.edu:143:" folder ":cram-md5:mernst:*") ;; CSAIL IMAP via ssl tunneling (encrypts message bodies as well as password) (concat "imap-ssl:imap.csail.mit.edu:993:" folder ":cram-md5:mernst:*") ) (defun vm-extra-spool-file (drop) "Returns either a spool file descriptor or nil. DROP is \"hourly\", \"daily\", etc." (let ((time-to-read-file (substitute-in-file-name (concat "$HOME/.mail/.time-to-read-" drop)))) (if (file-exists-p time-to-read-file) (progn (delete-file time-to-read-file) ;; return the descriptor (csail-imap-spool-file (concat "inbox.delay-" drop)))))) (defadvice vm-get-spooled-mail (around add-extra-spool-files activate) (let ((vm-spool-files (append vm-spool-files (remove nil (mapcar (function vm-extra-spool-file) '("hourly" "daily" "weekly" "monthly" "later")))))) ad-do-it))