-
-
Save schlos/d05c962579cbe8e603ac5a2c5d43cbcf to your computer and use it in GitHub Desktop.
Filters Gmail message threads to apply helpful GitHub labels, for organization.
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
/** | |
* 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