Fix scheduled events not executing due to property name mismatch

The scheduler was correctly scheduling events but they weren't executing because the code was checking for camelCase property names (channelId, pingRoleId) while the database returns snake_case names (channel_id, ping_role_id). This caused channel and role validation to be skipped, resulting in silent failures.

Also added sqlite3 CLI to Docker container for debugging database issues.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Chris Ham
2025-08-17 09:53:38 -07:00
parent 8823eac094
commit 5d72159cb2
2 changed files with 48 additions and 32 deletions

View File

@@ -1,6 +1,8 @@
# Use Node 20 LTS with full Debian for better compatibility # Use Node 20 LTS with full Debian for better compatibility
FROM node:20 FROM node:20
RUN apt update && apt install -y sqlite3
WORKDIR /app WORKDIR /app
# Copy package files (npm will work better for native modules in Docker) # Copy package files (npm will work better for native modules in Docker)

View File

@@ -1,4 +1,4 @@
const schedule = require('node-schedule'); const schedule = require("node-schedule");
class SchedulerService { class SchedulerService {
constructor() { constructor() {
@@ -11,7 +11,7 @@ class SchedulerService {
* @param {ConfigManager} configManager * @param {ConfigManager} configManager
*/ */
async initialize(client, configManager) { async initialize(client, configManager) {
console.log('Initializing scheduled events...'); console.log("Initializing scheduled events...");
const guildConfigs = configManager.getAllGuildConfigs(); const guildConfigs = configManager.getAllGuildConfigs();
@@ -27,17 +27,22 @@ class SchedulerService {
const databaseService = configManager.databaseService; const databaseService = configManager.databaseService;
if (!databaseService) continue; if (!databaseService) continue;
const scheduledEvents = databaseService.getScheduledEvents(guildConfig.id); const scheduledEvents = databaseService.getScheduledEvents(
guildConfig.id
);
if (!scheduledEvents || scheduledEvents.length === 0) { if (!scheduledEvents || scheduledEvents.length === 0) {
continue; continue;
} }
for (const event of scheduledEvents) { for (const event of scheduledEvents) {
await this.scheduleEvent(guild, event, guildConfig); await this.scheduleEvent(guild, event);
} }
} catch (error) { } catch (error) {
console.error(`Error setting up scheduled events for guild ${guildConfig.id}:`, error); console.error(
`Error setting up scheduled events for guild ${guildConfig.id}:`,
error
);
} }
} }
} }
@@ -46,26 +51,29 @@ class SchedulerService {
* Schedule a single event * Schedule a single event
* @param {Guild} guild * @param {Guild} guild
* @param {Object} event * @param {Object} event
* @param {Object} guildConfig
*/ */
async scheduleEvent(guild, event, guildConfig) { async scheduleEvent(guild, event) {
try { try {
// Validate channel // Validate channel
let channel = null; let channel = null;
if (event.channelId) { if (event.channel_id) {
channel = await guild.channels.fetch(event.channelId); channel = await guild.channels.fetch(event.channel_id);
if (!channel) { if (!channel) {
console.error(`Invalid channel ${event.channelId} for event ${event.id} in guild ${guild.name}`); console.error(
`Invalid channel ${event.channel_id} for event ${event.id} in guild ${guild.name}`
);
return; return;
} }
} }
// Validate role // Validate role
let pingRole = null; let pingRole = null;
if (event.pingRoleId) { if (event.ping_role_id) {
pingRole = await guild.roles.fetch(event.pingRoleId); pingRole = await guild.roles.fetch(event.ping_role_id);
if (!pingRole) { if (!pingRole) {
console.warn(`Invalid role ${event.pingRoleId} for event ${event.id} in guild ${guild.name}`); console.warn(
`Invalid role ${event.ping_role_id} for event ${event.id} in guild ${guild.name}`
);
} }
} }
@@ -81,9 +89,15 @@ class SchedulerService {
const jobKey = `${guild.id}-${event.id}`; const jobKey = `${guild.id}-${event.id}`;
this.jobs.set(jobKey, job); this.jobs.set(jobKey, job);
console.log(`Event ${event.id} scheduled. Next invocation: ${job.nextInvocation()}`); console.log(
`Event ${
event.id
} scheduled. Next invocation: ${job.nextInvocation()}`
);
} else { } else {
console.error(`Failed to schedule event ${event.id} - invalid cron expression: ${event.schedule}`); console.error(
`Failed to schedule event ${event.id} with schedule: ${event.schedule}`
);
} }
} catch (error) { } catch (error) {
console.error(`Error scheduling event ${event.id}:`, error); console.error(`Error scheduling event ${event.id}:`, error);
@@ -112,7 +126,7 @@ class SchedulerService {
// Send the message // Send the message
if (content.length > 0 && channel) { if (content.length > 0 && channel) {
await channel.send(content.join(' ')); await channel.send(content.join(" "));
console.log(`Executed scheduled event ${event.id}`); console.log(`Executed scheduled event ${event.id}`);
} }
} catch (error) { } catch (error) {
@@ -158,7 +172,7 @@ class SchedulerService {
job.cancel(); job.cancel();
} }
this.jobs.clear(); this.jobs.clear();
console.log('Cancelled all scheduled events'); console.log("Cancelled all scheduled events");
} }
} }