Auto-decline meetings outside working hours
Protect Northwind schedules — decline invites that land outside 9-6 London time.
Published Jul 20, 2025
Northwind works with clients across several time zones, which is fine until the invites start arriving for 7am or a Sunday afternoon. Each one is easy to decline by hand, but they add up, and a meeting left un-declined quietly blocks out personal time on the calendar.
This script enforces a simple rule: meetings should sit inside working hours. It scans the next fortnight of invites and automatically declines anything that starts before 9am, at or after 6pm, or on a weekend — measured in London time. Invites you have already accepted are left alone; only fresh, still-pending invites get the treatment.
What you’ll need
- Nothing to set up — the script runs against your default Google Calendar.
- A clear idea of your working hours. The defaults are 9am to 6pm, Monday to Friday, London time. Adjust the constants below to match yours.
The script
// The time zone working hours are measured in.
const TZ = 'Europe/London';
// Working day boundaries (24-hour clock). Meetings starting before
// START_HOUR or at/after END_HOUR are declined.
const START_HOUR = 9;
const END_HOUR = 18;
// Last working day of the week, as an ISO day number (Mon=1 ... Sun=7).
const LAST_WORK_DAY = 5;
// How far ahead to scan, in milliseconds (14 days).
const WINDOW_MS = 14 * 86400000;
/**
* Scans the next two weeks of calendar invites and declines any that
* start outside working hours, in London time.
*/
function declineOutOfHours() {
// 1. Build the scan window: now until two weeks from now.
const start = new Date();
const end = new Date(start.getTime() + WINDOW_MS);
const events = CalendarApp.getDefaultCalendar().getEvents(start, end);
for (const event of events) {
// 2. Only act on invites still awaiting a response. Skip anything
// already accepted, declined or that you own.
if (event.getMyStatus() !== CalendarApp.GuestStatus.INVITED) continue;
// 3. Read the start hour and ISO weekday in the chosen time zone.
const hour = parseInt(Utilities.formatDate(event.getStartTime(), TZ, 'H'));
const day = parseInt(Utilities.formatDate(event.getStartTime(), TZ, 'u'));
// 4. Decline if it falls on a weekend or outside working hours.
if (day > LAST_WORK_DAY || hour < START_HOUR || hour >= END_HOUR) {
event.setMyStatus(CalendarApp.GuestStatus.NO);
Logger.log('Declined out-of-hours invite: ' + event.getTitle());
}
}
}
How it works
declineOutOfHoursbuilds a 14-day window starting from now and reads every event in it from the default calendar.- For each event it checks
getMyStatus(). Only events with the statusINVITED— invites you have neither accepted nor declined — are considered. Meetings you own or have already responded to are skipped. - It formats the event’s start time into two numbers using the
Europe/Londontime zone: the hour on a 24-hour clock (H) and the ISO weekday (u), where Monday is 1 and Sunday is 7. - If the weekday is past Friday, or the hour is before 9 or at/after 18, the
meeting falls outside working hours and
setMyStatusdeclines it. Each decline is logged so you can review what was rejected.
Example run
Suppose four invites are sitting un-answered in the next two weeks:
| Invite | Start (London) | Outcome |
|---|---|---|
| Client sync | Tue 10:00 | Kept — inside hours |
| Early standup | Wed 08:00 | Declined — before 9am |
| Evening review | Thu 19:30 | Declined — at/after 6pm |
| Weekend catch-up | Sat 14:00 | Declined — weekend |
After the run, only the Tuesday client sync still shows as pending; the other three are declined and the organisers are notified, exactly as if you had clicked “No” yourself.
Trigger it
Run this on an hourly time-based trigger so invites are handled soon after they arrive:
- In the Apps Script editor open Triggers (the clock icon).
- Add a trigger for
declineOutOfHours, Time-driven, Hour timer, every hour.
An hourly cadence keeps the lag short — a 7am invite sent today is declined well before tomorrow morning, giving the organiser plenty of time to re-book.
Watch out for
- Declining sends a notification to the organiser. That is the point, but it
means a mis-set
START_HOURorEND_HOURwill fire off real decline emails to clients. Test withLogger.logbefore enabling the trigger. - The check is purely on start time. A meeting starting at 5:30pm that runs to
7pm is kept; one starting at 6:01pm is declined. Adjust
END_HOURif you want a stricter cut-off. - Declines are not reversible by the script. If it wrongly declines a meeting
you wanted, you must re-accept it manually — the script only ever sets
status to
NO, never back toYES. - All-day events have a start time of midnight, so they will be declined as
“before 9am”. Add an
event.isAllDayEvent()skip if all-day invites should be left alone. - The window is two weeks. An invite for a meeting more than 14 days out is not seen until it falls inside the window, so it may sit pending for a while before being declined.
Related
Schedule personal habits and routines
Block recurring habits on Awadesh's calendar — gym, walks, deep-work mornings.
Updated Nov 5, 2025
Sync birthdays and anniversaries to Calendar
Populate recurring personal dates from a Sheet — the Northwind team rituals calendar.
Updated Nov 1, 2025
Generate recurring events with custom exceptions
Handle complex recurrence rules in code — every Tuesday except UK bank holidays.
Updated Oct 28, 2025
Auto-reschedule low-priority conflicts
Move flexible Northwind events around fixed ones — focus blocks bend, client calls don't.
Updated Oct 16, 2025
Build a contract-renewal calendar
Track Northwind's recurring-revenue renewal dates as calendar events for proactive sales.
Updated Oct 8, 2025