Time-Driven Triggers

Time-driven triggers let you schedule a function to run automatically at a set interval — every hour, once a day, weekly, or at a specific date and time. They are one of the most powerful features in Apps Script for building fully automated workflows.

Creating a Daily Trigger

Run createDailyTrigger() once to schedule sendDailyReport to fire every morning at 8am:

function createDailyTrigger() { ScriptApp.newTrigger("sendDailyReport") .timeBased() .everyDays(1) .atHour(8) .inTimezone("America/New_York") .create(); Logger.log("Daily trigger created."); }

Creating an Hourly Trigger

function createHourlyTrigger() { ScriptApp.newTrigger("checkForNewDeals") .timeBased() .everyHours(1) .create(); Logger.log("Hourly trigger created."); }

Creating a Weekly Trigger

function createWeeklyTrigger() { ScriptApp.newTrigger("sendWeeklyDigest") .timeBased() .onWeekDay(ScriptApp.WeekDay.MONDAY) .atHour(9) .create(); Logger.log("Weekly Monday digest trigger created."); }

Daily Report Function

This function runs on the daily trigger and emails a summary of the Sales Tracker to the sales manager:

function sendDailyReport() { var sheet = SpreadsheetApp .getActiveSpreadsheet() .getSheetByName("Sales Tracker"); var data = sheet.getRange(2, 1, sheet.getLastRow() - 1, 8).getValues(); // Columns: [Customer Name, Email, Product, Amount, Region, Sales Rep, Status, Date] var closed = data.filter(function(row) { return row[6] === "Closed"; }); var inProgress = data.filter(function(row) { return row[6] === "In Progress"; }); var totalRevenue = closed.reduce(function(sum, row) { return sum + row[3]; }, 0); var today = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MMMM dd, yyyy"); var htmlBody = ` <h2>Daily Sales Report – ${today}</h2> <table border="1" cellpadding="8" cellspacing="0" style="border-collapse:collapse;"> <tr><td><strong>Closed Deals</strong></td><td>${closed.length}</td></tr> <tr><td><strong>In Progress</strong></td><td>${inProgress.length}</td></tr> <tr><td><strong>Total MRR (Closed)</strong></td><td>$${totalRevenue}/mo</td></tr> </table> <br> <p>View the full tracker: <a href="${SpreadsheetApp.getActiveSpreadsheet().getUrl()}">Sales Tracker</a></p> `; GmailApp.sendEmail( "[email protected]", "Daily Sales Report – " + today, "Daily report attached. Open in HTML-capable email client.", { htmlBody: htmlBody } ); Logger.log("Daily report sent."); }

With the sample data, the report shows 2 closed deals, 1 in progress, and $398/mo in total MRR.

Weekly Digest Function

function sendWeeklyDigest() { var sheet = SpreadsheetApp .getActiveSpreadsheet() .getSheetByName("Sales Tracker"); var data = sheet.getRange(2, 1, sheet.getLastRow() - 1, 8).getValues(); // Get deals closed this week var now = new Date(); var weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); var thisWeek = data.filter(function(row) { var dealDate = new Date(row[7]); return row[6] === "Closed" && dealDate >= weekAgo; }); var rows = thisWeek.map(function(row) { return `<tr><td>${row[0]}</td><td>${row[2]}</td><td>$${row[3]}/mo</td><td>${row[4]}</td></tr>`; }).join(""); var htmlBody = ` <h2>Weekly Closed Deals Digest</h2> <table border="1" cellpadding="8" cellspacing="0" style="border-collapse:collapse;"> <thead style="background:#4A90D9;color:#fff;"> <tr><th>Customer</th><th>Product</th><th>Amount</th><th>Region</th></tr> </thead> <tbody>${rows || "<tr><td colspan='4'>No deals closed this week.</td></tr>"}</tbody> </table> `; GmailApp.sendEmail("[email protected]", "Weekly Sales Digest", "", { htmlBody: htmlBody }); Logger.log("Weekly digest sent."); }

Available Time Intervals

MethodDescription
.everyMinutes(n)Every n minutes (1, 5, 10, 15, 30)
.everyHours(n)Every n hours (1, 2, 4, 6, 8, 12)
.everyDays(n)Every n days (1–7)
.everyWeeks(n)Every n weeks (1–3)
.onWeekDay(day)Specific day of the week
.onMonthDay(n)Specific day of the month
.atDate(year, month, day)One-time at a specific date