GmailApp - 将标签添加到特定的消息,而不是线程 [英] GmailApp - Add label to specific message, not the thread

查看:196
本文介绍了GmailApp - 将标签添加到特定的消息,而不是线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个脚本,以自动将我的电子邮件从一个标签移动到下一个标签(因此标有5天标签的邮件将自动标记为4天,然后 3天后,等等)。

问题是它将标签应用于整个线程,而不仅仅是消息 - 这是有问题的您已关闭对话视图,并将不同标签下的各种电子邮件分开。



以下是我的脚本(每日触发器):

  function moveUp(previousLabel,newLabel){
var threads = GmailApp.getUserLabelByName(previousLabel).getThreads()
var numThreads = threads。 ((var i = 0; i< numThreads; i ++){

if(GmailApp.getUserLabelByName(previousLabel).getThreads())获得长度为
的if(numThreads> 0) ).length> 0){
var lastThread = GmailApp.getUserLabelByName(previousLabel).getThreads()[0]
GmailApp.getUserLabelByName(newLabel).addToThread(lastThread.markUnread());
GmailApp.getUserLabelByName(previousLabel).removeFromThread(lastThread)
Utilities.sleep(200)
} else {
{break;}
}
}



function myFunction(){
var threads = GmailApp.getUserLabelByName( - To Do / 1 Day)。getThreads()$ b $ (var i = 0; i< numThreads; i ++){

if(GmailApp.getUserLabelByName){b $ var bThreads = threads.length
if(numThreads> 0) (-To Do / 1 Day)。getThreads()。length> 0){
var lastThread = GmailApp.getUserLabelByName( - To Do / 1 Day)。getThreads()[0]
lastThread.moveToInbox()。markUnread();
GmailApp.getUserLabelByName( - To Do / 1 Day)。removeFromThread(lastThread)
Utilities.sleep(200)
} else {
{break;}
}
}
}
moveUp( - 待办/ 2天, - 待办/ 1天)
moveUp( - 待办/ 3天 , - 要做/ 2天)
moveUp( - 要做/ 4天,要做/ 3天)
moveUp( - 要做/ 5天 - 要做/ 4天)
}

那么有谁知道如何只应用标签到特定的消息?或解决方案来实现相同的结果?



谢谢

解决方案

您可以使用 GMail API 代替。您需要为您的项目启用API。在编辑器中,选择资源>高级Google服务,然后点击这些服务也必须在 Google开发者控制台中启用。在这里,启用GMail API。



modifyMessage



使用示例:




$ b

  modifyMessage('me',messageId,['stack','overflow']); //添加两个标签
modifyMessage('me',messageId,null,['stack','overflow']); //删除两个标签

TL; DR 完整的代码可用<一个href =https://gist.github.com/mogsdad/6515581#label-a-message =noreferrer>在这个要点中,下面是隐藏的代码片段。



  / ** *修改与消息关联的标签。 *如果不成功则抛出。 *请参阅https://developers.google.com/gmail/api/v1/reference/users/messages/modify * * @param {String} userId用户的电子邮件地址。特殊值'me'*可用于指示已验证的用户。 * @param {String} messageId要修改的消息的ID。 * @param {String []} labelsToAdd要添加的标签名称的数组。 * @param {String []} labelsToRemove要移除的标签名称数组。 * * @returns {Object} Users.messages资源,请参阅参考资料。 * / function modifyMessage(userId,messageId,labelsToAdd,labelsToRemove){labelsToAdd = labelsToAdd || []; labelsToRemove = labelsToRemove || []; //请参阅https://developers.google.com/gmail/api/v1/reference/users/messages/modify var url ='https://www.googleapis.com/gmail/v1/users/${userId} / messages / $ {id} / modify'.replace($ {userId},me).replace($ {id},messageId); var headers = {Authorization:'Bearer'+ ScriptApp.getOAuthToken()}; var addLabelIds = []; for(var i = 0; i< labelsToAdd.length; i ++){addLabelIds [i] = getLabelId(labelsToAdd [i]); } var removeLabelIds = []; for(var i = 0; i< labelsToRemove.length; i ++){removeLabelIds [i] = getLabelId(labelsToRemove [i],false); } var request = {'addLabelIds':addLabelIds,'removeLabelIds':removeLabelIds}; var params = {method:post,contentType:application / json,headers:headers,payload:JSON.stringify(request),muteHttpExceptions:true}; // var check = UrlFetchApp.getRequest(url,params); //用于调试var response = UrlFetchApp.fetch(url,params); var result = response.getResponseCode(); if(result =='200'){// OK return JSON.parse(response.getContentText()); } else {//仅当muteHttpExceptions == true时才需要var err = JSON.parse(response.getContentText());抛出新的错误('错误('+结果+)+ err.error.message); }} / ** *获取给定LabelName的标签ID。如果未找到标签,将根据ok2Create的状态创建*。 *如果不成功则抛出。 *请参阅https://developers.google.com/gmail/api/v1/reference/users/messages/modify。 * * @param {String} labelName要检索标识的标签的名称。 * @param {Boolean} ok2Create(可选)如果找不到标签,则设置为true。 *默认为true。 * * @returns {String}标签的ID,如果未找到或创建,则返回null。 * / function getLabelId(labelName,ok2Create){if(typeof ok2Create =='undefined')ok2Create = true; var id = null; //请参阅https://developers.google.com/gmail/api/v1/reference/users/labels/list var url ='https://www.googleapis.com/gmail/v1/users/${userId} / labels'.replace($ {userId},me)//用户的电子邮件地址。我的特殊价值可以用来指示已认证的用户。 var headers = {Authorization:'Bearer'+ ScriptApp.getOAuthToken()}; var params = {method:get,contentType:application / json,headers:headers,muteHttpExceptions:true}; // var check = UrlFetchApp.getRequest(url,params); //用于调试var response = UrlFetchApp.fetch(url,params); var result = response.getResponseCode(); if(result =='200'){// OK var labels = JSON.parse(response.getContentText())。labels; var found = false; for(var i = 0; i< labels.length&!found; i ++){if(labels [i] .name == labelName){found = true; id = labels [i] .id; (!found&& ok2Create){id = createLabel(labelName);} } return id; } else {//仅当muteHttpExceptions == true时才需要var err = JSON.parse(response.getContentText());抛出新的错误('错误('+结果+)+ err.error.message); }} / ** *为给定的`labelName`创建标签。 *如果不成功则抛出。 *请参阅https://developers.google.com/gmail/api/v1/reference/users/messages/modify。 * * @param {String} labelName要创建的标签的名称* * @returns {String}标签的标识。 * / function createLabel(labelName){var id = null; //请参阅https://developers.google.com/gmail/api/v1/reference/users/labels/create var url ='https://www.googleapis.com/gmail/v1/users/${userId} / labels'.replace($ {userId},me)//用户的电子邮件地址。我的特殊价值可以用来指示已认证的用户。 var headers = {Authorization:'Bearer'+ ScriptApp.getOAuthToken()}; var request = {'name':labelName}; var params = {method:post,contentType:application / json,headers:headers,payload:JSON.stringify(request),muteHttpExceptions:true}; // var check = UrlFetchApp.getRequest(url,params); //用于调试var response = UrlFetchApp.fetch(url,params); var result = response.getResponseCode(); if(result =='200'){// OK var label = JSON.parse(response.getContentText()); id = label.id;返回ID; } else {//仅当muteHttpExceptions == true时才需要var err = JSON.parse(response.getContentText());抛出新的错误('错误('+结果+)+ err.error.message); 
$ b

 

/ **
*修改消息关联的标签。
*如果不成功则抛出。
*请参阅https://developers.google.com/gmail/api/v1/reference/users/messages/modify
*
* @param {String} userId用户的电子邮件地址。特殊值'我'
*可用于指示已验证的用户。
* @param {String} messageId要修改的消息的ID。
* @param {String []} labelsToAdd要添加的标签名称的数组。
* @param {String []} labelsToRemove要移除的标签名称数组。
*
* @returns {Object} Users.messages资源,请参阅参考资料。
* /
函数modifyMessage(userId,messageId,labelsToAdd,labelsToRemove){
labelsToAdd = labelsToAdd || [];
labelsToRemove = labelsToRemove || [];
//请参阅https://developers.google.com/gmail/api/v1/reference/users/messages/modify
var url ='https://www.googleapis.com/gmail/ v1 / users / $ {userId} / messages / $ {id} / modify'
.replace($ {userId},me)
.replace($ {id}, messageId);

GMail API是一个RESTful API,可以更加灵活和详细地访问线程,消息,标签,草稿,以及使用内置的GMailApp服务提供的历史记录。从我们的脚本中,我们通过URL访问API - 在这里,我们首先填写修改消息方法的基本URL中的详细信息。



授权:'Bearer'+ ScriptApp.getOAuthToken()
};


除了为我们的项目启用API外,每个请求都需要用户身份验证,这是通过嵌入在命令头中有一个不记名令牌



接下来,我们将构建其余的命令参数。

  var addLabelIds = []; 
for(var i = 0; i< labelsToAdd.length; i ++){
addLabelIds [i] = getLabelId(labelsToAdd [i]);
}
var removeLabelIds = [];
for(i = 0; i< labelsToRemove.length; i ++){
removeLabelIds [i] = getLabelId(labelsToRemove [i],false);
}
var request = {
'addLabelIds':addLabelIds,
'removeLabelIds':removeLabelIds
};

modify 的规范要求 POST 操作,其中有效载荷包含标签ID列表。这些ID不能通过内置的GMail服务获得,所以我们也会使用GMail API - getLabelId()是另一个类似于这个的函数,专门用于用于按名称检索标签的ID,并根据需要创建新标签。
$ b

var params = {
method: post,
contentType:application / json,
headers:headers,
payload:JSON.stringify(request),
muteHttpExceptions:true
};
// var check = UrlFetchApp.getRequest(url,params); //用于调试
var response = UrlFetchApp.fetch(url,params);

最后,我们组装了 params 对象该命令的属性包含和我们的认证令牌,有效载荷带有命令参数, stringify -d用于传输。设置 muteHttpExceptions:true 在出现故障时压制系统生成的异常,以便我们自己处理。

我已经注释到 UrlFetchApp.getRequest()的调用 - 在发送命令之前验证命令的内容很方便。



UrlFetchApp.fetch()的调用将我们的命令传递给在我们建立的顶级URL上运行的服务。

  var result = response.getResponseCode(); 
if(result =='200'){// OK
return JSON.parse(response.getContentText());
}

收到回复时,我们首先检查结果,该命令采用 HTTP状态代码。一个 200 OK 告诉我们我们很成功,所以我们继续前进,并将结果从响应中提取出来。 JSON.parse()变成 JSON字符串在消息中转换成一个JavaScript对象,我们返回给调用者。


$ b

  else {
//只有当muteHttpExceptions == true时才需要
var err = JSON.parse(response.getContentText());
抛出新错误('Error('+ result +)+ err.error.message);






如果我们遇到错误,自己的例外。根据命令的细节,我们可能想要以不同的方式处理特定的错误。例如,在修改命令中,如果我们提供了一个不存在的标签ID,我们将收到一个错误消息:


错误:错误(400)无效标签:无效标签



I'm building a script to automatically move my emails from one label to the next on a day by day basis (so that a message that is stored labelled "5 days" will automatically be labelled "4 days" tomorrow then "3 days" the day after that, and so on).

The problem is that it applies the label to the entire thread, not just the message - which is problematic if you have Conversation View turned off and the various emails seperated under different labels.

Here is my script (which has a daily trigger):

function moveUp(previousLabel, newLabel) {
  var threads = GmailApp.getUserLabelByName(previousLabel).getThreads()
  var numThreads = threads.length
  if (numThreads>0) {
    for(var i = 0; i < numThreads; i++) {

      if(GmailApp.getUserLabelByName(previousLabel).getThreads().length>0) {
        var lastThread = GmailApp.getUserLabelByName(previousLabel).getThreads()[0]
        GmailApp.getUserLabelByName(newLabel).addToThread(lastThread.markUnread());
        GmailApp.getUserLabelByName(previousLabel).removeFromThread(lastThread)
        Utilities.sleep(200)
      } else {
        {break;}
      }
    }
  }
}

function myFunction() {
  var threads = GmailApp.getUserLabelByName("-To Do/1 Day").getThreads()
  var numThreads = threads.length
  if (numThreads>0) {
    for(var i = 0; i < numThreads; i++) {

      if(GmailApp.getUserLabelByName("-To Do/1 Day").getThreads().length>0) {
        var lastThread = GmailApp.getUserLabelByName("-To Do/1 Day").getThreads()[0]
        lastThread.moveToInbox().markUnread();
        GmailApp.getUserLabelByName("-To Do/1 Day").removeFromThread(lastThread)
        Utilities.sleep(200)
      } else {
        {break;}
      }
    }
  }
    moveUp("-To Do/2 Days", "-To Do/1 Day")
    moveUp("-To Do/3 Days", "-To Do/2 Days")
    moveUp("-To Do/4 Days", "-To Do/3 Days")
    moveUp("-To Do/5 Days", "-To Do/4 Days")
}

So does anyone know how to only apply the labels to specific messages? Or a workaround to achieve that same result?

Thanks

解决方案

You can do this using the GMail API instead. You need to enable the API for your project. In the editor, select Resources > Advanced Google services, then click on "These services must also be enabled in the Google Developers Console." There, enable the GMail API.

modifyMessage

Example of use:

modifyMessage('me', messageId, ['stack','overflow']);       // add two labels
modifyMessage('me', messageId, null, ['stack','overflow']); // remove two labels

TL;DR The full code is available in this gist, and below in a hidden code snippet.

/**
 * Modify the Labels a Message is associated with.
 * Throws if unsuccessful.
 * see https://developers.google.com/gmail/api/v1/reference/users/messages/modify
 *
 * @param  {String} userId           User's email address. The special value 'me'
 *                                   can be used to indicate the authenticated user.
 * @param  {String} messageId        ID of Message to modify.
 * @param  {String[]} labelsToAdd    Array of Label names to add.
 * @param  {String[]} labelsToRemove Array of Label names to remove.
 *
 * @returns {Object}                 Users.messages resource, see reference. 
 */
function modifyMessage(userId, messageId, labelsToAdd, labelsToRemove) {
  labelsToAdd = labelsToAdd || [];
  labelsToRemove = labelsToRemove || [];
  // see https://developers.google.com/gmail/api/v1/reference/users/messages/modify
  var url = 'https://www.googleapis.com/gmail/v1/users/${userId}/messages/${id}/modify'
            .replace("${userId}","me")
            .replace("${id}", messageId );
  var headers = {
    Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
  };
  var addLabelIds = [];
  for (var i=0; i<labelsToAdd.length; i++) {
    addLabelIds[i] = getLabelId( labelsToAdd[i] );
  }
  var removeLabelIds = [];
  for (var i=0; i<labelsToRemove.length; i++) {
    removeLabelIds[i] = getLabelId( labelsToRemove[i], false );
  }
  var request = {
    'addLabelIds': addLabelIds,
    'removeLabelIds': removeLabelIds
  };
  var params = {
    method: "post",
    contentType: "application/json",
    headers: headers,
    payload: JSON.stringify(request),
    muteHttpExceptions: true
  };
  //var check = UrlFetchApp.getRequest(url, params); // for debugging
  var response = UrlFetchApp.fetch(url, params);

  var result = response.getResponseCode();
  if (result == '200') {  // OK
    return JSON.parse(response.getContentText());
  }
  else {
    // This is only needed when muteHttpExceptions == true
    var err = JSON.parse(response.getContentText());
    throw new Error( 'Error (' + result + ") " + err.error.message );
  }
}

/**
 * Get the Label ID for the given LabelName. If Label isn't found, it will be created
 * depending on the state of ok2Create.
 * Throws if unsuccessful.
 * See https://developers.google.com/gmail/api/v1/reference/users/messages/modify.
 *
 * @param {String}   labelName        Name of label to retrieve ID for.
 * @param {Boolean}  ok2Create        (optional) Set true if a label should be created when not found.
 *                                    Default is true.
 *
 * @returns {String}                  ID of Label, or null if not found or created.
 */
function getLabelId( labelName, ok2Create ) {
  if (typeof ok2Create == 'undefined') ok2Create = true;
  
  var id = null;
  // see https://developers.google.com/gmail/api/v1/reference/users/labels/list
  var url = 'https://www.googleapis.com/gmail/v1/users/${userId}/labels'
            .replace("${userId}","me")  // The user's email address. The special value me can be used to indicate the authenticated user.
  var headers = {
    Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
  };
  var params = {
    method: "get",
    contentType: "application/json",
    headers: headers,
    muteHttpExceptions: true
  };
  
  //var check = UrlFetchApp.getRequest(url, params); // for debugging
  var response = UrlFetchApp.fetch(url, params);

  var result = response.getResponseCode();
  if (result == '200') {  // OK
    var labels = JSON.parse(response.getContentText()).labels;
    var found = false;
    for (var i=0; i<labels.length & !found; i++) {
      if (labels[i].name == labelName) {
        found = true;
        id = labels[i].id;
      }
    }
    if (!found && ok2Create) {
      id = createLabel( labelName );
    }
    return id;
  }
  else {
    // This is only needed when muteHttpExceptions == true
    var err = JSON.parse(response.getContentText());
    throw new Error( 'Error (' + result + ") " + err.error.message );
  }
}

/**
 * Create Label for given `labelName`.
 * Throws if unsuccessful.
 * See https://developers.google.com/gmail/api/v1/reference/users/messages/modify.
 *
 * @param {String}   labelName        Name of label to create
 *
 * @returns {String}                  ID of Label.
 */
function createLabel( labelName ) {
  var id = null;
  // see https://developers.google.com/gmail/api/v1/reference/users/labels/create
  var url = 'https://www.googleapis.com/gmail/v1/users/${userId}/labels'
            .replace("${userId}","me")  // The user's email address. The special value me can be used to indicate the authenticated user.
  var headers = {
    Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
  };
  var request = {
    'name': labelName
  };
  var params = {
    method: "post",
    contentType: "application/json",
    headers: headers,
    payload: JSON.stringify(request),
    muteHttpExceptions: true
  };
  
  //var check = UrlFetchApp.getRequest(url, params); // for debugging
  var response = UrlFetchApp.fetch(url, params);

  var result = response.getResponseCode();
  if (result == '200') {  // OK
    var label = JSON.parse(response.getContentText());
    id = label.id;
    return id;
  }
  else {
    // This is only needed when muteHttpExceptions == true
    var err = JSON.parse(response.getContentText());
    throw new Error( 'Error (' + result + ") " + err.error.message );
  }
}

/**
 * Modify the Labels a Message is associated with.
 * Throws if unsuccessful.
 * see https://developers.google.com/gmail/api/v1/reference/users/messages/modify
 *
 * @param  {String} userId           User's email address. The special value 'me'
 *                                   can be used to indicate the authenticated user.
 * @param  {String} messageId        ID of Message to modify.
 * @param  {String[]} labelsToAdd    Array of Label names to add.
 * @param  {String[]} labelsToRemove Array of Label names to remove.
 *
 * @returns {Object}                 Users.messages resource, see reference. 
 */
function modifyMessage(userId, messageId, labelsToAdd, labelsToRemove) {
  labelsToAdd = labelsToAdd || [];
  labelsToRemove = labelsToRemove || [];
  // see https://developers.google.com/gmail/api/v1/reference/users/messages/modify
  var url = 'https://www.googleapis.com/gmail/v1/users/${userId}/messages/${id}/modify'
            .replace("${userId}","me")
            .replace("${id}", messageId );

The GMail API is a RESTful API with more flexible and detailed access to Threads, Messages, Labels, Drafts, and History than is provided using the built-in GMailApp Service. From our script, we access the API by URLs - here, we start by filling in details in the base URL for the modify Message method.

  var headers = {
    Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
  };

In addition to enabling the API for our project, each request requires user authentication, which is done by embedding a Bearer Token in the command header.

Next, we will build the rest of the command parameters.

  var addLabelIds = [];
  for (var i=0; i<labelsToAdd.length; i++) {
    addLabelIds[i] = getLabelId( labelsToAdd[i] );
  }
  var removeLabelIds = [];
  for (i=0; i<labelsToRemove.length; i++) {
    removeLabelIds[i] = getLabelId( labelsToRemove[i], false );
  }
  var request = {
    'addLabelIds': addLabelIds,
    'removeLabelIds': removeLabelIds
  };

The specification for modify calls for a POST operation, with a payload containing lists of Label IDs. Those IDs are not available through the built-in GMail Service, so we'll also use the GMail API for that - getLabelId() is another function similar to this one, specialized for retrieving the ID of labels by name, and creating new labels as needed. See the gist or snippet for that code.

  var params = {
    method: "post",
    contentType: "application/json",
    headers: headers,
    payload: JSON.stringify(request),
    muteHttpExceptions: true
  };
  //var check = UrlFetchApp.getRequest(url, params); // for debugging
  var response = UrlFetchApp.fetch(url, params);

Finally, we have assembled the params object for the command, with properties containing the headers with our authentication token, and payload with the command parameters, stringify-d for transport. Setting muteHttpExceptions: true squelches system-generated exceptions in case of failure, so that we can handle them ourselves.

I've commented out a call to UrlFetchApp.getRequest() - it's handy for validating the content of a command before sending it.

The call to UrlFetchApp.fetch() transmits our command to the service running at the URL we built up top.

  var result = response.getResponseCode();
  if (result == '200') {  // OK
    return JSON.parse(response.getContentText());
  }

When a response is received, we first check the result of the command, which is in the form of an HTTP Status Code. A 200 OK tells us that we were successful, so we go ahead and pull our result out of the response. JSON.parse() turns the JSON string in the message into a JavaScript object, which we return to the caller.

  else {
    // This is only needed when muteHttpExceptions == true
    var err = JSON.parse(response.getContentText());
    throw new Error( 'Error (' + result + ") " + err.error.message );
  }
}

If we encountered an error, though, we throw our own exception. Depending on the details of a command, we may want to handle specific errors differently. For example, on this modify command, if we provide a Label ID that does not exist, we will receive an error:

Error: Error (400) Invalid label: "Invalid-label"

这篇关于GmailApp - 将标签添加到特定的消息,而不是线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆