Scriptdrill

Automation and triggers Updated November 2026

Time-driven triggers

A time-driven trigger runs a function on a schedule without anyone opening the sheet. Create it in the editor under Triggers (clock icon), Add Trigger, event source Time-driven, or in code: ScriptApp.newTrigger("dailyReport").timeBased().atHour(7).everyDays(1).create(). The function then uses getSheetByName or openById, never getActiveSheet.

Syntax

ScriptApp.newTrigger(functionName).timeBased().everyHours(n) | .atHour(h).everyDays(1) | .onWeekDay(ScriptApp.WeekDay.MONDAY) .create()
PartWhat it is
everyMinutes(n)1, 5, 10, 15 or 30
everyHours(n) / everyDays(n) / everyWeeks(n)Repeat interval
atHour(h)Hour of day (0 to 23) in the script time zone; the exact minute is random within that hour
onWeekDay(day)ScriptApp.WeekDay.MONDAY etc., combine with atHour
at(date)One-off run at a specific Date

Examples

function createDailyTrigger() {
  ScriptApp.newTrigger("dailyReport").timeBased().atHour(7).everyDays(1).create();
}

Result: dailyReport runs every day between 7:00 and 8:00 in the script time zone

ScriptApp.newTrigger("syncOrders").timeBased().everyHours(1).create();

Result: syncOrders runs about once per hour

ScriptApp.newTrigger("weeklyDigest").timeBased().onWeekDay(ScriptApp.WeekDay.MONDAY).atHour(9).create();

Result: weeklyDigest runs every Monday morning

function deleteTriggersFor(name) {
  ScriptApp.getProjectTriggers()
    .filter(t => t.getHandlerFunction() === name)
    .forEach(t => ScriptApp.deleteTrigger(t));
}

Result: Removes every trigger pointing at that function; run before creating a new one to avoid duplicates

Common mistakes

  • The scheduled function fails with Cannot read properties of null: it uses getActiveSheet or getUi; triggers have no active sheet or UI, so use getSheetByName and skip dialogs.
  • The script runs twice a day: the trigger creation function was run twice; delete existing triggers for that handler first.
  • Runs at the wrong hour: atHour uses the project time zone (Project Settings), not your browser's; set it to your zone.
  • This trigger has been disabled for too many failures: fix the error shown in Executions, then recreate the trigger.

Practice Time-driven triggers

These drills check your answer on live data, free, no account needed.

  • Sleep with a PromiseReturn a Promise that resolves (with `undefined`) after `ms` milliseconds, so callers can write `await sleep(500)`. It must always return a Promise, even for `sleep(0)`. Tests run on a fake clock: `setTimeout`, `clearTimeout` and `Date.now` are simulated, so waits are instant and exact.
  • 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.
  • Run tasks in sequence`tasks` is an array of functions; each returns a Promise or a plain value. Run them one at a time, in order, starting each only after the previous one has finished, and resolve with the array of their results. If a task fails, reject and do not start the remaining tasks. Tests run on a fake clock: `setTimeout`, `clearTimeout` and `Date.now` are simulated, so waits are instant and exact.

Questions

Can I run a script every minute?

Yes with everyMinutes(1), but each run counts against daily trigger runtime quota (90 minutes per day on free accounts), so prefer 5 or 15 minutes unless you really need it.

Who runs a time-driven trigger?

The account that created it. The script can only access what that account can, and emails are sent from that account.

Related

  • Installable triggersInstallable triggers in Google Apps Script: how they differ from simple triggers, creating them from the UI or ScriptApp.newTrigger, onChange, onFormSubmit.
  • 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.
  • PropertiesServiceStore settings and secrets in Google Apps Script with PropertiesService: script, user and document properties, setProperty and getProperty, JSON values, keys.
  • 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: onOpen and custom menusNext: Installable triggers