Snippets · 12 functions
Triggers and script control snippets
Short functions that install or remove triggers, remember a value between runs, stop two runs from overlapping, and email you when a function fails.
How to use these
Set up before you run
For onOpen and onEdit, open Extensions > Apps Script from a test spreadsheet. Save onOpen and reopen the spreadsheet to see its menu. Save onEdit and edit a cell below row 1 to supply its event. Do not run onEdit from the toolbar: a manual run has no edit event.
Before running a trigger installer, read its setup and make sure the named handler function exists in the same project. Run the installer, not the event handler, and remove your test triggers when you finish.
Copy a snippet into a script file, read its setup and notes, change the placeholder values, and save. For functions meant to run manually, choose the function name in the toolbar and press Run. Results appear in the Execution log unless the description says otherwise.
1
Create a daily time trigger if it does not exist
Checks the current user's installable triggers first, so running this function twice does not create a duplicate daily trigger for that user.
function createDailyTriggerIfMissing() {
const handlerName = 'runDailyTask';
const alreadyExists = ScriptApp.getProjectTriggers().some((trigger) => trigger.getHandlerFunction() === handlerName);
if (alreadyExists) {
Logger.log('Daily trigger already exists for the current user.');
return;
}
ScriptApp.newTrigger(handlerName).timeBased().everyDays(1).atHour(6).create();
Logger.log('Daily trigger created.');
}
function runDailyTask() {
Logger.log('Daily task ran.');
} Good to know. getProjectTriggers returns only the current user's installable triggers. Other editors must remove their own triggers.
2
Create a weekly trigger on Monday morning
Installs a trigger that runs an existing runWeeklyTask function once a week, on Monday, near 8 AM in the script's time zone.
function createWeeklyMondayTrigger() {
const handlerName = 'runWeeklyTask';
ScriptApp.newTrigger(handlerName)
.timeBased()
.onWeekDay(ScriptApp.WeekDay.MONDAY)
.atHour(8)
.create();
Logger.log('Weekly Monday trigger created.');
} Good to know. First add a function named exactly runWeeklyTask that does your weekly work.
3
Create an hourly trigger
Installs a trigger that runs an existing checkInboxHourly function once every hour.
function createHourlyTrigger() {
const handlerName = 'checkInboxHourly';
ScriptApp.newTrigger(handlerName).timeBased().everyHours(1).create();
Logger.log('Hourly trigger created.');
} Good to know. First add a function named exactly checkInboxHourly that does your hourly work.
4
Delete this user's triggers for one function
Removes the current user's installed triggers that call a particular function, for example before reinstalling a trigger with new settings.
function deleteTriggersForFunction() {
const handlerName = 'runDailyTask';
const triggers = ScriptApp.getProjectTriggers().filter((trigger) => trigger.getHandlerFunction() === handlerName);
triggers.forEach((trigger) => ScriptApp.deleteTrigger(trigger));
Logger.log('Deleted ' + triggers.length + ' trigger(s) for the current user.');
} Good to know. This deletes only your own triggers.
5
List this user's installed triggers with their handler names
Logs the function name and event type for every trigger the current user has installed on the project.
function logInstalledTriggers() {
const triggers = ScriptApp.getProjectTriggers();
triggers.forEach((trigger) => {
Logger.log(trigger.getHandlerFunction() + ' - ' + trigger.getEventType());
});
Logger.log('Total triggers: ' + triggers.length);
} Good to know. The list does not include triggers that another editor installed.
7
An onEdit skeleton that ignores the header row
A simple trigger that runs on every edit in a bound Google Sheet, but exits immediately when the edited cell is in row 1.
/** @param {Events.SheetsOnEdit} e */
function onEdit(e) {
const range = e.range;
if (range.getRow() === 1) return;
Logger.log('Edited cell: ' + range.getA1Notation());
} Good to know. Test this by editing row 2 or below in the bound Sheet. Running onEdit from the editor does not pass it an event object.
8
Read and write a script property
Saves a value that survives between separate runs of the script, then reads it back.
function saveAndReadScriptProperty() {
const properties = PropertiesService.getScriptProperties();
properties.setProperty('LAST_RUN_STATUS', 'ok');
const status = properties.getProperty('LAST_RUN_STATUS');
Logger.log('Last run status: ' + status);
} 9
Use CacheService to remember a value for 10 minutes
Stores a value that expires after 10 minutes, so you can skip repeat work without having to delete the value later.
CacheService.Cachefunction rememberValueForTenMinutes() {
const cache = CacheService.getScriptCache();
const tenMinutesInSeconds = 10 * 60;
cache.put('LAST_API_RESULT', 'success', tenMinutesInSeconds);
const cached = cache.get('LAST_API_RESULT');
Logger.log('Cached value: ' + cached);
} 10
Use LockService to stop two runs from overlapping
Tries to get an exclusive lock before doing protected work, and skips the run if another copy of the script is already using it.
function runWithoutOverlap() {
const lock = LockService.getScriptLock();
const gotLock = lock.tryLock(10000);
if (!gotLock) {
Logger.log('Another run is already in progress. Skipping.');
return;
}
try {
Logger.log('Doing the protected work now.');
} finally {
lock.releaseLock();
}
} Good to know. tryLock waits up to the given number of milliseconds for the lock, then returns false if it still cannot get it.
11
A batch loop that stops after 4 minutes and saves where to resume
Processes items until it is close to the 6 minute script limit, saves its place, then picks back up on the next run.
function processItemsInBatches() {
const properties = PropertiesService.getScriptProperties();
const totalItems = 10000;
const maxRunTimeMs = 4 * 60 * 1000;
const startTime = Date.now();
let index = Number(properties.getProperty('NEXT_INDEX') || '0');
while (index < totalItems) {
if (Date.now() - startTime > maxRunTimeMs) break;
index++;
}
properties.setProperty('NEXT_INDEX', index >= totalItems ? '0' : String(index));
Logger.log('Stopped at index ' + index + ' of ' + totalItems + '.');
} Good to know. Pair this with a time trigger every few minutes so the next run continues from where the last one stopped.
12
Send yourself an email when a function throws
Wraps risky work in a try/catch block and emails you the error message, then rethrows it so the run is still recorded as failed.
GmailAppfunction runProtectedTask() {
try {
riskyOperation();
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
GmailApp.sendEmail('you@example.com', 'Script failed', 'runProtectedTask failed: ' + message);
Logger.log('Error emailed: ' + message);
throw error;
}
}
function riskyOperation() {
throw new Error('Example failure for testing.');
} Keep going
See these in a complete task
- Task guide Run an Apps Script function every day
Make a function run on its own once a day. Run the setup function once, and from then on Apps Script calls the reminder function each day around the hour you chose.
- Task guide Respond to a Google Form submission
Get an email every time someone submits your Google Form, listing each question and its answer. The email goes only to you, the owner of the script.
- Task guide Check a website and alert when it is down
Get one email when a website stops answering and one when it is back. An hourly trigger fetches the address, and a saved script property stops the script from emailing you every hour during one outage.
- Basics Google Apps Script triggers explained
Google Apps Script triggers run functions automatically when a file opens, a cell changes, a form is submitted, or a scheduled time arrives. Use a simple onEdit or onOpen for work in the bound file. Choose an installable trigger for a schedule, form submission, or work that needs authorization.
- Basics Google Apps Script quotas and limits
Google caps how long one run may take and how much your scripts may do in a day. Knowing the caps changes how you write anything that touches a lot of rows.
- Basics Common Apps Script errors and what they mean
Apps Script error messages say what failed, for example TypeError: Cannot read properties of null (reading 'getRange') or ReferenceError. Find the exact message below for its cause and fix.