Remove dead/stale code, dedup close+escalation paths
Dead/stale removals (grep-confirmed no consumers):
- config: drop 9 unread CONFIG keys (ROLE_TO_PING_ID, SIGNATURE,
REMINDER_*, RENAME_LOG_CHANNEL_ID, SETTINGS_*); remove their
ALLOWED_CONFIG_KEYS entries and the orphaned settings-site UI fields
- configSchema: delete unreachable json/string_or_json validators
- models: drop unused ticketTag field
- gmail-poll: remove unused isPollSuspended export
- utils: remove dead htmlToTextWithBlocks/decodeHtmlEntities/BLOCK_TAG_REGEX
- internalApi: remove router._allowedKeys (test it served is gone)
- discord client: drop unused GuildPresences privileged intent
- broccolini-discord: remove dormant /api 503 gate (no /api routes)
Fixes:
- context-menu ticket create now uses makeTicketName('unclaimed', ...)
instead of the contract-violating ticket-<n> name
- drop write-only pending.userId from both close paths
Dedup / simplify:
- new services/transcript.js shares the transcript text/date/header
builders between the button and force-close paths (had drifted)
- resolveEscalationCategoryId() replaces 3 copies of the category logic
- ticketChannelOverwrites() shares the create-permission array between
the two interactive ticket-create paths
- finalizeBody() shares the email-cleanup tail in parseGmailMessage
- getTicketActionRow drops its never-passed options arg;
sendTicketNotificationEmail drops its always-null subjectLine arg
- hoist invariant guild lookup out of the auto-close/unclaim loops
- drop redundant lastActivity write (and now-dead updateTicketActivity)
- /help lists all current commands and the right-click apps
This commit is contained in:
@@ -16,7 +16,6 @@ const {
|
||||
AttachmentBuilder,
|
||||
EmbedBuilder,
|
||||
MessageFlags,
|
||||
PermissionFlagsBits,
|
||||
ModalBuilder,
|
||||
TextInputBuilder,
|
||||
TextInputStyle
|
||||
@@ -25,10 +24,11 @@ const { mongoose } = require('../db-connection');
|
||||
const { CONFIG } = require('../config');
|
||||
const { makeTicketName, resolveCreatorNickname, getOrCreateTicketCategory, cleanupEmptyOverflowCategory, checkTicketCreationRateLimit, toDiscordSafeName } = require('../services/tickets');
|
||||
const { sendTicketClosedEmail } = require('../services/gmail');
|
||||
const { getTicketActionRow } = require('../utils/ticketComponents');
|
||||
const { getTicketActionRow, ticketChannelOverwrites } = require('../utils/ticketComponents');
|
||||
const { buildTranscriptText, formatDateForTranscript, renderTranscriptHeader } = require('../services/transcript');
|
||||
const { sanitizeEmbedText, truncateEmbedDescription } = require('../utils');
|
||||
const { enqueueRename, enqueueSend } = require('../services/channelQueue');
|
||||
const { runEscalation, runDeescalation } = require('./commands');
|
||||
const { runEscalation, runDeescalation, resolveEscalationCategoryId } = require('./commands');
|
||||
const { pendingCloses } = require('./pendingCloses');
|
||||
const { addMemberToStaffThread, createStaffThread } = require('../services/staffThread');
|
||||
const { pinMessage } = require('../services/pinMessage');
|
||||
@@ -309,7 +309,7 @@ async function handleConfirmCloseRequest(interaction, ticket) {
|
||||
await runFinalClose(interaction, freshTicket, effectiveSendEmail);
|
||||
}, timerSeconds * 1000));
|
||||
|
||||
pendingCloses.set(channelId, { timeout: timerId, userId: interaction.user.id, username: userTag, sendEmail });
|
||||
pendingCloses.set(channelId, { timeout: timerId, username: userTag, sendEmail });
|
||||
}
|
||||
|
||||
async function handleCancelCloseRequest(interaction) {
|
||||
@@ -358,10 +358,7 @@ async function handleEscalateButton(interaction, ticket) {
|
||||
return interaction.reply({ content: `This ticket is already at tier ${tier + 1}.`, flags: MessageFlags.Ephemeral });
|
||||
}
|
||||
|
||||
const isDiscordTicket = ticket.gmailThreadId.startsWith('discord-');
|
||||
const categoryId = tier === 1
|
||||
? (isDiscordTicket ? CONFIG.DISCORD_ESCALATED2_CHANNEL_ID : CONFIG.EMAIL_ESCALATED2_CHANNEL_ID)
|
||||
: (isDiscordTicket ? CONFIG.DISCORD_ESCALATED3_CHANNEL_ID : CONFIG.EMAIL_ESCALATED3_CHANNEL_ID);
|
||||
const categoryId = resolveEscalationCategoryId(ticket, tier);
|
||||
|
||||
if (!categoryId && !interaction.channel.isThread()) {
|
||||
return interaction.reply({
|
||||
@@ -474,33 +471,6 @@ async function runFinalClose(interaction, ticket, sendEmail = true) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Render the last 100 messages of a channel as a plaintext transcript. */
|
||||
async function buildTranscriptText(channel, ticket) {
|
||||
const messages = await channel.messages.fetch({ limit: 100 });
|
||||
return `TRANSCRIPT: ${ticket.subject}\nUser: ${ticket.senderEmail}\n---\n` +
|
||||
messages
|
||||
.reverse()
|
||||
.map(m => `[${m.createdAt.toLocaleString()}] ${m.author.tag}: ${m.cleanContent}`)
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
function formatDateForTranscript(d) {
|
||||
return new Date(d).toLocaleString('en-US', {
|
||||
month: '2-digit', day: '2-digit', year: 'numeric',
|
||||
hour: '2-digit', minute: '2-digit', second: '2-digit',
|
||||
hour12: true, timeZoneName: 'short'
|
||||
});
|
||||
}
|
||||
|
||||
function renderTranscriptHeader(channelName, senderEmail, openedStr, closedStr) {
|
||||
return CONFIG.DISCORD_TRANSCRIPT_MESSAGE
|
||||
.replace(/\{channel_name\}/g, channelName)
|
||||
.replace(/\{email\}/g, senderEmail || '')
|
||||
.replace(/\{date_opened\}/g, openedStr)
|
||||
.replace(/\{date_closed\}/g, closedStr)
|
||||
+ `\n\nDate Opened: ${openedStr}\nDate Closed: ${closedStr}`;
|
||||
}
|
||||
|
||||
async function dmTranscriptToCreator(client, ticket, channelName, transcriptText, openedStr, closedStr) {
|
||||
// Prefer ticket.creatorId (stored on creation). Fall back to legacy parsing for
|
||||
// pre-creatorId modal tickets only — split-pop returns the wrong value for
|
||||
@@ -601,17 +571,7 @@ async function handleTicketModal(interaction) {
|
||||
name: unclaimedName,
|
||||
type: ChannelType.GuildText,
|
||||
parent: parentCategoryIdForTicket,
|
||||
permissionOverwrites: [
|
||||
{ id: guild.id, deny: [PermissionFlagsBits.ViewChannel] },
|
||||
{
|
||||
id: interaction.user.id,
|
||||
allow: [PermissionFlagsBits.ViewChannel, PermissionFlagsBits.SendMessages, PermissionFlagsBits.ReadMessageHistory]
|
||||
},
|
||||
{
|
||||
id: CONFIG.ROLE_ID_TO_PING,
|
||||
allow: [PermissionFlagsBits.ViewChannel, PermissionFlagsBits.SendMessages, PermissionFlagsBits.ReadMessageHistory]
|
||||
}
|
||||
]
|
||||
permissionOverwrites: ticketChannelOverwrites(guild, interaction.user.id)
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('guild.channels.create (ticket modal):', err);
|
||||
|
||||
Reference in New Issue
Block a user