Installable triggers
Installable triggers are triggers you add explicitly (Triggers panel or ScriptApp.newTrigger) and they run with the full permissions of the user who installed them, so they can send email, fetch URLs and open other files, which simple onEdit and onOpen cannot. They also cover events simple triggers lack: onChange, onFormSubmit and time-driven schedules.
Syntax
ScriptApp.newTrigger(fn).forSpreadsheet(ss).onEdit() | .onChange() | .onFormSubmit() .create()| Part | What it is |
|---|---|
onEdit() | User edits a cell; e.range, e.value, e.oldValue |
onChange() | Any structural or content change, including by other scripts and imports; e.changeType |
onFormSubmit() | A linked Google Form is submitted; e.values and e.namedValues |
onOpen() | Installable version with full authorization |
Examples
function install() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
ScriptApp.newTrigger("notifyOnEdit").forSpreadsheet(ss).onEdit().create();
}
function notifyOnEdit(e) {
if (e.range.getColumn() !== 5 || e.value !== "Approved") return;
MailApp.sendEmail("ops@example.com", "Row approved", "Row " + e.range.getRow() + " was approved.");
}Result: Setting column E to Approved emails ops; works because it is installable
function onFormSubmitHandler(e) {
const name = e.namedValues["Full name"][0];
const email = e.namedValues["Email"][0];
MailApp.sendEmail(email, "Thanks " + name, "We received your form.");
}Result: Each form response gets a confirmation email (trigger type: From spreadsheet, On form submit)
function onChangeHandler(e) {
Logger.log(e.changeType);
}Result: EDIT, INSERT_ROW, REMOVE_ROW, INSERT_GRID, FORMAT or OTHER
Common mistakes
- Both a simple onEdit and an installable trigger on a function named onEdit: the code runs twice per edit; name the installable handler differently.
- The trigger stops when the installer leaves the company: triggers belong to the installing user; reinstall from a service account or a stable owner.
- onChange fires for your own script writes and loops forever: guard with a check on e.changeType or a flag in PropertiesService.
- e.namedValues is undefined in onFormSubmit: the trigger was created with the wrong event type, or the form is not linked to this spreadsheet.
Practice Installable triggers
These drills check your answer on live data, free, no account needed.
- Run only onceReturn a function that calls `fn` the first time it is called, with that call's arguments, and returns `fn`'s result. Every later call returns that same first result without calling `fn` again, even when the result was `undefined` or `0`.
- Retry a failing callCall `fn()` until it succeeds, at most `attempts` times, and resolve with its result. `fn` may return a Promise or a plain value, and it may throw or reject. If every attempt fails, reject with the error from the last attempt.
Questions
Simple vs installable trigger, which should I use?
Simple (onEdit, onOpen as plain function names) for UI-only reactions with no authorization needs; installable for email, external calls, other files, onChange, form submits and schedules.
How many installable triggers can I have?
20 per user per script. Delete unused triggers with ScriptApp.deleteTrigger.
Related
- onEdit triggerUse the onEdit trigger in Google Apps Script: the event object with range, value and oldValue, limiting it to one sheet or column, timestamps, installable.
- Time-driven triggersSchedule Google Apps Script with time-driven triggers: create them in the Triggers panel or with ScriptApp.newTrigger, run daily, hourly or weekly, delete.
- onOpen and custom menusAdd a custom menu to Google Sheets with Apps Script onOpen: createMenu, addItem, separators and submenus that run your functions, and why a menu may hide.
- Send email from a sheetSend email from Google Sheets with Apps Script: MailApp.sendEmail and GmailApp.sendEmail with HTML body, cc and attachments, loop a list of recipients, quota.
Previous: Time-driven triggersNext: Dialogs, prompts and sidebars