Search code examples
google-apps-scriptgmail-api

apps script: Process emails that contain specific text **only**


I have some production code that I am repurposing. Currently, it processes everything based on the gmail label and puts a specified portion into a spreadsheet. This will not change (though it could if that was the best way to solve this problem).

I now need to process a subset of those messages and put a portion of the message body into a spreadsheet. The body of the text is as follows:

This is an email alarm.
Room Lights OFF.

(Other examples might say "Room Lights ON", "ALARM", or "OK".

I only need to get the portion of the body after "Room Lights".

Also included in this gmail label are emails that do not mention "Room Lights" at all. These should be ignored and not added to the spreadsheet. Example:

This is an email alarm.
Network has returned.

or

This is an email alarm. 
Generator is OFF.

Question: How can I edit my code so that only "Room Lights" emails are added to the spreadsheet?

Example code:

function lightFunction() {
  newMonth();
  var label = GmailApp.getUserLabelByName("Lights");
  var label2 = GmailApp.getUserLabelByName("Processed");
  var threads = label.getThreads();
  var data = new Array();
  var newData = new Array();
  var alarmKeys = "This is an email alarm.";
  var keys = alarmKeys.split(",");
  var range = "A2:B";

    // get all the email threads matching label
    for (var i = 0; i < threads.length; i++) {
        var messages = GmailApp.getMessagesForThread(threads[i]);

        // archive thread
        // label2.addToThread(threads[i]);
        // label.removeFromThread(threads[i]);

        // get each individual email from the threads
        for (var j = 0; j < messages.length; j++) {
            var bodyText = messages[j].getPlainBody();
            
            for (k in keys) {
                bodyText = bodyText.replace(keys[k], "");
            }
            bodyText = bodyText.trim();
            
            var date = messages[j].getDate(); // date/time
            var lines = [date, bodyText];

            // Turn the first element in the array into a date element, format it, and put it back
            lines[0] = Utilities.formatDate(new Date(lines[0]), "America/Phoenix", "M/d/yy HH:mm:ss");
          
          // Put the array to a new item in the data array for further processing
            if (curMonth == (new Date(lines[0]).getMonth())) {
                data.push(lines);
            }
         }
      }  
   checkAdd(data, range);
}

Solution

  • ALTERNATE METHOD

    You could also tweak the part with data.push(lines); with regex using a match method in one line, something like this:

    lines[1].match(/Room Lights|OK|ALARM/gm) ? data.push(lines) : null;
    

    You may also check this sample regex test.

    In my understanding here is the flow:

    1. Read emails under labels Lights / Processed
    2. Check each email that may match the following texts:

    "Room Lights OFF", "Room Lights ON", "ALARM", or "OK"

    1. Only add the matched emails on the spreadsheet

    Tweaked Script

    function lightFunction() {
      newMonth();
      var curMonth = new Date().getMonth()
      var label = GmailApp.getUserLabelByName("Lights");
      var label2 = GmailApp.getUserLabelByName("Processed");
      var threads = label.getThreads();
      var data = new Array();
      var newData = new Array();
      var alarmKeys = "This is an email alarm.";
      var keys = alarmKeys.split(",");
      var range = "A2:B";
    
      // get all the email threads matching label
      for (var i = 0; i < threads.length; i++) {
        var messages = GmailApp.getMessagesForThread(threads[i]);
    
        // archive thread
        // label2.addToThread(threads[i]);
        // label.removeFromThread(threads[i]);
    
        // get each individual email from the threads
        for (var j = 0; j < messages.length; j++) {
          var bodyText = messages[j].getPlainBody();
    
          for (k in keys) {
            bodyText = bodyText.replace(keys[k], "");
          }
          bodyText = bodyText.trim();
    
          var date = messages[j].getDate(); // date/time
          var lines = [date, bodyText];
    
          // Turn the first element in the array into a date element, format it, and put it back
          lines[0] = Utilities.formatDate(new Date(lines[0]), "America/Phoenix", "M/d/yy HH:mm:ss");
    
          // Put the array to a new item in the data array for further processing
          if (curMonth == (new Date(lines[0]).getMonth())) {
            //Tweaked part
            lines[1].match(/Room Lights|OK|ALARM/gm) ? data.push(lines) : null;
            //Tweaked part
          }
        }
      }
      checkAdd(data, range);
    }
    

    Demonstration

    Sample emails

    enter image description here

    Log test of the data variable

    enter image description here

    References