more mvp strip

This commit is contained in:
2026-04-21 17:24:03 +00:00
parent 6d579207f3
commit f3ee27ed7a
17 changed files with 598 additions and 1088 deletions

View File

@@ -13,14 +13,12 @@ const {
const { mongoose } = require('../db-connection');
const { CONFIG } = require('../config');
const { getPriorityEmoji, replaceVariables } = require('../utils');
const { makeTicketName, resolveCreatorNickname, getOrCreateTicketCategory, createDiscordTicketAsThread, checkTicketCreationRateLimit } = require('../services/tickets');
const { makeTicketName, resolveCreatorNickname, getOrCreateTicketCategory, checkTicketCreationRateLimit } = require('../services/tickets');
const { sendTicketNotificationEmail } = require('../services/gmail');
const { getTicketActionRow } = require('../utils/ticketComponents');
const { getEmailRouting } = require('../services/guildSettings');
const { enqueueRename, enqueueMove, enqueueSend } = require('../services/channelQueue');
const { setNotifyDm } = require('../services/staffSettings');
const { logTicketEvent, logSecurity, logError } = require('../services/debugLog');
const { handleSetupCommand } = require('./setup');
const { pendingCloses } = require('./pendingCloses');
const Ticket = mongoose.model('Ticket');
@@ -221,39 +219,6 @@ async function handleCommand(interaction) {
// Only /help can be used by everyone; all other commands require staff role (ROLE_ID_TO_PING / ADDITIONAL_STAFF_ROLES)
if (interaction.commandName !== 'help' && (await requireStaffRole(interaction))) return;
// /setup
if (interaction.commandName === 'setup') {
return handleSetupCommand(interaction);
}
// /email-routing switch where new email tickets are created (thread vs category)
if (interaction.commandName === 'email-routing') {
await interaction.deferReply({ ephemeral: true });
try {
const current = await getEmailRouting(interaction.guild.id);
const row = new ActionRowBuilder().addComponents(
new ButtonBuilder()
.setCustomId('email_routing_thread')
.setLabel('Threads')
.setStyle(ButtonStyle.Primary)
.setEmoji('🧵'),
new ButtonBuilder()
.setCustomId('email_routing_category')
.setLabel('Category channels')
.setStyle(ButtonStyle.Primary)
.setEmoji('📁')
);
await interaction.editReply({
content: `Email ticket routing: **${current}**. Choose where new email tickets should be created:`,
components: [row]
});
} catch (err) {
logError('email-routing-command', err, interaction).catch(() => {});
await interaction.editReply('Failed to load routing options.').catch(() => {});
}
return;
}
// /escalate (tier 2 or 3 via level; works for both email and Discord). Always unclaims on escalate.
if (interaction.commandName === 'escalate') {
const reason = null;
@@ -926,48 +891,38 @@ async function handleContextMenu(interaction) {
let channel;
let parentCategoryIdForTicket = null;
if (CONFIG.DISCORD_THREAD_CHANNEL_ID) {
try {
channel = await createDiscordTicketAsThread(guild, ticketNumber, message.author.id);
parentCategoryIdForTicket = channel.parent?.parentId ?? null;
} catch (err) {
console.error('Discord ticket thread create (from message) failed:', err.message);
return interaction.editReply('❌ Could not create ticket thread. Check DISCORD_THREAD_CHANNEL_ID.');
}
} else {
let parentId;
try {
parentId = await getOrCreateTicketCategory(
guild,
CONFIG.DISCORD_TICKET_CATEGORY_ID,
CONFIG.TICKET_CATEGORY_NAME
);
} catch (err) {
console.error('getOrCreateTicketCategory (context menu ticket):', err);
return interaction.editReply('❌ Discord ticket category could not be resolved. Contact an administrator.');
}
parentCategoryIdForTicket = parentId;
try {
channel = await guild.channels.create({
name: `ticket-${ticketNumber}`,
type: ChannelType.GuildText,
parent: parentId,
permissionOverwrites: [
{ id: guild.id, deny: [PermissionFlagsBits.ViewChannel] },
{
id: message.author.id,
allow: [PermissionFlagsBits.ViewChannel, PermissionFlagsBits.SendMessages, PermissionFlagsBits.ReadMessageHistory]
},
{
id: CONFIG.ROLE_ID_TO_PING,
allow: [PermissionFlagsBits.ViewChannel, PermissionFlagsBits.SendMessages, PermissionFlagsBits.ReadMessageHistory]
}
]
});
} catch (err) {
console.error('guild.channels.create (context menu ticket):', err);
return interaction.editReply('❌ Failed to create ticket channel. Contact an administrator.');
}
let parentId;
try {
parentId = await getOrCreateTicketCategory(
guild,
CONFIG.DISCORD_TICKET_CATEGORY_ID,
CONFIG.TICKET_CATEGORY_NAME
);
} catch (err) {
console.error('getOrCreateTicketCategory (context menu ticket):', err);
return interaction.editReply('❌ Discord ticket category could not be resolved. Contact an administrator.');
}
parentCategoryIdForTicket = parentId;
try {
channel = await guild.channels.create({
name: `ticket-${ticketNumber}`,
type: ChannelType.GuildText,
parent: parentId,
permissionOverwrites: [
{ id: guild.id, deny: [PermissionFlagsBits.ViewChannel] },
{
id: message.author.id,
allow: [PermissionFlagsBits.ViewChannel, PermissionFlagsBits.SendMessages, PermissionFlagsBits.ReadMessageHistory]
},
{
id: CONFIG.ROLE_ID_TO_PING,
allow: [PermissionFlagsBits.ViewChannel, PermissionFlagsBits.SendMessages, PermissionFlagsBits.ReadMessageHistory]
}
]
});
} catch (err) {
console.error('guild.channels.create (context menu ticket):', err);
return interaction.editReply('❌ Failed to create ticket channel. Contact an administrator.');
}
const gmailThreadId = `discord-msg-${Date.now()}-${message.id}`;