0

I am trying to set up a very simple script to count the amount of individual emails (not threads) received in Gmail over a specific timeframe. Currently testing with set dates where I know what the individual message count should be.

I have used the following code

function emailCount() {
    var receivedCount = 0;
    var threads = GmailApp.search("to:("my email") after:2023/02/01 before:2023/02/02"); 
    Logger.log(threads.length);

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

    Logger.log(receivedCount);
}

Which returns the correct amount of email threads, but the email count is too high. The script is counting individual emails from the returned threads, even if those emails do not fit my search parameters (i.e. not in my date range).

Is there a way to return an individual email count from a date range, so I can get an accurate count for how many emails were received within a certain date range?

Similar posts have been made about email counts (I got the script from this post- Google Apps Script to count number of emails sent/received yesterday, that has a certain label, then save # daily to spreadsheet) but I can't see how I can achieve the count I am after.

Solved!

Thanks to @Tedinoz for their post below and advice. Amended their code slightly to create a function that generates an email count on a daily basis and saves it in a spreadsheet.

//Not my code! All credit to @Tedinoz and others recognised at the end of the post. 

function emailCount() {

  var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1')

  var startDate = sheet.getRange('C1').getValue(); // the start date of search range

  var endDate = sheet.getRange('E1').getValue(); // the end date of serach range

  Logger.log("DEBUG: Search Start date = "+startDate+",\nSeachEnd date = "+endDate)

   var startDateFormated = formatDate(startDate); // using function to covert date to yyyy/mm/ddd so it can be used in a gmail search. 

  Logger.log ("DEBUG: Formated start date = "+startDateFormated);

  var endDateFormated = formatDate(endDate);// using function to covert date to yyyy/mm/ddd so it can be used in a gmail search.

 Logger.log ("DEBUG: Formated end date = "+endDateFormated);

 Logger.log("to:(henry.ward@york.ac.uk) after:"+startDateFormated+" before:"+endDateFormated); // log of what the gmail search will be


  
  var threads = GmailApp.search("to:(henry.ward@york.ac.uk) after:"+startDateFormated+" before:"+endDateFormated); // gmail search 
  var threadCount = threads.length // pulls threads from search

   var messsageCounter = 0 // sets the message counter as 0

   for (var i=0;i<threadCount;i++){ // loops through the threads to get messages
      var messages = threads[i].getMessages()     
     var messageCount = messages.length
     Logger.log("DEBUG: Number of messages: "+messageCount)
    
     for (var m=0;m<messageCount;m++){ // loops through the messages to get dates
       var messageDate = messages[m].getDate()
       var subject = messages[m].getSubject() // pulls subject for easy debugging
       var sender =messages[m].getFrom() // pulls from as will need to exlude certain senders

      //Compare message date to search parameters. As well as dates needed to exclude emails sent by myself, as these were being included in the message counts from threads. 
      if (startDate.valueOf() <= messageDate.valueOf()&&messageDate.valueOf()<=endDate.valueOf()&&sender.valueOf()!="My name <my email address>"){
         Logger.log("DEBUG: Valid message: message date = "+messageDate+" subject = "+subject+" from = "+sender)
         messsageCounter++
      }
       else{
          Logger.log("DEBUG: Failed message: message date = "+messageDate)
      }
     }
   }
  Logger.log("Number of valid messages = "+messsageCounter)

// last section of script saves returned count into my spreadsheet. I have a trigger for a daily count, so it saves it into the last entry of a column.
//Also not my original code, but cannot find where I originally copied it from! 

  var columnIndex = 8 ; //col h - this is the col where I want to save the email count
  var values = sheet.getRange(1, columnIndex, sheet.getMaxRows()).getValues(); 
  for (var t = 0; t < values.length; t++) {
    if (values[t] == "") {
      var emptyCellIndex = t + 1;
      break;
    }
  }
  sheet.getRange(emptyCellIndex, columnIndex).setValue(messsageCounter);
}

To format the date, so it can be used in a gmail search function, I used the following code from @user3470953. Found as an answer to the post - Format JavaScript date as yyyy-mm-dd


function formatDate(date) {
    var d = new Date(date),
        month = '' + (d.getMonth() + 1),
        day = '' + d.getDate(),
        year = d.getFullYear();

    if (month.length < 2) 
        month = '0' + month;
    if (day.length < 2) 
        day = '0' + day;

    return [year, month, day].join('/');
}


marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Hi and welcome. `search` returns threads - you can't search on messages specifically. But have you considered looping through the threads, using `getMessages()`, then `getDate()`, and count the messages that are in your date range. – Tedinoz Feb 03 '23 at 02:41
  • Related question: [How to filter by messages, not by conversation?](https://webapps.stackexchange.com/a/79120/196152) on WebApps – Tedinoz Feb 03 '23 at 02:43
  • @Tedinoz - thanks for that suggestion! Incorporated that to pull the dates from the individual messages, but not sure how to go about setting up a conditional count to just count the dates in my range. Any advice? – Henry Ward Feb 03 '23 at 09:03

1 Answers1

0

GmailApp.search returns threads. In order to evaluate/identify the specific messages that satisfy the dates in the search query, one must loop through the messages, get the message date, and compare the message date to the "from"/"to" dates of the query.

The following script is an example of looping through the messages recovered from GMail.search. The number of threads returns was 1 (one); the number of messages = 5 (five); however only 2 (two) messages satisfied the criteria for the "from"/"to" dates.


function myFunction() {
  var startDate = new Date(2023, 0, 24); // the month is 0-indexed
  var endDate = new Date(2023, 0, 27); // the month is 0-indexed
  Logger.log("DEBUG: Search Start date = "+startDate+",\nSeachEnd date = "+endDate)
  
  var threads = GmailApp.search("subject:(Britax Safe-n-Sound Compaq AHR) after:2023/1/24 before:2023/1/27"); 
  var threadCount = threads.length

  var messsageCounter = 0
  for (var i=0;i<threadCount;i++){
    var messages = threads[i].getMessages()     
    var messageCount = messages.length
    Logger.log("DEBUG: Number of messages: "+messageCount)
    
    for (var m=0;m<messageCount;m++){
      var messageDate = messages[m].getDate()

      //Compare message date to search parameters
      if ((startDate.valueOf() <= messageDate.valueOf()) ||(messageDate.valueOf()<=endDate.valueOf)){
        Logger.log("DEBUG: Valid message: message date = "+messageDate)
        messsageCounter++
      }
      else{
        Logger.log("DEBUG: Failed message: message date = "+messageDate)
      }
    }
  }
  Logger.log("Number of valid messages = "+messsageCounter)
}

RESULTS

snapshot

Tedinoz
  • 5,911
  • 3
  • 25
  • 35
  • Amazing! Exactly what I was after. Just a few things I changed. The search paramaters were pulling through messages later than the end date and also includedmessages I sent, so I needed to set an additional exemption to exclude them. Will edit my post to include. – Henry Ward Feb 07 '23 at 09:13