Operational notices, selection cycles, training schedules, and unit updates from Battalion HQ.
Posting uses the cadre password — the same one that opens the Cadre Wing.
Images are linked, not uploaded — paste a direct link ending in .png or .jpg. Imgur works well. Avoid Discord attachment links: they expire and will break.
Insert a blank row directly under the header, click cell A2, and paste. The row splits itself across the columns.
To delete and pin from the site, replace your script with the version below and redeploy as a New version — saving alone will not update the live URL.
/exec 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) });
}
}