GmailApp.getMessagesForThreads() returns too many messages

Viewed 261

I want to return a list of all email subjects received at a specified day, at my Gmail account. If there is more than one message with the same subject, I want to have a number of how many there are. This is what I did:

var emailThreads = GmailApp.search("subject:<partial_subject> after:2020/8/30 before:2020/8/31");
var messages = GmailApp.getMessagesForThreads(emailThreads);

This returns "an array of arrays of messages, where each item in the outer array corresponds to a thread and the inner array contains the messages in that thread".

I try to access data I need like this:

for (i = 0; i < messages.length; i++) {
  messages[i][0].getSubject() // a subject
  messages[i].length          // number of messages with the same subject
}

However, this returns more messages than is displayed in Gmail UI.

Here's what I've noticed:

  • it only happens to threads with more than one message
  • it doesn't happen to all threads with more than one message
  • every time a run my script for the same day, the result is the same
  • when I run my script for different days, the result is different even though the same emails were received

Considering that this code is very simple and I'm only using methods delivered by google, I assume I must have misunderstood something or Gmail is doing something weird with messages in threads.

Any ideas what could this be and how to work around it?


Edit: I've noticed that there is a "Don't include chats" checkbox in gmail filter, which adds "-in:chats" into search query, but it didn't help either. I also tried adding "in:inbox" to the query, but with no change in the result.

2 Answers

Explanation:

  • The reason you are getting too many messages is because your current filter criteria does not query only emails but also hangout messages or other threads rather than emails.

  • Use this to get the subjects of all emails:

    var emailThreads = GmailApp.search("is:inbox after:2020/8/30 before:2020/8/31");
    

Solution:

This is how the full code would look like:

function myFunction() {
  
  var emailThreads = GmailApp.search("is:inbox after:2020/8/30 before:2020/8/31");
  var messages = GmailApp.getMessagesForThreads(emailThreads);
  var messageArr = [];
   
  for (i = 0; i < messages.length; i++) {
  Logger.log(messages[i][0].getSubject()) // a subject
  Logger.log(messages[i].length)        // number of messages with the same subject
}
      
  messages.forEach(m=>{
         messageArr.push({
         subject: m[0].getSubject(),
         num_messages:m.length
  })});    
}
  • I also created for you a json array messageArr which contains all the subject names and the number of message for each subject.

From the question

However, this returns more messages than is displayed in Gmail UI.

There might be some reasons for that

  1. Messages in Trash and Spam are not displayend on the search results on the Gmail UI (unless you include in:anywhere, textually)
  2. The UI is not showing all messages because the results might be paged and you missed that
  3. After the receive/import/deletion of a large number of messages there is a noticible delay on getting them displayed on the UI, so even if it looks that you reached the last search results page, wait some minutes and regresh the Gmail webpage.

getMessagesForThreads return messages that might not be shown on the Gmail UI search results because they were sent to the Spam or Trash.

To correctly compare the results from the Gmail UI with the results of this method, on the Gmail UI include in:anywhere as part of your search. The complete search statement will look something like this:

in:anywhere subject:<partial_subject> after:2020/8/30 before:2020/8/31

As mentionend on the first part of this answer, you might have to refresh the Gmail webpage several times to be sure that there aren't messages recently made available through the web UI.

Related

Resources

Related