Email yourself a weekly calendar summary
Send a Monday week-ahead digest of every Northwind meeting in the next seven days.
Published Jun 26, 2025
Mondays at Northwind tend to start with a scroll through the calendar to figure out what the week looks like — which mornings are blocked, which afternoons are clear, when the back-to-back days are. The calendar already knows all of that, but reading it day by day takes longer than it should and leaves you with no record once you have closed the tab.
This short script does the scroll for you. It fetches the next seven days of events, groups them by day, and emails the digest as plain text. A glance at your inbox on Monday morning tells you the shape of the week — and the email sits in the thread as a reference you can search later.
What you’ll need
- Access to the calendar you want to summarise. The script uses
CalendarApp.getDefaultCalendar(); replace withgetCalendarByIdfor a shared one. - Gmail access for the digest itself — sent to
Session.getActiveUser().getEmail(). - Nothing else — no spreadsheet, no API keys.
The script
// How many days the digest covers. Seven gives a full week ahead.
const DIGEST_DAYS = 7;
// Milliseconds in a day, used to build the end of the window.
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
/**
* Reads the next seven days of the default calendar and emails a digest,
* grouped by day, to the script owner.
*/
function weeklyCalendarDigest() {
const start = new Date();
const end = new Date(start.getTime() + DIGEST_DAYS * ONE_DAY_MS);
// 1. Pull every event in the next seven days.
const events = CalendarApp.getDefaultCalendar().getEvents(start, end);
// 2. Bucket events by their day. A Map keeps insertion order so days
// appear chronologically in the digest.
const tz = Session.getScriptTimeZone();
const byDay = new Map();
for (const e of events) {
const day = Utilities.formatDate(e.getStartTime(), tz, 'EEEE d MMMM');
if (!byDay.has(day)) byDay.set(day, []);
const time = Utilities.formatDate(e.getStartTime(), tz, 'HH:mm');
byDay.get(day).push(`${time} ${e.getTitle()}`);
}
// 3. Render each day as a header followed by indented event lines.
// If the week is empty, send a one-line "all clear" message.
const body = [...byDay.entries()]
.map(([day, list]) => `${day}\n${list.map((l) => ` ${l}`).join('\n')}`)
.join('\n\n') || 'Clear week ahead.';
// 4. Send the digest to the script owner.
GmailApp.sendEmail(
Session.getActiveUser().getEmail(),
`Week ahead — ${events.length} events`,
body
);
}
How it works
weeklyCalendarDigestbuilds a window from now to seven days ahead (DIGEST_DAYS).- It fetches every event in the window via the default calendar.
- It walks the events and groups them into a
Mapkeyed by day string ("Monday 1 September"), preserving order. Each value is a list ofHH:mm Titlelines. - It renders the map into plain text — one header per day, two-space
indented lines underneath, a blank line between days. An empty week
gets the fallback message
Clear week ahead.. - It emails the result to the script owner, with the event count in the subject so the digest is searchable later.
Example run
After a run on Monday morning, the email looks roughly like this:
Subject: Week ahead — 6 events
Monday 1 September 09:00 Production brief 14:00 Client call: Fabrikam
Tuesday 2 September 11:00 One-to-one: Alex
Wednesday 3 September 10:00 Workshop prep 15:30 Edit review
Friday 5 September 09:30 All-hands
Days without events are skipped — Thursday simply does not appear. That keeps the digest short on slow weeks.
Trigger it
Run this once a week, early on Monday:
- In the Apps Script editor, open Triggers (the clock icon).
- Add a trigger for
weeklyCalendarDigest, time-driven, week timer, Monday, between 7am and 8am. - Save and approve the calendar and Gmail authorisation prompts.
Watch out for
- All-day events are included. They show up with a start time of
00:00, which is usually fine but can clutter the top of each day’s block. Filter withisAllDayEvent()if you want them out — or put them in their own section at the end. - The script uses the script’s timezone via
Session.getScriptTimeZone(). If you travel or share the script with people in other timezones, set it explicitly in Project Settings so the times come out right. - Long event titles wrap awkwardly in plain text. If you want a richer
digest, swap
GmailApp.sendEmailfor the four-argument form with anhtmlBodyoption and render an HTML table instead. - The seven-day window includes today. If you would rather start at
midnight tonight, set
start.setHours(0, 0, 0, 0)and add a day to the end before fetching.
Related
Send a feedback survey after each event
Email attendees a survey link automatically after Northwind workshops or trainings.
Updated Oct 24, 2025
Build a team-capacity view from calendars
Show how booked the Northwind team is this week — meeting hours per person.
Updated Oct 20, 2025
Flag meetings that could have been emails
Detect short, agendaless, oversized meetings — the smell of bad calendar hygiene.
Updated Oct 12, 2025
Send tiered deadline countdown reminders
Email Northwind teammates at 7, 3, and 1 days out from a Sheet of upcoming deadlines.
Updated Sep 30, 2025
Archive past events to a log sheet
Keep a searchable Northwind meeting history — every event logged with title, attendees, duration.
Updated Sep 26, 2025