Skip to content

Instantly share code, notes, and snippets.

@stain stain/.notmuch-config
Last active Mar 27, 2019

What would you like to do?
NotMuch hooks for selectively sorting to inbox, moving archived messages to other folder. offlineimap syncs to /home/USER/mail/company and /home/USER/mail/org1
name=MyName MySurname
## Sorting to inbox now done by /home/USER/mail/.notmuch/hooks/post-new
## ...
accounts = org1,company
ui = ttyui
fsync = true
maxsyncaccounts = 16
utime_from_header = yes
filename_use_mail_timestamp = yes
[Account org1]
localrepository = org1-local
remoterepository = org1-remote
autorefresh = 2
postsynchook = notmuch new
[Repository org1-local]
type = Maildir
utime_from_header = yes
filename_use_mail_timestamp = yes
localfolders = ~/mail/org1
# Spaces in pathname are bad. Lets use `archive` which is a simple word
# Besides, we only need `All Mail` folder.
# Sup would manage mails on its own.
# If your GMail language setting is not English, you can execute
# `offlineimap --info` to find out the name of folder which is
# translated and encoded after your account is configured.
nametrans = lambda folder: {'archive': '[Gmail]/All Mail',
}.get(folder, folder)
[Repository org1-remote]
# IMAP with hardcoded GMail config
type = Gmail
maxconnections = 2
# The path of ca-certfile might be different on your system.
sslcacertfile = /etc/ssl/certs/ca-certificates.crt
# Remember that GMail requires full mail address as username
remoteuser =
remotepasseval = keyring.get_password('gmail', 'org1')
# Avoid XOAUTH2 errors
auth_mechanisms = GSSAPI, CRAM-MD5, PLAIN, LOGIN
nametrans = lambda folder: {
'[Gmail]/All Mail': 'archive',
'[Gmail]/Sent': 'Sent',
'[Gmail]/Drafts': 'Drafts',
}.get(folder, folder)
folderfilter = lambda folder: folder in ('[Gmail]/All Mail', '[Gmail]/Sent', '[Gmail]/Drafts')
# Exchange
[Account company]
localrepository = company-local
remoterepository = company-remote
autorefresh = 2
presynchook = /home/USER/mail/.notmuch/hooks/pre-sync
postsynchook = notmuch new
[Repository company-local]
type = Maildir
localfolders = ~/mail/company
utime_from_header = yes
filename_use_mail_timestamp = yes
[Repository company-remote]
type = IMAP
remotehost =
maxconnections = 3
ssl = yes
# The path of ca-certfile might be different on your system.
sslcacertfile = /etc/ssl/certs/ca-certificates.crt
remoteuser = user1
remotepasseval = keyring.get_password('imap', 'company1')
# Avoid XOAUTH2 errors
auth_mechanisms = GSSAPI, CRAM-MD5, PLAIN, LOGIN
folderfilter = lambda folder: folder not in ('Calendar', 'INBOX.Emergency Webmail Folder', 'Calendar', 'Contacts', 'Journal', 'Tasks', 'Notes') and not folder.startswith("Deleted Items") and not folder.startswith("Archive/2") or folder in ('Archive/2018', 'Archive/2019')
notmuch tag +watch -inbox -new tag:new 'folder:/.*Sent.*/'
set -e
echo -n Filtering new messages
## All messages
## Poor man's progress bar. adjust for number of steps
echo -n ' ['
for n in `seq $STEPS`; do
echo -n '.'
echo -ne ']\b'
# Backspace
for n in `seq $STEPS`; do
echo -ne '\b'
## notmuch post-processing script
## Generally only works with messages with the tag:new folder
## Folder-based sorting (ignoring tag:new)
## junked by other email clients, even if we
## might have sorted it earlier
echo -n j
notmuch tag -new -inbox +junk "folder:/company/.*Junk.*/"
# already archived - no longer unread or inbox
echo -n a
notmuch tag -new -unread -inbox "folder:/company/Archive/"
# The below rule all focus on (not yet filtered) messages
## First we'll deal with services that send straight to us
# **Github** processing is two-stage as we need to filter
# Github notifications can be quite noisy, hopefully we'll
echo -n 'g('
notmuch tag +github tag:new '('
# Mentions us, better have a look
echo -n p
notmuch tag -new +inbox +personal tag:new '(tag:github @myUserName)'
# Some of the projects we carea bout
echo -n c
notmuch tag -new +inbox +project1 tag:new '(tag:github project1)'
echo -n t
notmuch tag -new +inbox +project2 tag:new '(tag:github project2)'
echo -n b
notmuch tag -new +inbox +project3 tag:new '(tag:github project3)'
echo -n u
# rest of GitHub messages are for other projects and stay out of inbox
notmuch tag -new tag:new '(tag:github)'
## end GitHub
echo -n ')'
# Automated messages from accounting system. we should look at right away
echo -n e
notmuch tag -new +inbox +flagged +eu tag:new
# Notification from project1's issue tracker and chat systems
# not really personal even though they are sent
echo -n b
notmuch tag -new +inbox +project1 tag:new
## End of services
# To/Cc one of my addresses
echo -n p
notmuch tag -new +inbox +personal tag:new '(to:MySurname OR OR'
# Might not be personal, but it mentions our uniquish name inside.
# Flag, but continue processing
echo -n s
notmuch tag +inbox +personal tag:new '(MySurname OR MyName)'
# private@project1
echo -n 1
notmuch tag -new +inbox +flagged +private +project1 tag:new 'to:private@project1'
# private@general is noisy and won't go to inbox (unless they talk about project1!)
echo -n G
notmuch tag -new +private +general tag:new 'to:private@general AND NOT project1'
# other general emails
echo -n g
notmuch tag -new +general tag:new 'to:@general'
# private@ for any other list go to INBOX
echo -n P
notmuch tag +inbox +private tag:new 'to:private@'
# Flag anything with "project1"
echo -n 1
notmuch tag -new +inbox +project1 tag:new 'project1 OR to:project1'
# We have to respond, add +flagged
echo -n F
notmuch tag -new +inbox +project2 +flagged tag:new ''
# anything with "project2"
echo -n 2
notmuch tag -new +inbox +project2 tag:new 'project2 OR to:project2'
# Project3 and friends
echo -n 3
# Include selected people we only know on project3 who like to send personal emails,
# to find more candidates, use
# notmuch address tag:project3 | sort
notmuch tag -new +inbox +project3 tag:new 'project3 OR to:project3 OR OR'
# Project4 and friends
echo -n 4
notmuch tag -new +inbox +project4 tag:new 'project4 OR to:project4 OR OR OR''
echo -n t
## .. or re-tag any threads with those people
for tag in project3 project4; do
notmuch search --output=threads tag:$tag | xargs notmuch tag +$tag +inbox -new tag:new
# **Threads to watch**
# We sent something
echo -n w
notmuch tag +watch -new tag:new 'folder:/.*Sent.*/'
# Boss is involved
echo -n B
notmuch tag +watch +inbox +boss tag:new '( OR OR'
# Look for new message in watched threads.
# Previously flagged once also count (we intended to reply but didn't)
echo -n W
notmuch search --output=threads tag:watch OR tag:replied OR tag:flagged | xargs notmuch tag +inbox +watch -new tag:new
## Undo potential false INBOX positives from ourself
# (keep the other tags like watch)
echo -n -
notmuch tag -inbox -new tag:inbox
# Anything else sent to @company is still in inbox, but
# marked as unsorted
echo -n i
notmuch tag +inbox +unsorted -new tag:new folder:company/INBOX
# the rest (other accounts and folders) are just unsorted
echo -n u
notmuch tag +unsorted -new tag:new
# Tip: To sort unsorted again after updating these rules, do:
# notmuch tag -unsorted +new tag:unsorted
# notmuch tag -github +new tag:github
echo ']'
echo "Moving messages according to notmuch tags"
# Make sure we have updated paths
notmuch new --no-hooks
# Archive files that are NOT tagged Inbox
filter="folder:company/INBOX -tag:inbox"
echo "`notmuch count $filter` archived messages"
notmuch search --output=files --format=text0 $filter | xargs -0 --no-run-if-empty mv -t ~/mail/company/Archive/new/
filter="tag:deleted tag:spam tag:junk AND (folder:/company/INBOX/ OR folder:/company/Archive/ AND NOT folder:/Junk/)"
echo "`notmuch count $filter` junk messages"
notmuch search --output=files --format=text0 $filter | xargs -0 --no-run-if-empty mv -t ~/mail/company/Junk\ E-Mail/new/
# Make sure we have updated paths
notmuch new --no-hooks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.