Skip to content

Instantly share code, notes, and snippets.

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