Time-consuming tasks and Google Apps Script Add-ons

Post date: Nov 02, 2014 4:17:54 PM

More and more people are using Yet Another Mail Merge and recently I started to receive complains from users who were facing a "Maximum time exceeded" issue. That's understandable as an Apps Script process on Google servers can only run for a maximum of 6 minutes. So if you are trying to send 1500 emails, maybe with different attachments, inline images,... there's a lot of chances YAMM won't have time to process all that in 6 minutes.

Developers, rejoice!

In fact, it is very easy to overcome that limit, simply by going back and forth between the server and the client side in your add-on.

Let's take an example:

I want to list all my Drive files in a Google Sheet. I don't know exactly the number of files I have in Drive (not even sure I'll be able to list them all in a Sheet) but I do know I won't be able to list them all in one server-side script execution (6 minutes).

So I simply ask Google servers to process a very small batch (only 10 files) then go back to the client side and use a Javascript function to call the server again and process a new batch. Each time I call again the server side from the client side, the timer is reset and I never get close to the 6 minutes limit, while being able to run a script for hours if I want to!

function onSuccess(continuationToken){

// If server function returned a continuationToken it means the task is not complete

// so ask the server to process a new batch.

if(continuationToken) {

var nbOfFilesProcessedEl = document.getElementById("nbOfFilesProcessed");

nbOfFilesProcessedEl.innerHTML = parseInt(nbOfFilesProcessedEl.innerHTML) + 10;

google.script.run.withSuccessHandler(onSuccess).getDriveFiles(continuationToken);

}

}

Try it

If you want to try, you can make a copy of this Sheet, which contains a small Apps Script code to list all files from your Google Drive. Simply open the sidebar, click on the start button and the script will run and list all your files, without a care for the 6 minutes limitation. Of course, if you close the sidebar or the Sheet, you'll stop the script execution (you'll stop all client side execution and thus no more instructions will be sent to Google servers).

Here's also the code:

Code.gs

function onOpen() {

SpreadsheetApp.getUi().createMenu("List Drive files").addItem('Start', 'start').addToUi();

}

function start() {

var ui = HtmlService.createHtmlOutputFromFile('ui');

return SpreadsheetApp.getUi().showSidebar(ui);

}

function getDriveFiles(continuationToken) {

if(continuationToken) {

var files = DriveApp.continueFileIterator(continuationToken);

}

else {

var files = DriveApp.getFiles();

}

var i = 0;

while (files.hasNext() && i < 10) {

var file = files.next();

SpreadsheetApp.getActiveSheet().appendRow([file.getName(), file.getUrl()]);

i++;

if(i == 10) {

return files.getContinuationToken();

}

}

}

ui.html

<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">

<div style="text-align:center; margin-top:10px">

<div>Files processed:</div>

<div id="nbOfFilesProcessed">0</div>

<br>

<button id="startButton" class="blue" onclick="start()">Start</button>

<div class="secondary">Close the sidebar to stop the script.</div>

</div>

<script>

function start() {

document.getElementById("startButton").disabled = true;

google.script.run.withSuccessHandler(onSuccess).getDriveFiles();

}

function onSuccess(continuationToken){

// If server function returned a continuationToken it means the task is not complete

// so ask the server to process a new batch.

if(continuationToken) {

var nbOfFilesProcessedEl = document.getElementById("nbOfFilesProcessed");

nbOfFilesProcessedEl.innerHTML = parseInt(nbOfFilesProcessedEl.innerHTML) + 10;

google.script.run.withSuccessHandler(onSuccess).getDriveFiles(continuationToken);

}

}

</script>

Starting today, people using Yet Another Mail Merge will never face again this "Maximum time exceeded" issue. All add-ons doing mail merging tasks, listing a lot of information (all people from the Google Apps directory, all Drive files, all Google Sites on a Google Apps domain etc.) or whatever other time consuming task can use this method to be more efficient and play well within the constraints of the platform.