Last active
March 26, 2021 07:29
-
-
Save antifuchs/dde7d18d757d57478ba8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////// Easily customizable stuff | |
// Step zero: have a filter that sorts all [email protected] 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