Search code examples
google-apps-scriptgmail

Determine Google's Quota - Service invoked too many times for one day: gmail


I received the error "Service invoked too many times for one day: gmail". My script was scanning emails in my spam folder every 1 minute. Due to the error, I have set the script to execute every 10 minutes. I have also set a limit in my script so no more than 10 emails are processed each time the script runs.

My script is permanently deleting emails if key word(s) in the email's body or subject line match. Also, if the email contains an attachment, the email will be deleted.

I am using the consumer version of Gmail. I am trying to determine what the limit is for scanning emails using Google's quota sheet. Would using msg.getPlainBody().match, msg.getSubject().match, and msg.getAttachments().length be considered using the "Email read/write (excluding send)" feature?

Edit: See code below for further details about the calls being made. This is the original code that scanned all emails in the spam folder which caused me to exceed Google's limits. Code has since been modified to scan no more than 10 emails in spam folder.

var threads = GmailApp.search("in:spam");

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

  if (msg.getPlainBody().match(/car|truck|(you won)/gi) !== null) {
      console.log('Msg Delete')
      console.log(i)
      Gmail.Users.Messages.remove('me', msg.getId())
      continue;
  }

  if (msg.getSubject().match(/car|truck|(you won)/gi)  !== null) {
     console.log('Sbj Delete')
     console.log(i)
     Gmail.Users.Messages.remove('me', msg.getId())
     continue;
  }

  if (msg.getAttachments().length > 0) {
     console.log('Attachment Delete')
     console.log(i)
     Gmail.Users.Messages.remove('me', msg.getId())
     continue;
  }    

}

Solution

  • While Google's quota documentation that you linked doesn't specify whether or not performing a method like getSubject() on a GmailMessage counts towards the quota, a test in a bound script suggests that it does not.

    I ran this script in a container bound script and it executed successfully in under 2 minutes.

    function tryToHitQuota() {
      const email = GmailApp.getInboxThreads()[0].getMessages()[0];
      for (let i = 0; i < 50002; i++) {
        email.getPlainBody();
        email.getAttachments();
      }
    }
    

    Since this script succeeded and did not hit the quota, I think that the "read" referred to in the quota documentation means reading a gmail message, not calling class methods on the message that is returned.

    Looking at the code you shared, I see you're reading all of the messages from all of the threads in spam. That is potentially reading enough messages to make you hit your quota. You might want to implement some rate limiting in that function. For example, you could keep track of the messages that you've already visited, and skip over those. And you could change for (let i = 0; i < threads.length; ...) to for (let i = 0; i < numberLessThanQuota; ...)