Refactor ephemeral message handling in ticket interactions

- Updated ticket command and interaction responses to utilize the new `ephemeral()` function for consistent ephemeral message handling.
- Enhanced error handling for member fetching in ticket interactions, ensuring proper responses when members are not found.
- Improved localization for new error messages related to member presence in ticket commands.
- Documented changes in phase tracking to reflect updates in ticket interaction responses.
This commit is contained in:
TheOnlyMace
2026-07-25 16:32:30 +02:00
parent b5bf214d7f
commit 5f932f5d63
7 changed files with 118 additions and 30 deletions

View File

@@ -3,6 +3,7 @@ import { t, tf } from '@nexumi/shared';
import type { SlashCommand } from '../../types.js';
import { getGuildLocale } from '../../i18n.js';
import { requirePermission } from '../../permissions.js';
import { ephemeral } from '../../interaction-reply.js';
import { ticketCommandData } from './command-definitions.js';
import {
addUserToTicket,
@@ -26,7 +27,7 @@ async function ensureManageGuild(
locale: 'de' | 'en'
): Promise<boolean> {
if (!interaction.inGuild()) {
await interaction.reply({ content: t(locale, 'generic.guildOnly'), ephemeral: true });
await interaction.reply({ content: t(locale, 'generic.guildOnly'), ...ephemeral() });
return false;
}
return requirePermission(interaction, PermissionFlagsBits.ManageGuild, locale);
@@ -37,7 +38,7 @@ const ticketCommand: SlashCommand = {
async execute(interaction, context) {
const locale = await getGuildLocale(context.prisma, interaction.guildId);
if (!interaction.inGuild()) {
await interaction.reply({ content: t(locale, 'generic.guildOnly'), ephemeral: true });
await interaction.reply({ content: t(locale, 'generic.guildOnly'), ...ephemeral() });
return;
}
@@ -54,7 +55,10 @@ const ticketCommand: SlashCommand = {
const categories = await getGuildCategories(context, interaction.guildId!);
if (categories.length === 0) {
await interaction.reply({ content: t(locale, 'ticket.error.no_categories'), ephemeral: true });
await interaction.reply({
content: t(locale, 'ticket.error.no_categories'),
...ephemeral()
});
return;
}
@@ -62,7 +66,7 @@ const ticketCommand: SlashCommand = {
if (!channel?.isTextBased() || channel.isDMBased()) {
await interaction.reply({
content: t(locale, 'ticket.error.invalid_channel'),
ephemeral: true
...ephemeral()
});
return;
}
@@ -73,7 +77,7 @@ const ticketCommand: SlashCommand = {
title: name,
description
});
await interaction.reply({ content: t(locale, 'ticket.panel.created'), ephemeral: true });
await interaction.reply({ content: t(locale, 'ticket.panel.created'), ...ephemeral() });
} catch (error) {
if (error instanceof TicketPanelError) {
const key =
@@ -82,7 +86,7 @@ const ticketCommand: SlashCommand = {
: error.code === 'not_configured'
? 'ticket.error.invalid_channel'
: 'ticket.error.missing_permission';
await interaction.reply({ content: t(locale, key), ephemeral: true });
await interaction.reply({ content: t(locale, key), ...ephemeral() });
return;
}
throw error;
@@ -105,18 +109,28 @@ const ticketCommand: SlashCommand = {
);
await interaction.reply({
content: tf(locale, 'ticket.category.created', { name: category.name }),
ephemeral: true
...ephemeral()
});
return;
}
const ticket = await findTicketByChannel(context.prisma, interaction.channelId!);
if (!ticket) {
await interaction.reply({ content: t(locale, 'ticket.error.not_in_ticket'), ephemeral: true });
await interaction.reply({
content: t(locale, 'ticket.error.not_in_ticket'),
...ephemeral()
});
return;
}
const member = await interaction.guild!.members.fetch(interaction.user.id);
const member = await interaction.guild!.members.fetch(interaction.user.id).catch(() => null);
if (!member) {
await interaction.reply({
content: t(locale, 'ticket.error.member_not_found'),
...ephemeral()
});
return;
}
try {
if (sub === 'close') {
@@ -131,40 +145,57 @@ const ticketCommand: SlashCommand = {
const isOpener = ticket.openerId === interaction.user.id;
if (!isStaff && !isOpener) {
await interaction.reply({ content: t(locale, 'ticket.error.not_staff'), ephemeral: true });
await interaction.reply({
content: t(locale, 'ticket.error.not_staff'),
...ephemeral()
});
return;
}
const reason = interaction.options.getString('reason') ?? undefined;
await closeTicket(context, ticket, interaction.user.id, locale, reason);
await interaction.reply({ content: t(locale, 'ticket.close.success'), ephemeral: true });
await interaction.reply({ content: t(locale, 'ticket.close.success'), ...ephemeral() });
return;
}
if (sub === 'claim') {
await claimTicket(context, ticket, member, locale);
await interaction.reply({ content: t(locale, 'ticket.claim.success'), ephemeral: true });
await interaction.reply({ content: t(locale, 'ticket.claim.success'), ...ephemeral() });
return;
}
if (sub === 'add') {
const user = interaction.options.getUser('user', true);
const target = await interaction.guild!.members.fetch(user.id);
const target = await interaction.guild!.members.fetch(user.id).catch(() => null);
if (!target) {
await interaction.reply({
content: t(locale, 'ticket.error.member_not_found'),
...ephemeral()
});
return;
}
await addUserToTicket(context, ticket, member, target, locale);
await interaction.reply({
content: tf(locale, 'ticket.add.success', { user: `<@${user.id}>` }),
ephemeral: true
...ephemeral()
});
return;
}
if (sub === 'remove') {
const user = interaction.options.getUser('user', true);
const target = await interaction.guild!.members.fetch(user.id);
const target = await interaction.guild!.members.fetch(user.id).catch(() => null);
if (!target) {
await interaction.reply({
content: t(locale, 'ticket.error.member_not_found'),
...ephemeral()
});
return;
}
await removeUserFromTicket(context, ticket, member, target, locale);
await interaction.reply({
content: tf(locale, 'ticket.remove.success', { user: `<@${user.id}>` }),
ephemeral: true
...ephemeral()
});
return;
}
@@ -174,7 +205,7 @@ const ticketCommand: SlashCommand = {
await renameTicket(context, ticket, member, name, locale);
await interaction.reply({
content: tf(locale, 'ticket.rename.success', { name }),
ephemeral: true
...ephemeral()
});
return;
}
@@ -186,14 +217,14 @@ const ticketCommand: SlashCommand = {
content: tf(locale, 'ticket.priority.success', {
priority: t(locale, `ticket.priority.${level}`)
}),
ephemeral: true
...ephemeral()
});
}
} catch (error) {
if (error instanceof TicketError) {
await interaction.reply({
content: t(locale, `ticket.error.${error.code}`),
ephemeral: true
...ephemeral()
});
return;
}