Generate a folder-level changelog
Track additions and deletions in a Northwind folder over time — a written history.
Published Nov 5, 2025
Drive has no built-in history for a folder. If a file vanishes from Northwind’s
shared Deliverables folder, there is no log saying when it went or what was
added since — you are left guessing from memory. For a folder that clients and
freelancers both touch, that is a real gap.
This script builds that history itself. Each run takes a snapshot of the file IDs in a folder, compares it to the previous snapshot stored in Script Properties, and appends a row to a changelog Sheet for every file added or removed since. Run it on a schedule and you get a dated, written record of exactly what changed.
What you’ll need
- A Drive folder to watch — its ID goes in the config below.
- A blank Google Sheet for the changelog — its ID goes in the config too.
- Nothing else. The previous snapshot is kept in Script Properties; the script manages it for you.
The script
// The folder whose contents you want to track over time.
const WATCHED_FOLDER_ID = '1abcWatchedFolderId';
// The Sheet that the changelog rows are appended to.
const CHANGELOG_SHEET_ID = '1abcChangelogId';
// The Script Property key under which the last snapshot is stored.
const SNAPSHOT_KEY = 'PREVIOUS_FILES';
/**
* Compares the current file list of the watched folder against the
* last snapshot and appends an "added" or "removed" row per change.
*/
function detectChanges() {
const props = PropertiesService.getScriptProperties();
// 1. Load the previous snapshot of file IDs (empty on the first run).
const previous = JSON.parse(props.getProperty(SNAPSHOT_KEY) || '[]');
// 2. Take a fresh snapshot of what is in the folder right now.
const current = listFileIds(WATCHED_FOLDER_ID);
// 3. Diff the two lists: IDs new this run, and IDs that disappeared.
const added = current.filter((id) => !previous.includes(id));
const removed = previous.filter((id) => !current.includes(id));
// 4. Append a dated row to the changelog for every change.
if (added.length || removed.length) {
const sheet = SpreadsheetApp.openById(CHANGELOG_SHEET_ID).getSheets()[0];
added.forEach((id) => sheet.appendRow([new Date(), 'added', id]));
removed.forEach((id) => sheet.appendRow([new Date(), 'removed', id]));
Logger.log(`Logged ${added.length} added, ${removed.length} removed.`);
} else {
Logger.log('No changes since the last run.');
}
// 5. Store the current snapshot as the baseline for next time.
props.setProperty(SNAPSHOT_KEY, JSON.stringify(current));
}
/**
* Returns an array of the file IDs directly inside a folder.
*/
function listFileIds(folderId) {
const ids = [];
const it = DriveApp.getFolderById(folderId).getFiles();
while (it.hasNext()) ids.push(it.next().getId());
return ids;
}
How it works
detectChangesreads the previous snapshot from Script Properties. On the very first run there is nothing stored, so it defaults to an empty array.listFileIdswalks the watched folder and returns the IDs of every file in it right now — this is the current snapshot.- It diffs the two lists: an ID in
currentbut notpreviousis an addition; an ID inpreviousbut notcurrentis a removal. - For each change it appends a row to the changelog Sheet — a timestamp, the
word
addedorremoved, and the file ID. If nothing changed, it logs that and writes no rows. - Finally it overwrites the stored snapshot with the current list, so the next run compares against this run’s state.
Example run
The watched folder starts with three files. The first run records nothing — it just stores the baseline. Before the second run, a file is added and another is deleted. The second run appends:
| Date | Change | File ID |
|---|---|---|
| 2025-11-05 06:00:11 | added | 1xyzNewBriefId |
| 2025-11-05 06:00:11 | removed | 1xyzOldDraftId |
Over weeks the changelog Sheet becomes a complete, dated history of the folder — a record you can scroll back through whenever someone asks “when did that file go?”.
Trigger it
The script only sees changes between two runs, so it needs to run on a schedule:
- In the Apps Script editor open Triggers (the clock icon).
- Add a trigger for
detectChanges, time-driven, on a daily or hourly timer.
Pick the interval to match how granular you want the history. Hourly catches near to when a change happened; daily is enough for a slow-moving folder.
Watch out for
- The changelog stores file IDs, not names — a removed file is gone, so its
name cannot be looked up after the fact. If names matter, extend
listFileIdsto snapshot{id, name}pairs and log the name too. - It only sees the gap between runs. A file added and deleted between two runs leaves no trace at all.
- It watches one folder, not subfolders. A file moved into a subfolder reads as
removedfrom the parent. - A renamed file keeps the same ID, so a rename produces no changelog entry — the script tracks presence, not metadata.
- Clearing the
PREVIOUS_FILESScript Property resets the baseline. The next run then logs every current file asadded, which floods the changelog.
Related
Detect and report broken file shortcuts
Find Drive shortcuts in Northwind folders pointing at deleted or inaccessible files.
Updated Dec 3, 2025
Build a Drive cleanup recommendation report
Suggest what Northwind can delete or archive — large, stale, duplicate, or untouched files.
Updated Nov 21, 2025
Track contract expiry from Drive files
Read expiry dates out of Northwind contract Docs and warn before renewals.
Updated Oct 28, 2025
Build a Drive quota early-warning system
Alert Northwind before storage runs out — email when usage crosses 80%.
Updated Oct 20, 2025
Enforce file naming and tagging governance
Flag Northwind files that don't match required naming or tagging conventions.
Updated Oct 16, 2025