Skip to content

Instantly share code, notes, and snippets.

@stain
Last active November 13, 2023 08:17
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save stain/c176164be966eb5c1850ea0886058b49 to your computer and use it in GitHub Desktop.
Save stain/c176164be966eb5c1850ea0886058b49 to your computer and use it in GitHub Desktop.
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
[database]
path=/home/USER/mail
[user]
name=MyName MySurname
primary_email=me@example.com
other_email=me@example.org
[new]
## Sorting to inbox now done by /home/USER/mail/.notmuch/hooks/post-new
tags=new
[search]
exclude_tags=deleted;spam;junk
[maildir]
synchronize_flags=true
## ...
[general]
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 = me@org1.example.com
remotepasseval = keyring.get_password('gmail', 'org1')
# Avoid XOAUTH2 errors https://github.com/OfflineIMAP/offlineimap/issues/285
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 = imap.company.example.com
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 https://github.com/OfflineIMAP/offlineimap/issues/285
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')
#!/bin/sh
notmuch tag +watch -inbox -new tag:new 'folder:/.*Sent.*/'
#!/bin/bash
set -e
echo -n Filtering new messages
## All messages
## Poor man's progress bar. adjust for number of steps
STEPS=30
echo -n ' ['
for n in `seq $STEPS`; do
echo -n '.'
done
echo -ne ']\b'
# Backspace
for n in `seq $STEPS`; do
echo -ne '\b'
done
## 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 '(from:notifications@github.com)'
# 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 from:nomail@accounts.example.com from:warning@example.org
# Notification from project1's issue tracker and chat systems
# not really personal even though they are sent to:me@example.com
echo -n b
notmuch tag -new +inbox +project1 tag:new from:notifications@tasks.example.com from:noreply@example.com from:chat.example.org
## End of services
# To/Cc one of my addresses
echo -n p
notmuch tag -new +inbox +personal tag:new '(to:MySurname OR to:me@example.com OR to:me@example.org)'
# 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 'to:project2@example.org'
# 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 from:alice@example.com OR from:bob@example.org'
# Project4 and friends
echo -n 4
notmuch tag -new +inbox +project4 tag:new 'project4 OR to:project4 OR OR from:charlie@example.com OR from:daniel@example.org''
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
done
# **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 '(from:boss@example.com OR to:boss@example.com OR cc:boss@example.com)'
##
# 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 from:me@example.com from:me@example.org
##
# 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 ']'
#!/bin/bash
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