Task guide
Email yourself tomorrow's calendar agenda
Get an email each evening listing tomorrow's events on your main Google Calendar. Run the setup function once to install the daily trigger.
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, edit, share, and permanently delete all the calendars you can access using Google Calendar. The code only reads tomorrow's events on your main calendar. It adds or changes nothing there.
- Read, compose, send, and permanently delete all your email from Gmail. Google asks for full Gmail access because the code uses GmailApp, but the code only sends the agenda to your own address.
- See your primary Google Account email address. The code reads it to know where to send the agenda.
- Allow this application to run when you are not present. This lets the script install its daily trigger and send the agenda each evening.
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
Follow these steps in order
Paste both functions and save
Paste both functions over the starter code and save. createAgendaTrigger installs the schedule. emailTomorrowsAgenda is the work that runs each evening.
Test the agenda by hand
Choose emailTomorrowsAgenda in the function dropdown above the code, then click Run. Approve access when Google asks. This sends one email to you and changes nothing on your calendar, so you can repeat it. If tomorrow has no events, no email is sent.
Install the daily trigger
Choose createAgendaTrigger and click Run once. Running it again does not add a second trigger, because it stops when a trigger for emailTomorrowsAgenda already exists.
Check the schedule
Click Triggers, the clock icon in the left sidebar. emailTomorrowsAgenda is 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 test run.
- Add a test event for tomorrow in Google Calendar and run emailTomorrowsAgenda again. The script sends nothing when tomorrow has no events on your main calendar.
- The times in the email are off by some hours.
- Open Project Settings, the gear icon in the left sidebar, and set the time zone to yours. Utilities.formatDate uses the project time zone, not the one on your computer.
- The email arrives at an unexpected hour.
- To move it, delete the trigger under Triggers, change SEND_HOUR, save, and run createAgendaTrigger again. A day timer runs some time inside the chosen hour, not exactly on the hour.
- The agenda is missing events from a shared calendar.
- Replace CalendarApp.getDefaultCalendar() with CalendarApp.getCalendarById and the ID from Google Calendar settings. The script reads only your main 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
Make a function run on its own once a day. Run the setup function once, and from then on Apps Script calls the reminder function each day around the hour you chose.
- Task guide Create Calendar events from Sheet rows
Turn rows on an Events tab into events on your Google Calendar. The script creates an event for each row that has no event ID yet, then writes the new ID back into the row so a later run skips it.
- 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.