apps-script-triggerslisted
Install: claude install-skill bootgs/skills
# Apps Script Triggers
## Simple vs installable
| | Simple (`onOpen`, `onEdit`, `onInstall`, `onSelectionChange`) | Installable (`ScriptApp.newTrigger(...)`) |
|---|---|---|
| Registration | Automatic — GAS calls the global function by name | Explicit — created programmatically or via the Triggers UI |
| Runs as | The user currently viewing the file, with **their** authorization | The user who created the trigger, with **that user's** authorization, regardless of who triggers it |
| Can call authorized services | No — no `UrlFetchApp`, no most advanced services, no services needing OAuth consent | Yes — full access to whatever the installing user has authorized |
| Typical use | UI-only reactions (build a menu, format a cell) | Anything that calls an external API, sends email, or must run reliably regardless of viewer permissions |
If a simple `onEdit` needs to call `UrlFetchApp` or `MailApp`, it will silently fail or throw a permission error — convert it to an installable trigger instead. This is the most common "trigger works when I test it, breaks for other users" bug: the simple trigger works for you (the owner, already authorized) and fails for a viewer/editor without those grants.
## Event object shapes
| Trigger | Event object fields |
|---|---|
| `onEdit` | `{ range, oldValue, value, source, user, authMode }` — `oldValue`/`value` are only present for single-cell edits with a scalar value; multi-cell pastes omit them (check `range.getNumRows()/getNumColumns()` ins