Step 1. Create a new Google Sheet.
Step 2. Extensions → Apps Script → replace all code with the script below → click Save.
▸ Show code
/*** CK VIDEOS CHECKLIST — Apps Script (Sheets + Calendar) ***/
/*** VERSION: 2026-06-22f ***/
function doGet(e) {
const p = e && e.parameter;
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('Data') || ss.insertSheet('Data');
if (p && p.action === 'load') {
return ContentService.createTextOutput(
JSON.stringify({
data: sheet.getRange('A1').getValue(),
teamNotes: sheet.getRange('C1').getValue()
})).setMimeType(ContentService.MimeType.JSON);
}
return ContentService.createTextOutput(JSON.stringify({ status: 'ok' }))
.setMimeType(ContentService.MimeType.JSON);
}
function doPost(e) {
const body = JSON.parse(e.postData.contents);
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('Data') || ss.insertSheet('Data');
if (body.action === 'save') {
const ex = sheet.getRange('A1').getValue();
const exTs = sheet.getRange('B1').getValue();
if (ex) {
const lr = sheet.getLastRow();
sheet.getRange('A' + (lr + 1)).setValue(ex);
sheet.getRange('B' + (lr + 1)).setValue(exTs);
}
sheet.getRange('A1').setValue(body.data);
sheet.getRange('B1').setValue(new Date().toISOString());
if (body.teamNotes !== undefined) sheet.getRange('C1').setValue(body.teamNotes);
if (body.humanRows && body.humanRows.length) {
let vs = ss.getSheetByName('Videos') || ss.insertSheet('Videos');
vs.clearContents();
vs.getRange(1,1,body.humanRows.length,body.humanRows[0].length).setValues(body.humanRows);
vs.getRange(1,1,1,body.humanRows[0].length).setFontWeight('bold');
vs.setFrozenRows(1);
}
}
if (body.action === 'calendar') {
const result = upsertCalendarEvent(body);
return ContentService.createTextOutput(JSON.stringify({ status: 'ok', cal: result }))
.setMimeType(ContentService.MimeType.JSON);
}
if (body.action === 'calendar_delete') {
const result = deleteCalendarEvent(body.itemId);
return ContentService.createTextOutput(JSON.stringify({ status: 'ok', cal: result }))
.setMimeType(ContentService.MimeType.JSON);
}
return ContentService.createTextOutput(JSON.stringify({ status: 'ok' }))
.setMimeType(ContentService.MimeType.JSON);
}
function upsertCalendarEvent(body) {
if (!body.itemId) return 'no-id';
const cal = CalendarApp.getDefaultCalendar();
const tag = '[CKVID:' + body.itemId + ']';
const start = new Date(body.start);
const end = new Date(start.getTime() + 60 * 60 * 1000);
const title = body.title || 'CK Video';
const desc = (body.desc || 'CK Videos Checklist') + '
' + tag;
const searchFrom = new Date(start.getTime() - 365 * 24 * 60 * 60 * 1000);
const searchTo = new Date(start.getTime() + 365 * 24 * 60 * 60 * 1000);
const events = cal.getEvents(searchFrom, searchTo);
let deleted = 0;
for (let i = 0; i < events.length; i++) {
if ((events[i].getDescription() || '').indexOf(tag) !== -1) {
events[i].deleteEvent(); deleted++;
}
}
cal.createEvent(title, start, end, { description: desc });
return deleted > 0 ? 'replaced' : 'created';
}
function deleteCalendarEvent(itemId) {
if (!itemId) return 'no-id';
const cal = CalendarApp.getDefaultCalendar();
const tag = '[CKVID:' + itemId + ']';
const now = new Date();
const from = new Date(now.getTime() - 2*365*24*60*60*1000);
const to = new Date(now.getTime() + 2*365*24*60*60*1000);
const events = cal.getEvents(from, to);
let deleted = 0;
for (let i = 0; i < events.length; i++) {
if ((events[i].getDescription() || '').indexOf(tag) !== -1) {
events[i].deleteEvent(); deleted++;
}
}
return deleted > 0 ? 'deleted-' + deleted : 'not-found';
}
function cleanupCountOnly() { return _cleanup(false); }
function cleanupDeleteNow() { return _cleanup(true); }
function _cleanup(reallyDelete) {
const cal = CalendarApp.getDefaultCalendar();
const now = new Date();
const from = new Date(now.getTime() - 2*365*24*60*60*1000);
const to = new Date(now.getTime() + 2*365*24*60*60*1000);
const events = cal.getEvents(from, to);
let hit = 0;
for (let i = 0; i < events.length; i++) {
const d = events[i].getDescription() || '';
const t = events[i].getTitle() || '';
if (d.indexOf('[CKVID:') !== -1 || d.indexOf('[CK Video]') !== -1 || t.indexOf('[CK Video]') !== -1) {
hit++; if (reallyDelete) events[i].deleteEvent();
}
}
const msg = (reallyDelete ? 'DELETED ' : 'WOULD DELETE ') + hit + ' events.';
Logger.log(msg); return msg;
}
Step 3. Deploy → New Deployment → Web App → Anyone → Copy URL.
Step 4. Paste URL above and save.