////// Easily customizable stuff | |
// Step zero: have a filter that sorts all notifications@github.com mail into _github_incoming & archives it | |
var incomingLabel = '_github_incoming'; // You can hide this in the sidebar. | |
// github sends to "me", and I want less of that pollution | |
var toMeLabel = 'asf'; | |
// labels for various conditions: | |
var meLabel = 'github'; | |
var teamMentionLabel = 'github/team_mention'; | |
///// End of the easily customizable stuff | |
// The main entry and trigger point for the post-hoc filter: | |
function processIncoming() { | |
processMessages(true); | |
} | |
// Run this manually from the scripts console to backfill your github labels without filling your inbox: | |
function processIncomingBackfill() { | |
processMessages(false); | |
} | |
function processMessages(putIntoInbox) { | |
var incoming = getOrCreateLabel(incomingLabel); | |
var threads = incoming.getThreads(); | |
for (var i = 0; i < threads.length; i++) { | |
var thread = threads[i]; | |
var messages = thread.getMessages(); | |
// We consider only the last message, as you might have unsubscribed from github threads, or situations may have otherwise changed: | |
sortMessage(messages[messages.length-1], thread, putIntoInbox); | |
thread.removeLabel(incoming); | |
} | |
} | |
function getOrCreateLabel(name) { | |
var label = GmailApp.getUserLabelByName(name); | |
if(label == null){ | |
label = GmailApp.createLabel(name); | |
} | |
return label | |
} | |
function sortMessage(message, thread, putIntoInbox) { | |
var headers = messageHeaders(message.getRawContent()); | |
if (isMessageRelevant(headers)) { | |
Logger.log("Thread with message subject %s is relevant", headers['Subject']); | |
markAsMine(thread, putIntoInbox); | |
} else { | |
Logger.log("Thread with subject %s is not relevant", headers['Subject']); | |
markAsNonRelevant(thread); | |
} | |
} | |
function isMessageRelevant(headers) { | |
var isIt = (headers['X-GitHub-Reason'] === 'author') || | |
(headers['X-GitHub-Reason'] === 'comment') || | |
(headers['X-GitHub-Reason'] === 'assign') || | |
(headers['X-GitHub-Reason'] === 'mention'); | |
return isIt; | |
} | |
function markAsMine(thread, putIntoInbox) { | |
thread.addLabel(getOrCreateLabel(meLabel)); | |
if (putIntoInbox) { | |
thread.moveToInbox(); | |
} | |
} | |
function markAsNonRelevant(thread) { | |
thread.addLabel(getOrCreateLabel(teamMentionLabel)); | |
var messages = thread.getMessages(); | |
var wasEverRelevant = false; | |
for(var i=0; i < messages.length; i++) { | |
var body = messages[i].getRawContent(); | |
var headers = messageHeaders(body); | |
if (isMessageRelevant(headers)) { | |
wasEverRelevant = true; | |
} | |
} | |
if (!wasEverRelevant && toMeLabel !== null) { | |
thread.removeLabel(GmailApp.getUserLabelByName(toMeLabel)); | |
} | |
} | |
/* Takes a raw message and returns a dictionary of header=>header values. | |
* Note: This handles only "simple"&short (non-continued) headers, so any | |
* continuation lines aren't going to be processed - only the first line | |
* will be considered a value. | |
*/ | |
function messageHeaders(body) { | |
var lines = body.split(/\r?\n/); | |
var headers = [], wasNewline = false; | |
// Determine the empty line & split there: | |
for(var i=0; i < lines.length && !wasNewline; i++) { | |
var line = lines[i]; | |
if (line === '') { | |
wasNewline = true; | |
} else { | |
headers.push(line); | |
} | |
} | |
var headerDict = {} | |
for (var i=0; i < headers.length; i++) { | |
var headerSplit = headers[i].split(": "); | |
var key = headerSplit.shift(); | |
if (!key.match(/^\s/)) { | |
// it's a not header continuation, so add it as a new key | |
headerDict[key] = headerSplit.join(": "); | |
} | |
} | |
return headerDict; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment