Task guide
Email yourself tomorrow’s calendar agenda
A setup function installs one daily trigger for the early evening. Each evening the script reads tomorrow on your main calendar and emails you the list.
1 · Prepare
Put these pieces in place
- Use the Google account whose main calendar holds the events you want to see.
- Create a standalone Apps Script project at script.google.com, or use any project you already have.
- Keep both functions below in the same project, because the trigger looks up the second one by name.
Change these values
- Send hour
18The trigger runs during this hour, in the project time zone. 18 means the 6 PM hour.
- Time format
h:mm aThis prints times like 9:30 AM. Use HH:mm for a 24 hour clock.
- Handler function name
emailTomorrowsAgendaThe setup function looks for this name so it never installs a second trigger.
2 · Review before running
What the script can access and change
Permissions you approve
- See the events on your Google Calendar. Nothing is added or changed there.
- Send email from your Google account, to your own address.
- Create and view triggers in this Apps Script project.
Effects of one run
- Sends the script owner one email each evening listing tomorrow’s events on the main calendar.
- Sends nothing on days when tomorrow has no events.
- Creates one daily trigger, and only when a trigger for emailTomorrowsAgenda is not already installed.
3 · Copy
Paste this into the Apps Script editor
Create or open a script file, replace the example values marked above, then save the project.
const SEND_HOUR = 18; // The trigger runs during this hour, in the project time zone. 18 means the 6 PM hour.
const TIME_FORMAT = 'h:mm a'; // This prints times like 9:30 AM. Use HH:mm for a 24 hour clock.
const HANDLER_FUNCTION_NAME = 'emailTomorrowsAgenda'; // The setup function looks for this name so it never installs a second trigger.
function createAgendaTrigger() {
const alreadyInstalled = ScriptApp.getProjectTriggers().some((trigger) => {
return trigger.getHandlerFunction() === HANDLER_FUNCTION_NAME;
});
if (alreadyInstalled) return;
ScriptApp.newTrigger(HANDLER_FUNCTION_NAME)
.timeBased()
.everyDays(1)
.atHour(SEND_HOUR)
.create();
}
function emailTomorrowsAgenda() {
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
const events = CalendarApp.getDefaultCalendar().getEventsForDay(tomorrow);
if (events.length === 0) return;
const timeZone = Session.getScriptTimeZone();
const lines = events.map((event) => {
if (event.isAllDayEvent()) return 'All day: ' + event.getTitle();
const startText = Utilities.formatDate(event.getStartTime(), timeZone, TIME_FORMAT);
const endText = Utilities.formatDate(event.getEndTime(), timeZone, TIME_FORMAT);
return startText + ' to ' + endText + ': ' + event.getTitle();
});
const subject = 'Agenda for ' + Utilities.formatDate(tomorrow, timeZone, 'EEEE, MMMM d');
GmailApp.sendEmail(Session.getEffectiveUser().getEmail(), subject, lines.join('\n'));
} 4 · Run safely
Follow these steps in order
Paste both functions and save
The first function installs the schedule. The second function is the work that runs each evening.
Test the agenda by hand
Choose emailTomorrowsAgenda and press Run. Approve access when Google asks. This sends one email to you and changes nothing on your calendar, so you can repeat it.
Install the daily trigger
Choose createAgendaTrigger and run it once. Running it again is harmless because it stops when a trigger for emailTomorrowsAgenda already exists.
Check the schedule
Open Triggers in the left sidebar. You should see emailTomorrowsAgenda listed as a day timer for the 6 PM to 7 PM hour.
5 · Confirm
How to tell it worked
You receive an email with a subject such as Agenda for Tuesday, March 4, and one line per event, either a time range and title or All day and the title.
If the result is different
Troubleshooting
- No email arrives after the manual test.
- That is expected when tomorrow has no events on your main calendar. Add a test event for tomorrow and run emailTomorrowsAgenda again.
- The times in the email look wrong.
- Open Project Settings with the gear icon and check the time zone. Utilities.formatDate uses that time zone, not the one on your computer.
- The email arrives at an unexpected hour.
- A day timer runs somewhere inside the chosen hour, not exactly on the hour. To move it, delete the trigger in the Triggers panel, change SEND_HOUR, and run createAgendaTrigger again.
- The agenda is missing events from a shared calendar.
- The script reads only CalendarApp.getDefaultCalendar(). Use CalendarApp.getCalendarById with the ID from Google Calendar settings to read another calendar.
Technical details
Names used in this script
Open these details when you want to adapt the example or look up an exact service or method name.
Show Apps Script symbols and service pages
Apps Script symbols
Service pages
Keep going
Related tasks, basics, and apps
- Task guide Run an Apps Script function every day
Run the setup function once, then Apps Script calls the reminder function each day around your chosen hour.
- Task guide Create Calendar events from Sheet rows
Keep one planned event per row in a tab named Events. The script creates the events that have no ID yet and writes the new ID back into the row.
- Object reference Trigger builder
ScriptApp.newTrigger(functionName) returns a TriggerBuilder that configures a timeBased(), forSpreadsheet(), or forForm() trigger before create() saves it.
- Object reference Calendar
A calendar holds a set of events. Most scripts use your default calendar, but you can also open another calendar you have access to by its ID.
- Object reference Calendar event
A calendar event is one entry on a calendar, such as a meeting or a reminder. It carries a title, a start and end time, and an optional guest list.
- Basics Dates, time zones, and Utilities.formatDate
A Date holds one instant in time. Use Utilities.formatDate(date, timeZone, pattern) and Session.getScriptTimeZone() to format it in the right time zone.
- Google app Google Calendar
CalendarApp scripts read events on a date with getEventsForDay() and add new CalendarEvent entries with createEvent() after you approve Calendar access.
- Google app Gmail
GmailApp scripts can send messages, search threads, apply labels, and read attachments after you approve Gmail access for the project.
- Google app Triggers
A trigger is a saved schedule or event rule in ScriptApp that runs your function on time, on edit, or on form submit.