1

I'm using a script to forward a long list of emails (under one label) to a new account. However, I'm hitting a exceeded maximum execution time error not even quarter way through. I was wondering if there was a workaround, maybe a possibility to store the variables on the sheet and resume after a set time? I'm not too well versed in coding so any help on this would be appreciated.

function forwardMail() {
  var data = SpreadsheetApp.getActiveSheet().getRange("A2:B11").getValues();
  for (i in data) {
    var row = data[i];
    var name = row[0].toString();
    var email = row[1].toString();
    var label = GmailApp.getUserLabelByName(name);
    if (label && (email != "")) {
      var threads = label.getThreads();
      for (var x in threads) {
        var messages = threads[x].getMessages();
        for (var y in messages) {
          var subject = messages[y].getSubject();
          messages[y].forward(email, {
            subject: subject});
        }
        threads[x].removeLabel(label);
      }
    }
  }
}
Xenox Dissanayake
  • 273
  • 1
  • 3
  • 14
  • one way is to make the code asynchronous - though, I'm surprised that `messages[y].forward` isn't asynchronous! Also, it's a little tricky though with that `threads[x].removeLabel(label);` after the `y in` loop ... I think [this pastebin](https://pastebin.com/pPRQxsbx) is a very asynchronous solution that still calls `message.forward` in sequence – Jaromanda X Jul 16 '18 at 08:56
  • 3
    Keep in mind that there's also a quota for number of emails that you can send. – TheMaster Jul 16 '18 at 11:20
  • 1
    Possible duplicate of [Exceeded maximum execution time in Google Apps Script](https://stackoverflow.com/questions/7854573/exceeded-maximum-execution-time-in-google-apps-script) – Rubén Jul 16 '18 at 14:07
  • If you processing rows from a spreadsheet, then it is possible to set a flag to indicate a row is completed. You can then process a set number of records and then continue from the last flag. Will post some script below in the answer for you to have a look. – New_2_Code Jul 16 '18 at 14:24
  • Possible duplicate of [Google Apps Script Class GmailApp Batch Operations?](https://stackoverflow.com/questions/12029027/google-apps-script-class-gmailapp-batch-operations) – TheMaster Jul 16 '18 at 18:16

1 Answers1

0

This script should process one line in your spreadsheet during execution. On the following execution it will run the next line and so on. It could still use some work, but it's a good place start and hopefully conveys the idea I have for you to circumvent the maximum execution time.

The idea here is you set a value in column C to indicate that a record has been processed already. When the script runs again, it then continues from the next record. Still needs some functionally to stop it from attempting to run blank rows. But I am sure you can work that in.

Once you got those minor issues sorted out you can put this on a trigger to run every 1 or 5 minutes. (Depending on how long execution time is.)

This is how I have beaten the execution time in the past. As always, hope this helps.

function forwardMail() {

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();

var rowsToProcess = sheet.getRange("C2:C").getValues();
var rowCounter = rowsToProcess.filter(String).length +1;

for (var index = rowCounter; index = rowCounter +1; index++){
var data = sheet.getRange(index, 1, 1, 2).getValues();
var name = data[0].toString();
var email = data[1].toString();

var label = GmailApp.getUserLabelByName(name);
if (label && (email != "")) {
var threads = label.getThreads();

for (var x in threads) {
var messages = threads[x].getMessages();

for (var y in messages) {
var subject = messages[y].getSubject();
messages[y].forward(email, {subject: subject});
} //End of Y for loop

threads[x].removeLabel(label);
} //End of X for loop
} //End of IF statement
} //End of INDEX for loop

sheet.getRange(index, 3, 1, 1).setValue("Mails Processed");
} //End of Function
New_2_Code
  • 330
  • 2
  • 18