diff --git a/commands/register.js b/commands/register.js index 1a4c512..c525063 100644 --- a/commands/register.js +++ b/commands/register.js @@ -544,6 +544,13 @@ async function registerCommands() { .setIntegrationTypes([ApplicationIntegrationType.GuildInstall]) .setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages), + new SlashCommandBuilder() + .setName('fix-stale-tickets') + .setDescription('Admin only: backfill lastActivity on open tickets where it is null (sets to createdAt).') + .setContexts([InteractionContextType.Guild]) + .setIntegrationTypes([ApplicationIntegrationType.GuildInstall]) + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + new SlashCommandBuilder() .setName('accountinfo') .setDescription('Look up website account info by email or Discord user') diff --git a/handlers/buttons.js b/handlers/buttons.js index d44f8fe..6da6cca 100644 --- a/handlers/buttons.js +++ b/handlers/buttons.js @@ -706,8 +706,7 @@ async function handleTicketModal(interaction) { .setTitle("We got your ticket.") .setDescription("We'll be with you as soon as possible.") .setColor(5763719) - .setThumbnail("https://indifferentbroccoli.com/img/broccoli_shadow_square.png") - .setFooter({ text: "indifferent broccoli tickets (:|)", iconURL: "https://i.ibb.co/sJdytfFM/Untitled-design-6.png" }); + .setThumbnail("https://indifferentbroccoli.com/img/broccoli_shadow_square.png"); const infoEmbed = new EmbedBuilder() .setColor(5763719) diff --git a/handlers/commands.js b/handlers/commands.js index 63b9c56..9f4d936 100644 --- a/handlers/commands.js +++ b/handlers/commands.js @@ -1156,6 +1156,24 @@ async function handleCommand(interaction) { } } + // /fix-stale-tickets + if (interaction.commandName === 'fix-stale-tickets') { + if (interaction.user.id !== CONFIG.ADMIN_ID) { + return interaction.reply({ content: 'You do not have permission to run this command.', ephemeral: true }); + } + await interaction.deferReply({ ephemeral: true }); + try { + const result = await Ticket.updateMany( + { status: 'open', lastActivity: null }, + [{ $set: { lastActivity: '$createdAt' } }] + ); + await interaction.editReply(`Fixed ${result.modifiedCount} ticket(s).`); + } catch (err) { + console.error('fix-stale-tickets:', err); + await interaction.editReply('❌ Failed to backfill tickets.').catch(() => {}); + } + } + // /stats if (interaction.commandName === 'stats') { trackInteraction('commands', 'stats', interaction.user.tag); diff --git a/services/surgeChecker.js b/services/surgeChecker.js index 0a3124f..64ff55c 100644 --- a/services/surgeChecker.js +++ b/services/surgeChecker.js @@ -71,7 +71,7 @@ async function checkStaleSurge(client) { const cutoff = new Date(Date.now() - CONFIG.SURGE_STALE_HOURS * 3600000); const count = await Ticket.countDocuments({ status: 'open', - lastActivity: { $lte: cutoff } + lastActivity: { $lte: cutoff, $ne: null } }); if (count >= CONFIG.SURGE_STALE_COUNT) { setCooldown('surge:stale'); @@ -88,7 +88,7 @@ async function checkNeedsResponseSurge(client) { const count = await Ticket.countDocuments({ status: 'open', lastMessageAuthorIsStaff: false, - lastActivity: { $lte: cutoff } + lastActivity: { $lte: cutoff, $ne: null } }); if (count >= CONFIG.SURGE_NEEDS_RESPONSE_COUNT) { setCooldown('surge:needs_response');