首页 > 解决方案 > 当使用相同的标签名称多次调用时,GmailApp.createLabel 的行为是什么?

问题描述

我尝试了以下代码。

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

运行此函数后,我看到只有一个标签,并且保留了FOO之前分配的线程。FOO并且在运行时不会为“重复标签名称”抛出异常。

这是一个有效的行为吗?可以依靠吗?官方文档没有提到这样的事情。

标签: google-apps-scriptgmail

解决方案


使用已经存在的标签名称调用GmailApp.createLabel()将返回已经存在的标签。它不会对您现有的标签进行任何更改。


根据文档,创建或获取标签的唯一方法是通过标签的名称。重要的是, GmailLabel 类中列出的唯一标识属性是name。因此,我的假设是 Apps Script 正在强制执行名称的唯一性,并且它正在防止覆盖现有标签。

我们可以尝试一个简单的测试。如果存在覆盖保护,则创建新标签可能会删除标签和电子邮件之间的关联。那么让我们看看有哪些邮件出现在某个标签下,新建一个同名标签,看看邮件列表是不是一样。

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
}

结果是它们是相同的,因此证实了createLabel()足够聪明的假设以避免覆盖现有标签。

不过,我们可以走得更远。Gmail API清楚地表明标签有一个 ID。同样,我没有看到标签名称必须唯一的任何要求(尽管我们可以假设最终用户只能与标签名称进行交互——如果存在多个具有相同名称的用户体验将是糟糕的)。

如果您在Advanced Google services中启用 Gmail API ,我们可以测试 API 要求。尝试创建一个与我们已经知道存在的标签同名的新标签。

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

这会导致以下错误,然后确认标签名称必须是唯一的。

对 gmail.users.labels.create 的 API 调用失败并出现错误:标签名称存在或冲突

让我们更进一步。最初,我假设 Apps 脚本可以防止覆盖现有标签。所以让我们检查现有标签的ID,然后GmailApp.createLabel()用相同的标签名称调用,看看是否创建了新标签/标签ID是否更改。

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
  }
}

如您所见,标签 ID 保持不变,这意味着GmailApp.createLabel()确实可以防止覆盖现有标签。


推荐阅读