Last active
October 20, 2020 06:31
-
-
Save Rican7/867cb9dee1555528041865bc3b8cdd11 to your computer and use it in GitHub Desktop.
Filters Gmail message threads to apply helpful GitHub labels, for organization.
This file contains hidden or 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
/** | |
* Labels Gmail email threads | |
*/ | |
function labelGithubEmails() { | |
/** | |
* Gmail label names for GitHub messages | |
*/ | |
const githubLabelName = 'GitHub' | |
const githubPullRequestLabelName = 'GitHub/Pull Request' | |
const githubIssueLabelName = 'GitHub/Issue' | |
const githubDiscussionLabelName = 'GitHub/Discussion' | |
const githubReleaseLabelName = 'GitHub/Release' | |
const githubCommitLabelName = 'GitHub/Commit' | |
const githubLabel = GmailApp.getUserLabelByName(githubLabelName) | |
const githubPullRequestLabel = GmailApp.getUserLabelByName(githubPullRequestLabelName) | |
const githubIssueLabel = GmailApp.getUserLabelByName(githubIssueLabelName) | |
const githubDiscussionLabel = GmailApp.getUserLabelByName(githubDiscussionLabelName) | |
const githubReleaseLabel = GmailApp.getUserLabelByName(githubReleaseLabelName) | |
const githubCommitLabel = GmailApp.getUserLabelByName(githubCommitLabelName) | |
/** | |
* The query to use when finding messages to process | |
* | |
* Tweak this to improve the processing time/performance of messages, especially to prevent reaching maximum time/limits defined in the quotas. | |
* | |
* See: https://support.google.com/mail/answer/7190 | |
* See: https://developers.google.com/apps-script/guides/services/quotas#current_limitations | |
*/ | |
const gmailSearchQuery = '(label:github AND NOT label:github-pull-request AND NOT label:github-issue AND NOT label:github-discussion AND NOT label:github-release AND NOT label:github-commit) AND newer_than:1d'; | |
const rfc822MessageIdHeaderName = 'Message-ID' | |
const pullRequestMessageIdRegex = /.*\/pull(s)?\/.*@github.com/i; | |
const issueMessageIdRegex = /.*\/issue(s)?\/.*@github.com/i; | |
const discussionMessageIdRegex = /.*\/discussion(s)?\/.*@github.com/i; | |
const releaseMessageIdRegex = /.*\/release(s)?\/.*@github.com/i; | |
const commitMessageIdRegex = /.*\/commit(s)?\/.*@github.com/i; | |
const maxPerPage = 50; | |
var startIndex = 0; | |
do { | |
var threads = GmailApp.search(gmailSearchQuery, startIndex, maxPerPage); | |
Logger.log('Gmail search query found %s results, with a range of %s-%s', threads.length, startIndex, (startIndex + maxPerPage)) | |
threads.forEach(function (gmailThread) { | |
var firstMessage = gmailThread.getMessages()[0]; | |
var mailRFCMessageIds = getEmailHeaderValues(firstMessage.getRawContent(), rfc822MessageIdHeaderName); | |
// Determine the type of message | |
var [isPullRequest, isIssue, isDiscussion, isRelease, isCommit] = mailRFCMessageIds.reduce( | |
function ([isPullRequestMessage, isIssueMessage, isDiscussionMessage, isReleaseMessage, isCommitMessage], messageId) { | |
// Test for message type | |
isPullRequestMessage = isPullRequestMessage || pullRequestMessageIdRegex.test(messageId); | |
isIssueMessage = isIssueMessage || issueMessageIdRegex.test(messageId); | |
isDiscussionMessage = isDiscussionMessage || discussionMessageIdRegex.test(messageId); | |
isReleaseMessage = isReleaseMessage || releaseMessageIdRegex.test(messageId); | |
isCommitMessage = isCommitMessage || commitMessageIdRegex.test(messageId); | |
return [isPullRequestMessage, isIssueMessage, isDiscussionMessage, isReleaseMessage, isCommitMessage]; | |
}, | |
[false, false, false, false, false] | |
); | |
Logger.log('Message (%s) with `Message-ID: %s` detected as %s', firstMessage.getId(), mailRFCMessageIds.join(', '), {"isPullRequest": isPullRequest, "isIssue": isIssue, "isDiscussion": isDiscussion, "isRelease": isRelease, "isCommit": isCommit}) | |
if (isPullRequest) { | |
gmailThread.addLabel(githubPullRequestLabel); | |
} | |
if (isIssue) { | |
gmailThread.addLabel(githubIssueLabel); | |
} | |
if (isDiscussion) { | |
gmailThread.addLabel(githubDiscussionLabel); | |
} | |
if (isRelease) { | |
gmailThread.addLabel(githubReleaseLabel); | |
} | |
if (isCommit) { | |
gmailThread.addLabel(githubCommitLabel); | |
} | |
}); | |
startIndex += threads.length; | |
} while (threads.length >= maxPerPage); | |
} | |
/** | |
* Gets values for an email header | |
*/ | |
function getEmailHeaderValues(rawEmail, headerName) { | |
const headerRegex = new RegExp('^' + headerName + ': (.*(?:\\r?\\n\\s+.*)?)$', 'gim'); | |
var values = []; | |
do { | |
var matches = headerRegex.exec(rawEmail); | |
if (Array.isArray(matches) && 1 in matches) { | |
values.push(matches[1]); | |
} | |
} while (null !== matches); | |
return values; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To use this filter
main.gs
in the Google Apps Script project.labelGithubEmails
function every minute.It should work now!