Flag meetings that could have been emails
Detect short, agendaless, oversized meetings — the smell of bad calendar hygiene.
Published Oct 12, 2025
Half of Northwind’s most frustrating meetings have the same shape — fifteen minutes long, six people in the room, no agenda in the description, and a title like “Quick sync”. They eat time in aggregate even though none of them look expensive on their own. The first step to retiring them is to count them.
This script scans the last seven days of your calendar and picks out events that match all three “could-have-been-an-email” smells: short, big group, no agenda. The output is a single email each Monday morning listing them — small enough to act on, specific enough that the conversation about “fewer meetings” stops being vague.
What you’ll need
- Edit access to a Google Calendar (the script uses your default calendar).
- A mailbox to receive the digest. Edit
DIGEST_RECIPIENTbelow or useSession.getActiveUser().getEmail()to send it to yourself. - Nothing else.
The script
// Inbox that receives the weekly digest of suspect meetings.
const DIGEST_RECIPIENT = '[email protected]';
// Meetings shorter than or equal to this many minutes count as "short".
const SHORT_MEETING_MINUTES = 15;
// Meetings with at least this many guests count as "oversized".
const LARGE_MEETING_GUESTS = 4;
// Descriptions shorter than this many characters count as "no agenda".
const MIN_AGENDA_LENGTH = 20;
// How many days back to look. One week is the natural reporting window.
const LOOKBACK_DAYS = 7;
/**
* Scans the last `LOOKBACK_DAYS` of the default calendar and emails a
* digest of meetings that are short, large, and agendaless. Quietly
* does nothing if no meetings match.
*/
function flagWastefulMeetings() {
// 1. Build the lookback window. Multiplying milliseconds is fine for
// a week — no DST off-by-one risk worth worrying about here.
const start = new Date(Date.now() - LOOKBACK_DAYS * 86_400_000);
const end = new Date();
const events = CalendarApp.getDefaultCalendar().getEvents(start, end);
// 2. Filter on the three smells together. Any one of them alone is
// fine — together they describe the meetings worth flagging.
const flagged = events.filter((e) => {
const minutes = (e.getEndTime() - e.getStartTime()) / 60_000;
const guests = e.getGuestList().length;
const description = (e.getDescription() || '').trim();
const hasAgenda = description.length > MIN_AGENDA_LENGTH;
return minutes <= SHORT_MEETING_MINUTES
&& guests >= LARGE_MEETING_GUESTS
&& !hasAgenda;
});
if (flagged.length === 0) {
Logger.log('No wasteful meetings detected this week.');
return;
}
// 3. Format one line per meeting. Date plus title plus headcount is
// enough context to recognise the meeting at a glance.
const tz = Session.getScriptTimeZone();
const body = flagged
.map((e) => {
const when = Utilities.formatDate(e.getStartTime(), tz, 'd MMM HH:mm');
const headcount = e.getGuestList().length;
return when + ' ' + e.getTitle() + ' (' + headcount + ' ppl)';
})
.join('\n');
const subject = flagged.length
+ ' meeting' + (flagged.length === 1 ? '' : 's')
+ ' could have been emails';
GmailApp.sendEmail(DIGEST_RECIPIENT, subject, body);
}
How it works
- The script defines what “wasteful” means in three constants at the top — short, large, and agendaless. Move them up or down to tune the signal.
getEventsreads every event whose interval touches the last seven days. That includes recurring instances, which are flagged just like any other event.- The filter combines all three rules. A 30-minute meeting passes the guest-and-agenda checks but fails the length check, so it is not flagged — that is by design.
- If nothing matches, the script logs and exits. No “all clear” email, because the inbox already has plenty of clutter.
- Otherwise it formats one line per meeting — date, time, title, headcount —
and sends a digest to
DIGEST_RECIPIENT. The subject line counts the matches, so the inbox preview is already informative.
Example run
A typical week at Northwind might produce a digest like this:
Subject: 3 meetings could have been emails
8 Oct 09:30 Quick sync (5 ppl) 9 Oct 14:00 Status update (6 ppl) 11 Oct 11:15 Touch base (4 ppl)
Each line is recognisable enough to pull up the event and decide whether next week’s version should be cancelled, replaced with a written update, or attended with a sharper agenda.
Trigger it
A Monday-morning digest fits the human rhythm best:
- In the Apps Script editor, open Triggers.
- Add a trigger for
flagWastefulMeetings, event source Time-driven, type Week timer, day Monday, time 8am to 9am.
Run it on demand the first few times to tune the thresholds — what counts as “short” or “oversized” varies by team.
Watch out for
- The thresholds are deliberately conservative. If the digest is full of
legitimate stand-ups, raise
LARGE_MEETING_GUESTSto five or six, or shortenSHORT_MEETING_MINUTESto ten. Tune until the list is small enough to act on. - “No agenda” is detected by description length, which is crude. A meeting with the description “Project kickoff” looks agendaless because it is shorter than 20 characters. Add a richer check — for example, “contains a newline” — if your team writes terse but real agendas.
- The script only reads your default calendar. If you want a team-wide view, loop over a list of calendar IDs and concatenate the events.
- Recurring meetings show up once per instance. A weekly “quick sync” lands in every digest until it is fixed or cancelled — which is arguably the point, but it can feel naggy. Group by event ID if you only want each series flagged once a quarter.
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
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
Email a clean daily agenda each morning
Send Awadesh a list of today's Northwind events at 7am — no app needed.
Updated Sep 22, 2025