Snippets · 12 functions
Triggers and script control snippets
Each snippet is a complete function that installs a trigger, remembers a value between runs, or reports a failure, ready to paste into the Apps Script editor.
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 schedules.
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. Before running this, add a runWeeklyTask function that performs your real weekly work. Apps Script calls the function by this exact name.
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. Before running this, add a checkInboxHourly function that performs your real hourly work. Apps Script calls the function by this exact name.
4
Delete this user's triggers for one function
Removes the current user's installed triggers that call a particular function name, useful before that user reinstalls 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. getProjectTriggers cannot delete schedules installed by another editor; each owner must remove their 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. This does not include triggers that another editor installed; each owner sees their own installable triggers.
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. Exercise this by editing row 2 or below in the bound Sheet; running onEdit from the editor does not supply its 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 on its own after 10 minutes, useful for avoiding repeat work without a manual cleanup step.
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
Run the setup function once, then Apps Script calls the reminder function each day around your chosen hour.
- Task guide Respond to a Google Form submission
Add a small response function, then install a form-submit trigger so each new answer produces a private email summary.
- Task guide Check a website and alert when it is down
An hourly trigger fetches one address. The script remembers the last result in a script property, so a long outage produces one alert instead of one every hour.
- Basics Google Apps Script triggers explained
A Google Apps Script trigger runs a function when an event happens, without pressing Run. Simple triggers like onEdit and onOpen need no setup, while installable triggers run on a schedule or form submit using the OAuth scopes approved by their owner.
- 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 name the failure directly, from TypeError: Cannot read properties of null (reading 'getRange') to ReferenceError and quota limits. Find the exact message below for the cause and fix.