Consolidate schedule config, support multi-post per day

- Schedule config moved to nested schedule object in prompts.json
- Scheduler picks 1-3 random times for personality with 4hr min gap
- shouldRun reads from schedule object

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matt Jackson
2026-03-07 23:12:29 +00:00
parent 417f943239
commit d2ca2d23ba
3 changed files with 87 additions and 37 deletions

View File

@@ -19,33 +19,72 @@ if (!config) {
process.exit(1);
}
// Pick a random time in the window
const windowMinutes = (config.endHour - config.startHour) * 60;
const delayMinutes = Math.floor(Math.random() * windowMinutes);
const hours = Math.floor(delayMinutes / 60) + config.startHour;
const minutes = delayMinutes % 60;
const schedule = config.schedule;
const [startHour, endHour] = schedule.window;
const minGap = (schedule.minGapHours || 4) * 60;
const pad = (n) => String(n).padStart(2, "0");
console.log(`[${promptName}] Scheduled for ${pad(hours)}:${pad(minutes)} PST`);
const now = new Date(
new Date().toLocaleString("en-US", { timeZone: "America/Los_Angeles" })
);
const target = new Date(now);
target.setHours(hours, minutes, 0, 0);
let delayMs = target.getTime() - now.getTime();
if (delayMs <= 0) {
console.log("Target time passed. Posting now.");
delayMs = 0;
function randomMinuteInWindow() {
const windowMinutes = (endHour - startHour) * 60;
return Math.floor(Math.random() * windowMinutes);
}
console.log(`Waiting ${Math.round(delayMs / 60000)} minutes...`);
function pickSpacedTimes(count) {
for (let attempt = 0; attempt < 100; attempt++) {
const times = Array.from({ length: count }, () => randomMinuteInWindow()).sort((a, b) => a - b);
let valid = true;
for (let i = 1; i < times.length; i++) {
if (times[i] - times[i - 1] < minGap) {
valid = false;
break;
}
}
if (valid) return times;
}
const window = (endHour - startHour) * 60;
const gap = Math.floor(window / (count + 1));
return Array.from({ length: count }, (_, i) => gap * (i + 1));
}
setTimeout(() => {
function nowPST() {
return new Date(new Date().toLocaleString("en-US", { timeZone: "America/Los_Angeles" }));
}
function runBot() {
try {
execFileSync("node", [join(__dirname, "bot.js"), promptName], { stdio: "inherit" });
} catch {
process.exit(1);
console.error(`[${promptName}] bot.js failed`);
}
}, delayMs);
}
const [minPerDay, maxPerDay] = schedule.postsPerDay || [1, 1];
const count = Math.floor(Math.random() * (maxPerDay - minPerDay + 1)) + minPerDay;
const times = pickSpacedTimes(count);
const pad = (n) => String(n).padStart(2, "0");
const scheduled = times.map((m) => `${pad(Math.floor(m / 60) + startHour)}:${pad(m % 60)}`);
console.log(`[${promptName}] ${count} post(s) scheduled at: ${scheduled.join(", ")} PST`);
function scheduleNext(index) {
if (index >= times.length) return;
const minutes = times[index];
const hours = Math.floor(minutes / 60) + startHour;
const mins = minutes % 60;
const now = nowPST();
const target = new Date(now);
target.setHours(hours, mins, 0, 0);
let delayMs = target.getTime() - now.getTime();
if (delayMs < 0) delayMs = 0;
console.log(`[${promptName}] #${index + 1} in ${Math.round(delayMs / 60000)} minutes`);
setTimeout(() => {
runBot();
scheduleNext(index + 1);
}, delayMs);
}
scheduleNext(0);