Google Apps Script
Server-side JavaScript that runs on Google's infrastructure with built-in, auto-authorised services for Workspace. V8 is the only runtime: Rhino was shut down on 31 January 2026, so write modern JavaScript (const/let, arrow functions, classes, template literals, destructuring) and set "runtimeVersion": "V8" in appsscript.json if a legacy manifest still says DEPRECATED_ES5.
Steps
-
Pick the binding and entry point. Container-bound scripts (opened from a Sheet, Doc or Form) can use
getActiveSpreadsheet()/getActiveDocument()and simple triggers (onOpen,onEdit). Standalone scripts and anything run from a time trigger must open files by ID or URL. Done when every file access in the plan uses a call that works in the chosen binding. -
Write against the service, batching I/O. Read a whole range with
getValues(), transform in memory, write back once withsetValues(). Cache expensive lookups with CacheService and persist config or cursors with PropertiesService. Done when nogetValue/setValue/appendRowsits inside a loop over rows. -
Fit the 6-minute limit. Each execution stops at 6 minutes (custom functions at 30 seconds). For larger jobs, process a slice, save a cursor in PropertiesService, and let a time trigger pick up the next slice. Done when the worst-case run is bounded by a batch size, not the data size.
-
Set triggers idempotently. Before
ScriptApp.newTrigger(...), delete existing triggers for the same handler so re-running setup never duplicates them. Done when running the setup function twice leaves one trigger per handler. -
Narrow the scopes. List
oauthScopesexplicitly inappsscript.json, preferringspreadsheets.currentonly,drive.fileandscript.send_mailover their broad counterparts. Done when every scope in the manifest maps to a call the script makes. -
Handle failure visibly. Wrap trigger handlers in try/catch, log with
console.error(it reaches Cloud Logging with severity), and notify by email or an error sheet - a failed time trigger is otherwise silent. Done when every trigger handler has a catch that records the error somewhere a human will see it.
Quick start
function generateWeeklyReport() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const rows = ss.getSheetByName('Data').getRange('A2:C').getValues()
.filter(row => row[0]);
const summary = ss.getSheetByName('Summary') || ss.insertSheet('Summary');
summary.clear();
const out = [['Name', 'Value', 'Status'], ...rows];
summary.getRange(1, 1, out.length, out[0].length).setValues(out);
MailApp.sendEmail({
to: Session.getEffectiveUser().getEmail(),
subject: 'Weekly report generated',
body: `Report generated with ${rows.length} records.`
});
}
Gotchas
- Retired services. ContactsApp (shut down 31 Jan 2025) - use the People advanced service. Classic Sites service (shut down 24 Sep 2024), UiApp (2019) and DocsList (2015) are gone - use HtmlService for UI and DriveApp for files. Google keeps the list at https://developers.google.com/apps-script/guides/support/sunset.
- GmailApp vs MailApp. Both send. MailApp is send-only and needs the narrower
script.send_mailscope; reach for GmailApp when the script also reads, searches, labels or drafts. - CacheService defaults to 10 minutes, caps at 6 hours and 100 KB per value, and can evict early - always handle a miss.
- Simple triggers (
onOpen,onEdit) run without authorisation, so they cannot send mail or open other files; use an installable trigger for that. - Quotas differ by account. Email recipients are 100/day on consumer accounts and 1,500/day on Workspace; trigger runtime is 90 min/day vs 6 h/day.
- Local development with clasp:
.clasp.jsonholds thescriptIdandrootDir;clasp pushuploads.js/.gsandappsscript.json.
Validation
scripts/validators.py checks spreadsheet IDs, A1 notation (including open-ended ranges like A2:D), sheet names, cell values and the 10-million-cell limit before you hard-code them. Run with python3 "${CLAUDE_SKILL_DIR}/scripts/validators.py" for a self-test, or import its functions.
References
- references/apps-script-api-reference.md - read when you need a service's method signatures (SpreadsheetApp, DocumentApp, GmailApp, DriveApp, CalendarApp, ScriptApp, UrlFetchApp, Utilities), OAuth scopes, or the full quota table.
- references/examples.md - read when building a report, Gmail auto-responder, document-from-template or daily trigger from scratch.
- references/best-practices.md - read when reviewing an existing script for batching, caching, error handling or scope problems.
- references/patterns.md - read when adding data validation dropdowns, retry with backoff, or form-submit processing.
assets/spreadsheet-automation-template.jsandassets/trigger-setup-template.js- copy as a starting point for a new Sheets automation or trigger manager.
微信扫一扫