Stephen Gilmore

Advanced Gmail filters with Apps Script

Productivity July 10th, 2023 3 minute read.

Gmail provides many advanced search operators to filter emails. But sometimes, I need something more complex that isn't supported out of the box. A recent example was applying a label to any email with a specific header value. The rest of this post covers how to do it. In about 5-ish steps, we'll create an App Script to apply a label to any incoming email with the header X-PHISHTEST.

Creating the script

  1. Following the quickstart guide, create a new script by visiting script.google.com/create

  2. Name the project something meaningful and then edit the Code.gs file to add the following:

// main function designed to get a list of gmail threads and process them 1 by 1 via processsMessage()
function processInbox() {
   // https://webapps.stackexchange.com/questions/5719/is-it-possible-to-create-a-gmail-filter-that-works-on-headers-other-than-from-t
   var threads = GmailApp.search("is:unread in:inbox");
   for (var i = 0; i < threads.length; i++) {
      // get all messages in a given thread
      var messages = threads[i].getMessages();
      for (var j = 0; j < messages.length; j++) {
         var message = messages[j];

         // Process the message to check if it's a phishing email
         processMessage(message);
      }
   }
}

// processes an individual message, checking for the header "X-PHISHTEST"
function processMessage(message) {
  var subject = message.getSubject();
  var header = message.getHeader("X-PHISHTEST");
  if (header) {
    // Log phishing email found
    console.info("Found X-PHISHTEST header: " + message.getSubject() + " (" + message.getHeader("From") + ")")
    // Add "Phish" label
    message.getThread().addLabel(GmailApp.getUserLabelByName("Phish"));
  }
}
  1. Click the Run button and accept the required permissions to run the script. Check the output to make sure there are no errors. (Don't forget to manually create the Gmail label if it doesn't already exist)

Scheduling the script

  1. Click on the 'Triggers' icon (looks like a clock) to create a trigger to automatically run the script.
  2. Add a new trigger with the following configuration:
    Choose which function to run: processInbox
    Which runs at deploymnet: Head
    Select event source: Time-driven
    Select type of time based trigger: Minutes timer
    Select minute interval: Every 5 minutes
    Failure notification settings: Notify me daily
    
  3. Click Save

Done!