What would be the behaviour of GmailApp.createLabel when called multiple times with same label name?

15 views
Skip to first unread message

roar.om...@gmail.com

unread,
May 7, 2019, 2:32:51 AM5/7/19
to Google Apps Script Community
I tried the following code.

function addLabel() {
  console
.log(GmailApp.createLabel('FOO'));
  console
.log(GmailApp.createLabel('FOO'));
}

After running this function, I see that there is only one label FOO and the threads which are assigned earlier to FOO are retained. And no exception thrown at runtime for 'duplicate label name'.

Is this a valid behaviour? Can it be relied upon? The Official documentation doesn't mention anything like this.

Diego Moreno

unread,
May 7, 2019, 4:51:27 AM5/7/19
to Google Apps Script Community
Seems I just answered your question in Stack Overflow. https://stackoverflow.com/a/56018497/1329498

Calling GmailApp.createLabel() with a label name that already exists will return the already existing label. It will not make any changes to your existing label.

----------

According to the documentation, the only way to create or get a label is via the label's name. Importantly, the only identifying property listed in the GmailLabel class is the name. As such, my assumption would be that Apps Script is enforcing uniqueness of names and that it's preventing overwriting of existing labels. 

We can try a simple test. If the overwrite protection does _not_ exist, then creating a new label would likely remove the association between label & email. So let's see which emails appear under a certain label, create a new label with the same name, and see if the list of emails is the same. 

function test() {
 
var label1 = GmailApp.getUserLabelByName("test_label"); // Get existing label
 
var threads = label1.getThreads();
 
var label1_messages = [];
 
for (var i in threads) {
   
var messages = threads[i].getMessages();
   
for (var j in messages) {
      label1_messages
.push(messages[j].getId()); // Store the message IDs in label1_messages
   
}
 
}
 
 
var label2 = GmailApp.createLabel("test_label"); // Create a new label with the same name
 
var threads = label2.getThreads();
 
var label2_messages = [];
 
for (var i in threads) {
   
var messages = threads[i].getMessages();
   
for (var j in messages) {
      label2_messages
.push(messages[j].getId()); // Store the message IDs in label2_messages
   
}
 
}
 
Logger.log(JSON.stringify(label1_messages) == JSON.stringify(label2_messages)); // Quick, non-robust check of the arrays results in TRUE
}


The result is that they are the same, so that confirms the assumption that createLabel() is smart enough to avoid overwriting existing labels.

We can go further, though. The Gmail API clearly indicates that labels have an ID. Here again, I don't see any requirement that label names be unique (although, we can assume it given that end users can only interact with label names–it would be terrible UX if multiple with the same name existed).

If you enable the Gmail API in Advanced Google services, we can test the API requirements. Try creating a new label with the same name of a label that we already know exists. 

function createLabel() {
 
Gmail.Users.Labels.create({name: "test_label"}, "me");
}


That results in the below error, which then confirms that label names must be unique. 

API call to gmail.users.labels.create failed with error: Label name exists or conflicts

Let's go one step further. Initially, I assumed that Apps Script was protecting against overwriting existing labels. So let's check the ID of the existing label, then call GmailApp.createLabel() with the same label name, and see if a new label was created/the label ID changed.

function finalTest() {
 
var response = Gmail.Users.Labels.list("me"); // Get labels
 
for (var i in response.labels) {
   
var label = response.labels[i];
   
if (label.name == "test_label")
     
Logger.log(label.id); // ID: Label_48
 
}
 
 
var newLabel = GmailApp.createLabel("test_label"); // Create a new label with the same name
 
 
var response = Gmail.Users.Labels.list("me"); // Get labels again to see if any difference
 
for (var i in response.labels) {
   
var label = response.labels[i];
   
if (label.name == "test_label")
     
Logger.log(label.id); // ID: Label_48
 
}
}


As you can see, the label ID remains the same, meaning that GmailApp.createLabel() is indeed protecting against overwriting existing labels. 

roar.om...@gmail.com

unread,
May 7, 2019, 5:54:33 AM5/7/19
to Google Apps Script Community
Thanks Diego for the elaborate answer. This information could be added to the apps script docs. It would help people understand the behaviour clearly.
Reply all
Reply to author
Forward
0 new messages