Cannot add created label to threads

Viewed 38

I tried to write a function in Google Apps Script that creates a new label in Gmail and adds it to threads. I have two problems:

  1. When I run the function for the first time (archivedLabel not existing yet) I cannot add it to the threads immediately after it is created. archivedLabel = GmailApp.getUserLabelByName(labelText) at the end of the if statement will still return null and the script crashes. If I run the script for the second time (label already created) everything works fine.

  2. The new labels only appear in Gmail after the user refreshes the Gmail App in the browser. Is there a way to do this automatically or a method to refresh the labels and messages so I can see the new label in Gmail without manually reloading the page?

function addArchivedLabel(thread){
  var labelText = "Backed up";
  var archivedLabel = GmailApp.getUserLabelByName(labelText);
  
  //create new archived label if not already existing
  if(archivedLabel == null) {
    var textColor = "#89d3b2"; // Please set this.
    var backgroundColor = "#ffbc6b"; // Please set this.
    var userId = "me";
    var resource = Gmail.newLabel();
    resource.labelListVisibility = "labelShow";
    resource.messageListVisibility = "show";
    resource.name = labelText;
    var labelColor = Gmail.newLabelColor();
    labelColor.textColor = textColor;
    labelColor.backgroundColor = backgroundColor;
    resource.color = labelColor;
    
    Gmail.Users.Labels.create(resource, userId);
    archivedLabel = GmailApp.getUserLabelByName(labelText);
  }
  archivedLabel.addToThread(thread); //add new label to archived emails
}
1 Answers

I just encountered the same problem For some reason this is working :

function getOrCreateLabel() {
  if (!GmailApp.getUserLabelByName(LABEL_NAME)) {
    GmailApp.createLabel(LABEL_NAME)
  }
  console.log(GmailApp.getUserLabelByName(LABEL_NAME)) // not NULL
}

And this is not working as expected:

function getOrCreateLabel() {
  if (!GmailApp.getUserLabelByName(LABEL_NAME)) {
     Gmail.Users.Labels.create({
       "labelListVisibility": "labelHide",
       "messageListVisibility": "hide",
       "name": LABEL_NAME
     }, "me")
  }
  console.log(GmailApp.getUserLabelByName(LABEL_NAME)) // NULL
}

For the second function,It seems that appsscript cache the response of GmailApp.getUserLabelByName at runtime.

So in my opinion. You will need to create a trigger, here a working exemple:

function addArchivedLabel(thread){
  var labelText = "Backed up";
  var archivedLabel = GmailApp.getUserLabelByName(labelText);

  const thread_id = UserProperties.getProperty("thread")
  // Check if come from trigger
  if (thread_id) {
    //  retrieve the thread
    thread = GmailApp.getThreadById(thread_id)

    // Clean property and trigger
    UserProperties.deleteProperty("thread")
    ScriptApp.getScriptTriggers().forEach((p) => {
      if (p.getHandlerFunction() == "addArchivedLabel") {
        ScriptApp.deleteTrigger(p)
      }
      })
  }
  
  //create new archived label if not already existing
  if(archivedLabel == null) {
    var textColor = "#89d3b2"; // Please set this.
    var backgroundColor = "#ffbc6b"; // Please set this.
    var userId = "me";
    var resource = Gmail.newLabel();
    resource.labelListVisibility = "labelShow";
    resource.messageListVisibility = "show";
    resource.name = labelText;
    var labelColor = Gmail.newLabelColor();
    labelColor.textColor = textColor;
    labelColor.backgroundColor = backgroundColor;
    resource.color = labelColor;
    
    Gmail.Users.Labels.create(resource, userId);
    UserProperties.setProperty("thread", thread.getId())
    ScriptApp.newTrigger("addArchivedLabel").timeBased().everyMinutes(1).create()
    return
  }
  archivedLabel.addToThread(thread); //add new label to archived emails
}

// fixture to simulate get thread
    function main() {
      const thread = GmailApp.getInboxThreads()
      addArchivedLabel(thread[0])
    }

Hope it will help

Related