4
votes

Using google script for google mail, I'm trying to upload new emails with certain labels to our CRM using an API. I can't check if messages have been uploaded already, so I have to apply a label in the mailbox to messages that have been processed before.

Unfortunately, google script only lets you add or check labels on a thread level. Since new messages can come in for a thread after it has last been uploaded to the CRM, I don't know what messages of a thread have actually been processed already.

The Code below contains what I had in mind, the function getLabels does not work for Message however so it does not work.

Hope somebody has a smart solution!

Thanks

//execute main sequence
function collecttobesend() {
    var labeladd = GmailApp.getUserLabelByName("add to CRM");
    var labeladded = GmailApp.getUserLabelByName("added to CRM");
    //var threads = label.getThreads();
    var threads = GmailApp.search('label:added-to-crm -label:add-to-crm')

    for (var i = 0; i < threads.length; i++) {
        thread = threads[i];

        // get all messages in a given thread
        var messages = thread.getMessages();

        // iterate over each message
        for (var j = 0; j < messages.length; j++) {
            message = messages[j];
            var labels = message.getLabels();
            var messagehaslabeladded = false;

            for (var k = 0; k < labels.length; k++) {
                if (labels[k] = labeladded) {
                    messagehaslabeladded = true;
                }
            }

            // if message has not been added yet
            if (messagehaslabeladded = false) {
                var success = false;

                //add to CRM through API
                success = true;

                //if succesfull add label
                if (success = true) {
                    message.addLabel(labeladded);
                }
            }
        }
    }
2
I just encountered the same problem. And then found a contradictory statement on the Gmail search query help > Note: Labels are only added to a message, and not an entire > conversation My experience is directly the opposite, the API only allows me to get labels at the conversation level, not the individual message level. I'll try to get someone from Support to comment - Le Stephane
Got a notification of your comment. I actually found a solution, see answer below. - John Willson

2 Answers

0
votes

Tricky.

Your problem as I see it is twofold.

1) If a thread receives a response after the 'added to CRM' label has been applied, then that new message won't even trigger the check if it needs to be added, as it will never have 'add to CRM' applied.

2) It won't be able to tell the difference between the messages in the thread that have been added, and the messages that still need to be added.

This isn't a particularly elegant solution, but with regards to 1), there's a cumbersome yet workable solution. You can set a script to check for messages in the inbox using .getInboxThreads() to check something like:

 // if message might have been updated
    if (messageHasLabelAdded == true && messageIsInInbox == True) {
       //Iterate through again to index the new messages
 }

Having this run every few minutes should catch any new messages in the thread, but it relies heavily on your users 'Archiving' a message once they're done.

With 2) are you able to get/post metadata with your CRM? If so, you can always get the messages ID using getId(). This is a unique property, so if it can be associated with the message in your CRM, it's just a question of comparing the ID with the IDs in your CRM and checking if a message with that ID is already uploaded.

That could get cubersome once you have several thousand messages uploaded to your CRM, but it might be the start you need.

0
votes

I actually found a solution. As Le Stephane commented, the google notes state that labels are added to messages, and this is true. However, adding and removing labels is done on a thread level to all messages in the thread at once.

Hence the solution is to have two labels: 'to-add' and 'added'. Run a second script that removes the 'to-add' label from a thread (and all messages in the thread that had the label) and immediately adds the label again (to ALL messages in the thread).

This has the effect that all messages in a thread, old and new, have the label 'to-add', and only old messages have the label 'added'. You can now search for messages with the label 'to-add' but not the label 'added'. After the api has added these messages to the crm, you add the label 'added' to the thread and hence all messages in the thread.

Messages that come in after the script ran are in the thread with these labels, but don't have the labels attached to the message itself, and hence the above two step approach works.