Track contract expiry from Drive files
Read expiry dates out of Northwind contract Docs and warn before renewals.
Publicado 28 oct 2025
Northwind signs contracts the way most studios do — a Google Doc per client, filed in a folder, then forgotten until something goes wrong. The expiry date is written into the document, but nobody re-reads every contract every month, so a renewal slips past and the studio is suddenly out of cover or auto-renewed on old terms.
This script reads the expiry date straight out of each contract Doc. It scans a folder, pulls the date out of the document text with a regular expression, and emails a digest of anything expiring within a warning window. It is a reminder system that needs no separate spreadsheet of dates to maintain — the contracts themselves are the source of truth.
What you’ll need
- A Drive folder of contract Google Docs — its ID goes in the config below.
- Each contract must contain an expiry line the regex can find, e.g.
Expiry: 2026-03-31orExpires 2026-03-31. The date must be inYYYY-MM-DDform. - The address the digest should go to — set it in the config.
The script
// The folder of contract Google Docs to scan.
const CONTRACTS_FOLDER_ID = '1abcContractsFolderId';
// Where the "expiring soon" digest is sent.
const NOTIFY_EMAIL = '[email protected]';
// How many days ahead counts as "expiring soon".
const WARN_DAYS = 30;
// One day in milliseconds — used to build the cutoff date.
const DAY_MS = 86400000;
// Matches "expiry", "expires", or "expire", then a YYYY-MM-DD date.
const EXPIRY_PATTERN = /expir(?:y|es?)[:\s]*(\d{4}-\d{2}-\d{2})/i;
/**
* Scans the contracts folder, reads the expiry date from each Doc,
* and emails a digest of contracts expiring within WARN_DAYS.
*/
function checkExpiringContracts() {
// 1. Get every Google Doc in the contracts folder.
const files = DriveApp.getFolderById(CONTRACTS_FOLDER_ID)
.getFilesByType(MimeType.GOOGLE_DOCS);
// 2. Work out the cutoff: anything dated past this is not "soon".
const now = Date.now();
const cutoff = now + WARN_DAYS * DAY_MS;
// 3. Walk each Doc and collect the ones expiring inside the window.
const expiring = [];
while (files.hasNext()) {
const file = files.next();
// Read the document body as plain text and search for an expiry date.
const text = DocumentApp.openById(file.getId()).getBody().getText();
const match = text.match(EXPIRY_PATTERN);
if (!match) continue;
// Skip contracts already expired or still beyond the warning window.
const expiry = new Date(match[1]).getTime();
if (expiry < now || expiry > cutoff) continue;
expiring.push(`• ${file.getName()} expires ${match[1]}\n ${file.getUrl()}`);
}
// 4. Send a digest only if something is actually expiring soon.
if (!expiring.length) {
Logger.log('No contracts expiring in the next ' + WARN_DAYS + ' days.');
return;
}
GmailApp.sendEmail(
NOTIFY_EMAIL,
`${expiring.length} contract(s) expiring soon`,
expiring.join('\n'),
);
Logger.log('Sent a digest of ' + expiring.length + ' contract(s).');
}
How it works
checkExpiringContractsopens the contracts folder and gets only its Google Docs —getFilesByTypeskips PDFs, images, and anything else.- It computes a
cutofftimestampWARN_DAYSinto the future. A contract counts as “expiring soon” only if its date falls between now and that cutoff. - For each Doc it reads the body as plain text and runs
EXPIRY_PATTERNagainst it. A Doc with no matching line is skipped silently. - It parses the captured
YYYY-MM-DDdate. Contracts already expired (before now) or still far off (past the cutoff) are dropped; the rest are formatted into a bullet line with the file name, date, and link. - If the
expiringlist is empty it logs and stops — no empty email. Otherwise it sends one digest toNOTIFY_EMAILlisting every contract due for renewal.
Example run
Say the contracts folder holds five Docs and today is 2025-10-28 with
WARN_DAYS at 30. Two contracts have expiry lines inside the window:
| Contract Doc | Expiry line found | In window? |
|---|---|---|
| Acme Retainer 2025 | Expires 2025-11-12 | yes |
| Globex Hosting | Expiry: 2026-06-01 | no — too far off |
| Initech Support | Expiry: 2025-09-30 | no — already expired |
| Umbrella Studio Lease | Expires 2025-11-20 | yes |
| Wayne Co Licence | (no expiry line) | skipped |
The run sends one email, subject “2 contract(s) expiring soon”, with:
• Acme Retainer 2025 expires 2025-11-12
https://docs.google.com/document/d/...
• Umbrella Studio Lease expires 2025-11-20
https://docs.google.com/document/d/...
Trigger it
The reminder is only useful if it runs without anyone asking:
- In the Apps Script editor open Triggers (the clock icon).
- Add a trigger for
checkExpiringContracts, time-driven, on a weekly timer.
Weekly means a 30-day window gives roughly four nudges before any renewal — enough warning without becoming noise.
Watch out for
- The regex needs a date in
YYYY-MM-DDform. A contract writtenexpires 31 March 2026will not match — standardise the expiry wording when contracts are drafted. - It reads only the first match per document. If a Doc mentions several dates,
put the contract’s own expiry line first, or tighten
EXPIRY_PATTERN. - It scans one folder, not subfolders. Contracts filed in client subfolders are missed unless you add a recursive walk.
- Already-expired contracts are skipped, not flagged. If you want to catch ones
that lapsed unnoticed, drop the
expiry < nowcheck and label them separately. - The digest goes to a single address. For a shared inbox, use a group address
in
NOTIFY_EMAILso the whole team sees the reminder.
Relacionados
Detect and report broken file shortcuts
Find Drive shortcuts in Northwind folders pointing at deleted or inaccessible files.
Actualizado 3 dic 2025
Build a Drive cleanup recommendation report
Suggest what Northwind can delete or archive — large, stale, duplicate, or untouched files.
Actualizado 21 nov 2025
Generate a folder-level changelog
Track additions and deletions in a Northwind folder over time — a written history.
Actualizado 5 nov 2025
Build a Drive quota early-warning system
Alert Northwind before storage runs out — email when usage crosses 80%.
Actualizado 20 oct 2025
Enforce file naming and tagging governance
Flag Northwind files that don't match required naming or tagging conventions.
Actualizado 16 oct 2025