3
votes

Is it possible to search to messages with the label 'Apps script queue' and give just these specific messages (not the whole thread) a new label?

When I use GmailApp.search('label:Apps script queue') I get the requested messages but when I assign a new label to these messages, all the other messages of the thread (on other places in the mailbox) will get the same label. And that is not what I want.

3

3 Answers

1
votes

This code does not return an error while adding a label to a specific message in a thread and if you use thread list method you'll see that it is only placed in the specific messageID(treated separately). But once your UI(Gmail site) is in conversation mode, it will be viewable in both labels.

function searchMail(){
  var threads = GmailApp.search("SOME SEARCH");
  Logger.log(threads.length);
  listLabel('me');
  for (var i = 0; i < threads.length; i++) {
    var messages = threads[i].getMessages();
    Logger.log(messages.length);

    for (var j = 0; j < messages.length; j++){
      if (messages[j].isInInbox()){
        Logger.log('me' + 'id msg: ' + messages[j].getId());
        //Add label to the first reply
        addLabel('me',messages[1].getId());
      }
      else{
       Logger.log('me' + 'id msg: ' + messages[j].getId() +" not in inbox");
      }
    }
  }
}

function addLabel(userId, messageId){

  var resource = {addLabelIds: ["Label_6"]}

  Gmail.Users.Messages.modify(resource, userId, messageId);

}
0
votes

In Gmail, labels are applied to a thread and cannot be applied to a single email message of a thread.

You can however apply stars / colors to individual messages.

0
votes

This is an old thread, but for anybody who might be reading it like me, maybe this will save you some time:

function getLabelMap() {
  var allLabels = Gmail.Users.Labels.list('me');
  var labelMap = [];

  for (var label of allLabels.labels) {
    labelMap[label.name] = label.id;
  }
  
  return labelMap;
}

var labelMap = getLabelMap();

function getLabel(labelName) {
  return labelMap[labelName];
}

function labelMessage(messageID, labelName) {
  var labelID = getLabel(labelName);
  var labelRequest = {addLabelIds: [labelID]};
  var subject = GmailApp.getMessageById(messageID).getSubject();

  if (labelID != null) {
    Logger.log("Labelling as %s: %s", labelName, subject);
    Gmail.Users.Messages.modify(labelRequest, 'me', messageID);
  } else {
    Logger.log("Label not found: %s", labelName);
  }
}

function unlabelMessage(messageID, labelName) {
  var labelID = getLabel(labelName);
  var labelRequest = {removeLabelIds: [labelID]};
  var subject = GmailApp.getMessageById(messageID).getSubject();

  if (labelID != null) {
    Logger.log("Removing label %s: %s", labelName, subject);
    Gmail.Users.Messages.modify(labelRequest, 'me', messageID);
  } else {
    Logger.log("Label not found: %s", labelName);
  }
}

function reLabel () {

  var messagesToRelabel = Gmail.Users.Messages.list('me', {'q':'label:Apps-script-queue'}).messages || [];

  // Loop through each message (not by thread), using the Advanced Gmail Service (full GMail API in a Google Script).
  messagesToRelabel.forEach(function (messageToRelabel){
    unlabelMessage(messageToRelabel.id, "Apps script queue");
    labelMessage(messageToRelabel.id, "New label");
  });

}

Not asked for by the OP, but may be helpful for others who are trying to do "advanced filtering / labeling" using the GMail API:

function getMessageHeader(messageID, headerField) {
  var messageInfo = Gmail.Users.Messages.get('me', messageID, {'format':'METADATA', 'metadataHeaders':[headerField]});

  if (messageInfo.payload.headers) {
    return messageInfo.payload.headers[0].value;
  } else {
    return null;
  }
}

The above lets you filter on header info, e.g. I use it to check whether X-Uniform-Type-Identifier is equal to com.apple.mail-note to automatically flag old Apple Notes for deletion.