Operations, training blocks, and selection cycles. Click any event for the full brief. Times are as listed — check the Discord for last-minute changes.
Adding events uses the cadre password — the same one that opens the Cadre Wing.
Insert a blank row directly under the header, click cell A2, and paste.
Your current script only knows how to write news posts. This version adds events and deletion for both pages, from the same deployment URL.
function doPost(e) {
var NEWS_SHEET = '1K0JrkBr1EDIqlZfhla7C9Dnauxl2br6QFa9QvV4NLsg';
var EVENTS_SHEET = '13jvcCd21NTmwCss9BUXh151Bf9Vi9akqWC7oV-V4M-A';
var PW_SHEET = '136R9Sl1JSmARjzXjEXd3T1CCoAlnlBqqMKUEnmvjPpA';
var out = function (o) {
return ContentService.createTextOutput(JSON.stringify(o))
.setMimeType(ContentService.MimeType.JSON);
};
function findRow(sh, titleCol, row, wanted) {
var last = sh.getLastRow();
row = parseInt(row, 10);
wanted = String(wanted || '').trim();
if (row >= 2 && row <= last &&
String(sh.getRange(row, titleCol).getValue()).trim() === wanted) return row;
if (wanted && last > 1) {
var col = sh.getRange(2, titleCol, last - 1, 1).getValues();
for (var i = 0; i < col.length; i++) {
if (String(col[i][0]).trim() === wanted) return i + 2;
}
}
return 0;
}
try {
var d = JSON.parse(e.postData.contents);
var pw = String(
SpreadsheetApp.openById(PW_SHEET).getSheets()[0].getRange('A1').getValue()
).trim();
if (String(d.pw || '').trim() !== pw) return out({ ok: false, error: 'bad password' });
var isEvents = (d.target === 'events');
var sh = SpreadsheetApp.openById(isEvents ? EVENTS_SHEET : NEWS_SHEET).getSheets()[0];
var titleCol = isEvents ? 4 : 2;
if (d.action === 'delete') {
var t = findRow(sh, titleCol, d.row, d.title);
if (!t) return out({ ok: false, error: 'row not found' });
sh.deleteRow(t);
return out({ ok: true, deleted: t });
}
if (d.action === 'pin') {
if (isEvents) return out({ ok: false, error: 'pin applies to news only' });
var p = findRow(sh, titleCol, d.row, d.title);
if (!p) return out({ ok: false, error: 'row not found' });
var cell = sh.getRange(p, 6);
cell.setNumberFormat('@');
cell.setValue(String(d.pinned || '').toUpperCase() === 'YES' ? 'YES' : 'NO');
return out({ ok: true, pinned: p });
}
var cols, values;
if (isEvents) {
cols = 7;
values = [[d.date || '', d.time || '', d.timezone || '', d.title || '',
d.type || '', d.location || '', d.description || '']];
} else {
cols = 6;
values = [[d.date || '', d.title || '', d.body || '',
d.image || '', d.author || '', d.pinned || 'NO']];
}
sh.insertRowAfter(1);
var rng = sh.getRange(2, 1, 1, cols);
rng.setNumberFormat('@');
rng.setValues(values);
return out({ ok: true });
} catch (err) {
return out({ ok: false, error: String(err) });
}
}