scan for deleted tickets
This commit is contained in:
@@ -16,7 +16,7 @@ const { handleDiscordReply } = require('./handlers/messages');
|
|||||||
|
|
||||||
// Services & jobs
|
// Services & jobs
|
||||||
const { sendTicketClosedEmail } = require('./services/gmail');
|
const { sendTicketClosedEmail } = require('./services/gmail');
|
||||||
const { checkAutoClose, checkAutoUnclaim } = require('./services/tickets');
|
const { checkAutoClose, checkAutoUnclaim, reconcileDeletedTicketChannels } = require('./services/tickets');
|
||||||
const { notifyAllStaffUnclaimed } = require('./services/staffNotifications');
|
const { notifyAllStaffUnclaimed } = require('./services/staffNotifications');
|
||||||
const { registerCommands } = require('./commands/register');
|
const { registerCommands } = require('./commands/register');
|
||||||
const bosscordRoutes = require('./routes/bosscord');
|
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);
|
setInterval(() => runChatAlertChecks(client).catch(e => console.error('runChatAlertChecks:', e)), 5 * 60 * 1000);
|
||||||
console.log('✓ Chat alert monitoring: every 5 minutes');
|
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) {
|
if (!CONFIG.STAFF_IDS.length) {
|
||||||
console.warn('[surgeChecker] STAFF_IDS is not set — zero-staff detection disabled.');
|
console.warn('[surgeChecker] STAFF_IDS is not set — zero-staff detection disabled.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ async function checkUnclaimedSurge(client) {
|
|||||||
const count = await Ticket.countDocuments({
|
const count = await Ticket.countDocuments({
|
||||||
status: 'open',
|
status: 'open',
|
||||||
claimedBy: null,
|
claimedBy: null,
|
||||||
createdAt: { $lte: cutoff }
|
createdAt: { $lte: cutoff, $ne: null }
|
||||||
});
|
});
|
||||||
if (count >= CONFIG.SURGE_UNCLAIMED_COUNT) {
|
if (count >= CONFIG.SURGE_UNCLAIMED_COUNT) {
|
||||||
setCooldown('surge:unclaimed');
|
setCooldown('surge:unclaimed');
|
||||||
@@ -123,7 +123,7 @@ async function checkTier3UnclaimedSurge(client) {
|
|||||||
status: 'open',
|
status: 'open',
|
||||||
escalationTier: 2,
|
escalationTier: 2,
|
||||||
claimedBy: null,
|
claimedBy: null,
|
||||||
createdAt: { $lte: cutoff }
|
createdAt: { $lte: cutoff, $ne: null }
|
||||||
}).lean();
|
}).lean();
|
||||||
if (tickets.length > 0) {
|
if (tickets.length > 0) {
|
||||||
setCooldown('surge:tier3_unclaimed');
|
setCooldown('surge:tier3_unclaimed');
|
||||||
|
|||||||
@@ -584,6 +584,39 @@ async function checkAutoUnclaim(client) {
|
|||||||
logAutomation('Auto-unclaim run', null, `checked: ${checked}, unclaimed: ${unclaimed}`).catch(() => {});
|
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 = {
|
module.exports = {
|
||||||
getNextTicketNumber,
|
getNextTicketNumber,
|
||||||
pickTicketCategoryId,
|
pickTicketCategoryId,
|
||||||
@@ -606,5 +639,6 @@ module.exports = {
|
|||||||
updateTicketActivity,
|
updateTicketActivity,
|
||||||
checkAutoClose,
|
checkAutoClose,
|
||||||
checkReminders,
|
checkReminders,
|
||||||
checkAutoUnclaim
|
checkAutoUnclaim,
|
||||||
|
reconcileDeletedTicketChannels
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user