Google Apps Script to filter emails from Fedora Discussion in GMail

Hi everyone,

If you are using GMail and you’re reading the messages from Fedora Discussion there, then you might find the following Google Apps Script handy as it helps to orient better in tags, categories and messages there. What it does is that it looks at the messages from Fedora Discussions, parses the tags and categories and creates GMail labels for these and labels the messages with them. So it might look as:

The script is originally hosted at FedoraDiscourseGMailLabeler.gs · GitHub, but I’m putting it here as well:

//
// 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:notifications@fedoraproject.discoursemail.com"
//       - 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:notifications@fedoraproject.discoursemail.com");
  else {
    // GMail can't query anything newer than 1 hour.
    var threads = GmailApp.search("from:notifications@fedoraproject.discoursemail.com 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_();
}

Improvements are welcome! :slight_smile:

1 Like