Skip to content

Instantly share code, notes, and snippets.

@tpopela
Last active April 14, 2023 09:17
Show Gist options
  • Save tpopela/e2f17bf8eac15bee734b993e170f4dfa to your computer and use it in GitHub Desktop.
Save tpopela/e2f17bf8eac15bee734b993e170f4dfa to your computer and use it in GitHub Desktop.
//
// HOWTO:
// 1. Go to script.google.com for the Google account that is receiving the
// email notifications from Fedora Discourse
// 2. Create a new project and rename it to "Fedora Discourse GMail Labeler"
// 3. Copy and paste this whole script in the editor and replace whatever
// content is there
// 4. Save the file
// 5. On the left side next to the editor click on the plus button next to
// Services and add a "Gmail API" service
// 6. Now run the script by clicking on the "Run" button
// 7. You will have to grant the permissions to the project so it can access
// your inbox
// 8. Wait until the run completes
// 9. Change the value of the firstRun variable in this script to false
// 10. Switch to Triggers section on the left side and add a new trigger
// and make sure that the processFedoraDiscourse function is set in the
// "Choose which function to run" field. By default the script runs once
// per hour, but I suggest to run it more often - i.e. once per 15 minutes.
// To do that set the following parameters:
// - event source is set to "Time driven"
// - type of time based trigger is set to "Minutes timer"
// - minute interval is set to "15 minutes"
// 11. Save the trigger
// 12. One thing that you should keep in mind is that the script doesn't run
// when new message is delivered, so the messages will stay in your inbox
// until the trigger triggers. What I would suggest is to create a new GMail
// filter with the following parameters:
// - from field set to "from:[email protected]"
// - choose "Skip the Inbox (Archive it)"
// - choose "Fedora Discourse" label in "Apply the label:" field
// 13. Profit!
//
var labelPrefix = "Fedora Discourse"
var categoriesLabelPrefix = labelPrefix + "/categories"
var tagsLabelPrefix = labelPrefix + "/tags"
var genericLabel = labelPrefix + "/generic"
// Change this to false after the first run so the script is not processing
// all the messsages when it's being executed.
var firstRun = true;
function getLabel_(labelName) {
var label = GmailApp.getUserLabelByName(labelName);
if (!label) {
Logger.log("Creating label: " + labelName);
label = GmailApp.createLabel(labelName);
}
return label;
}
function extractHeaderValue_(messageBody, key) {
var regex = new RegExp("X-Discourse-" + key + ": (.*)$", "m");
var result = regex.exec(messageBody);
if (!result)
return null;
return result[1];
}
function removeAllOurLabels_(thread) {
var labels = thread.getLabels();
labels.forEach(function (label) {
var name = label.getName();
if (name.indexOf("/tags/") || name.indexOf("/categories/"))
thread.removeLabel(label);
})
}
function processThread_(thread) {
// Remove all labels that we've previously set to the thread, because tags might have
// changed or the discussion was moved to a different category. This could definitely
// be optimized so we can remove the label only when needed.
removeAllOurLabels_(thread);
// Get the last message in a given thread as that one should contain the latest
// and most relevant tags and the actual category.
var messages = thread.getMessages();
var index = 0;
if (messages.length > 1)
index = messages.length - 1;
var message = messages[index];
var body = message.getRawContent();
var tags = extractHeaderValue_(body, "Tags");
if (tags) {
tags.split(" ").forEach(function(tag) {
var label = getLabel_(tagsLabelPrefix + "/" + tag);
thread.addLabel(label);
});
}
var category = extractHeaderValue_(body, "Category");
if (category) {
var label = getLabel_(categoriesLabelPrefix + "/" + category);
thread.addLabel(label);
}
if (!category && !tags) {
var label = getLabel_(genericLabel);
thread.addLabel(label);
}
Logger.log(" message with tags: \"" + tags + "\" and category \"" + category + "\"");
}
function processNewThreads_() {
if (firstRun)
var threads = GmailApp.search("from:[email protected]");
else {
// GMail can't query anything newer than 1 hour.
var threads = GmailApp.search("from:[email protected] newer_than:1h");
}
Logger.log("Got threads: " + threads.length);
threads.forEach(function(thread) {
Logger.log("Processing thread: " + thread.getFirstMessageSubject());
processThread_(thread);
});
}
function setupLabels_() {
GmailApp.createLabel(labelPrefix);
GmailApp.createLabel(categoriesLabelPrefix);
GmailApp.createLabel(tagsLabelPrefix);
GmailApp.createLabel(genericLabel);
}
function processFedoraDiscourse() {
setupLabels_();
processNewThreads_();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment