Trigger Tricks: Running Google Apps Scripts on Form Submit, Edit, or a Timer
The real power of Google Apps Script isn’t just in what your scripts can do—it’s in when they run. Using triggers, you can have your scripts execute automatically at specific times or in response to certain events, turning manual processes into fully automated workflows.
In this guide, I’ll walk you through everything you need to know about Google Apps Script triggers, from simple time-based scheduling to advanced event-driven automation.
What Are Triggers?
Triggers are mechanisms that automatically run your Apps Script functions when certain events occur. Think of them as the “when” for your script’s “what”—they determine when your code executes without you having to manually run it.
Types of Triggers
Google Apps Script offers two main categories of triggers:
Simple Triggers
These run automatically without requiring special authorization:
onOpen()
: Runs when a user opens a spreadsheet, document, or formonEdit()
: Runs when a user edits a spreadsheetonFormSubmit()
: Runs when a form is submittedonInstall()
: Runs when a user installs an add-on
Installable Triggers
These require explicit setup and can handle more complex scenarios:
- Time-driven triggers: Run at specific times or intervals
- Spreadsheet triggers: Include open, edit, form submit, and change events
- Form triggers: Run on form submit
- Calendar triggers: Run when events are created, updated, or deleted
Let’s explore how to implement each type with practical examples.
Time-Driven Triggers: Schedule Scripts to Run Automatically
Time-driven triggers let you run scripts at specific times or intervals—perfect for daily reports, monthly summaries, or any recurring task.
Example: Daily Email Report
This script sends a daily summary report from a Google Sheet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function sendDailyReport() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("Sales");
const dataRange = sheet.getRange("A2:D");
const data = dataRange.getValues();
// Calculate today's totals
let todayTotal = 0;
const today = new Date();
today.setHours(0, 0, 0, 0); // Set to beginning of today
for (let i = 0; i < data.length; i++) {
if (data[i][0] === "") continue; // Skip empty rows
// Convert date string to Date object and check if it's today
const rowDate = new Date(data[i][0]);
rowDate.setHours(0, 0, 0, 0);
if (rowDate.getTime() === today.getTime()) {
todayTotal += Number(data[i][3] || 0); // Column D contains sale amounts
}
}
// Format currency
const formattedTotal = Utilities.formatString('$%.2f', todayTotal);
// Compose and send email
const recipient = "your.email@example.com";
const subject = `Daily Sales Report: ${today.toDateString()}`;
const body = `
Daily Sales Summary for ${today.toDateString()}
Total Sales Today: ${formattedTotal}
This is an automated report from your Google Sheet.
`;
GmailApp.sendEmail(recipient, subject, body);
}
Setting Up the Time Trigger
- Open your Google Sheet and go to Extensions → Apps Script
- Paste the above code and save
- Click on the clock icon (Triggers) in the left sidebar
- Click Add Trigger and configure:
- Function to run:
sendDailyReport
- Event source: Time-driven
- Type of time: Day timer
- Time of day: 6am to 7am
- Function to run:
- Click Save
Now your report will automatically send every morning between 6-7am.
Form Submit Triggers: React to New Submissions
Form submit triggers run your code whenever someone submits a Google Form—perfect for automated responses, data processing, or notifications.
Example: Custom Confirmation Emails
This script sends personalized thank-you emails to form respondents:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function sendThankYouEmail(e) {
// e is the form submit event object
const responses = e.response.getItemResponses();
let email = "";
let name = "";
// Extract email and name from form responses
for (let i = 0; i < responses.length; i++) {
const question = responses[i].getItem().getTitle();
const answer = responses[i].getResponse();
if (question === "Email Address") {
email = answer;
} else if (question === "Your Name") {
name = answer;
}
}
// Only proceed if we have a valid email
if (email) {
const subject = "Thank you for your submission";
const body = `
Dear ${name},
Thank you for completing our form. We've received your information and will process it shortly.
Best regards,
Your Organization
`;
GmailApp.sendEmail(email, subject, body);
}
}
Spreadsheet Edit Triggers: React to Changes
Edit triggers run when users modify your spreadsheet, allowing you to validate data, update related cells, or track changes.
Example: Automatic Timestamp on Edit
This script adds a timestamp whenever someone modifies specific columns:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function onEdit(e) {
// e is the edit event object
const sheet = e.source.getActiveSheet();
const range = e.range;
// Only run if edits happen in columns B, C, or D (indexes 1, 2, or 3)
if (range.getColumn() >= 2 && range.getColumn() <= 4) {
// Add timestamp in column E (index 4) of the same row
const row = range.getRow();
const timestampCell = sheet.getRange(row, 5);
// Only update if this is a data row (not the header)
if (row > 1) {
timestampCell.setValue(new Date());
// Format as date+time
timestampCell.setNumberFormat("yyyy-MM-dd HH:mm:ss");
}
}
}
Debugging and Monitoring Triggers
When working with triggers, robust error handling is crucial because you won’t be there to see errors as they happen.
Example: Error Handling in a Triggered Function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function weeklyReport() {
try {
// Your code here
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("Data");
// More processing...
// Send email with report
GmailApp.sendEmail("manager@example.com", "Weekly Report", "Report data...");
// Log success
console.log("Weekly report sent successfully on " + new Date());
} catch (error) {
// Log error details
console.error("Error in weeklyReport: " + error.message);
// Send notification about the error
GmailApp.sendEmail(
"admin@example.com",
"Error in Weekly Report Script",
"The weekly report script failed with error: " + error.message
);
}
}
Trigger Limitations and Best Practices
Limitations
- Quotas: Free Google accounts have daily quotas for trigger executions
- Duration: A script must complete within 6 minutes (or 30 minutes for certain operations)
- Frequency: Time-driven triggers can run at most once per minute
Best Practices
- Keep scripts efficient: Optimize code to run as quickly as possible
- Use error handling: Always wrap triggered code in try/catch blocks
- Implement logging: Log important events and errors
- Set up failure notifications: Get alerted when your triggers fail
- Test thoroughly: Manual testing before setting up triggers saves headaches
Conclusion
Triggers transform Google Apps Script from a handy coding tool into a powerful automation platform. By configuring your scripts to run automatically based on time or events, you can create sophisticated workflows that save time and reduce errors.
Whether you’re maintaining a simple inventory system or creating complex approval processes, mastering triggers unlocks the full potential of Google Apps Script.
Next Steps
Ready to level up your Google Apps Script skills further? Check out these other tutorials:
- Top 10 Google Sheets Time-Saving Scripts
- How to Send Personalized Gmail Newsletters
- Building a Simple CRUD Web App
What automation challenges are you facing? Share in the comments, and I might feature solutions in upcoming tutorials!
Questions? Corrections? Issues and pull requests are always welcome.