scan for deleted tickets

This commit is contained in:
indifferentketchup
2026-04-07 10:15:58 -05:00
parent 7da082275f
commit 03794ceb25
3 changed files with 42 additions and 4 deletions

View File

@@ -16,7 +16,7 @@ const { handleDiscordReply } = require('./handlers/messages');
// Services & jobs
const { sendTicketClosedEmail } = require('./services/gmail');
const { checkAutoClose, checkAutoUnclaim } = require('./services/tickets');
const { checkAutoClose, checkAutoUnclaim, reconcileDeletedTicketChannels } = require('./services/tickets');
const { notifyAllStaffUnclaimed } = require('./services/staffNotifications');
const { registerCommands } = require('./commands/register');
const bosscordRoutes = require('./routes/bosscord');
@@ -203,6 +203,10 @@ client.once('ready', async () => {
setInterval(() => runChatAlertChecks(client).catch(e => console.error('runChatAlertChecks:', e)), 5 * 60 * 1000);
console.log('✓ Chat alert monitoring: every 5 minutes');
reconcileDeletedTicketChannels(client).catch(e => console.error('reconcileDeletedTicketChannels:', e));
setInterval(() => reconcileDeletedTicketChannels(client).catch(e => console.error('reconcileDeletedTicketChannels:', e)), 60 * 60 * 1000);
console.log('✓ Reconcile deleted ticket channels: every 1 hour');
if (!CONFIG.STAFF_IDS.length) {
console.warn('[surgeChecker] STAFF_IDS is not set — zero-staff detection disabled.');
}

View File

@@ -105,7 +105,7 @@ async function checkUnclaimedSurge(client) {
const count = await Ticket.countDocuments({
status: 'open',
claimedBy: null,
createdAt: { $lte: cutoff }
createdAt: { $lte: cutoff, $ne: null }
});
if (count >= CONFIG.SURGE_UNCLAIMED_COUNT) {
setCooldown('surge:unclaimed');
@@ -123,7 +123,7 @@ async function checkTier3UnclaimedSurge(client) {
status: 'open',
escalationTier: 2,
claimedBy: null,
createdAt: { $lte: cutoff }
createdAt: { $lte: cutoff, $ne: null }
}).lean();
if (tickets.length > 0) {
setCooldown('surge:tier3_unclaimed');

View File

@@ -584,6 +584,39 @@ async function checkAutoUnclaim(client) {
logAutomation('Auto-unclaim run', null, `checked: ${checked}, unclaimed: ${unclaimed}`).catch(() => {});
}
async function reconcileDeletedTicketChannels(client) {
const guild = client.guilds.cache.get(CONFIG.DISCORD_GUILD_ID) || client.guilds.cache.first();
if (!guild) return { checked: 0, reconciled: 0 };
const openTickets = await Ticket.find({
status: 'open',
discordThreadId: { $ne: null }
}).lean();
let checked = 0, reconciled = 0;
for (const ticket of openTickets) {
checked++;
try {
let channel = guild.channels.cache.get(ticket.discordThreadId);
if (!channel) {
channel = await guild.channels.fetch(ticket.discordThreadId).catch(() => null);
}
if (!channel) {
await Ticket.updateOne(
{ gmailThreadId: ticket.gmailThreadId },
{ $set: { status: 'closed', discordThreadId: null } }
);
logAutomation('Reconcile: channel deleted', ticket.discordThreadId, `ticket #${ticket.ticketNumber}`).catch(() => {});
reconciled++;
}
} catch (err) {
console.error(`reconcileDeletedTicketChannels error for ${ticket.gmailThreadId}:`, err);
}
}
logAutomation('Reconcile run', null, `checked: ${checked}, reconciled: ${reconciled}`).catch(() => {});
return { checked, reconciled };
}
module.exports = {
getNextTicketNumber,
pickTicketCategoryId,
@@ -606,5 +639,6 @@ module.exports = {
updateTicketActivity,
checkAutoClose,
checkReminders,
checkAutoUnclaim
checkAutoUnclaim,
reconcileDeletedTicketChannels
};