Skip to content

Commit c647e73

Browse files
committed
[Feat]: enhance ticket system with reaction handling and ephemeral responses
1 parent 6a749e0 commit c647e73

File tree

3 files changed

+28
-12
lines changed

3 files changed

+28
-12
lines changed

src/commands/ticket-close.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,33 @@
11
import { SlashCommandBuilder, PermissionsBitField } from 'discord.js';
22
import { buildEmbed } from '../utils/embed';
33

4+
const EPHEMERAL_FLAG = 1 << 6;
5+
46
const data = new SlashCommandBuilder()
57
.setName('ticketclose')
68
.setDescription('Cierra el ticket actual (solo junta)');
79

810
async function execute(interaction: any) {
911
// Require MANAGE_CHANNELS or equivalent (JUNTA). Adjust to your role check if needed.
1012
if (!interaction.memberPermissions?.has(PermissionsBitField.Flags.ManageChannels)) {
11-
return interaction.reply({ content: 'Solo JUNTA puede cerrar tickets.', ephemeral: true });
13+
return interaction.reply({
14+
content: 'Solo JUNTA puede cerrar tickets.',
15+
flags: EPHEMERAL_FLAG,
16+
});
1217
}
1318
const channel = interaction.channel;
1419
const category = channel?.parent;
1520
try {
16-
await interaction.reply({
21+
const respond =
22+
interaction.deferred || interaction.replied
23+
? interaction.editReply.bind(interaction)
24+
: interaction.reply.bind(interaction);
25+
26+
await respond({
1727
embeds: [buildEmbed({ title: 'Ticket', description: 'Ticket cerrado' })],
18-
ephemeral: true,
28+
flags: EPHEMERAL_FLAG,
1929
});
30+
2031
if (channel && channel.deletable) await channel.delete('Ticket cerrado');
2132
if (category && category.children) {
2233
for await (const child of category.children.cache.values()) {
@@ -26,7 +37,7 @@ async function execute(interaction: any) {
2637
}
2738
} catch (err) {
2839
console.error('Error closing ticket', err);
29-
await interaction.followUp?.({ content: 'Error al cerrar el ticket.', ephemeral: true });
40+
await interaction.followUp?.({ content: 'Error al cerrar el ticket.', flags: EPHEMERAL_FLAG });
3041
}
3142
}
3243

src/events/messageReactionAdd.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,22 @@ export default {
88
async execute(reaction: any, user: any) {
99
try {
1010
if (user.bot) return;
11-
const guild = reaction.message.guild;
11+
if (reaction.partial) await reaction.fetch();
12+
if (reaction.message?.partial) await reaction.message.fetch();
13+
const guild = reaction.message?.guild;
1214
if (!guild) return;
15+
1316
const cfg = getGuildConfig(guild.id);
1417
if (!cfg?.channels.ticketTrigger) return;
1518
if (reaction.message.channelId !== cfg.channels.ticketTrigger) return;
19+
if (reaction.emoji?.name !== '🎫') return;
1620

17-
// Ensure full reaction/message data
18-
if (reaction.partial) await reaction.fetch();
19-
if (reaction.message.partial) await reaction.message.fetch();
20-
21-
// Only respond to 🎫
22-
if (reaction.emoji.name !== '🎫') return;
21+
// Remove the user's reaction to keep the trigger clean
22+
try {
23+
await reaction.users.remove(user.id).catch(() => {});
24+
} catch (err) {
25+
console.error('Failed to remove reaction', err);
26+
}
2327

2428
// Create category for the ticket
2529
const category = await guild.channels.create({

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ const client: BotClient = new Client({
4040
GatewayIntentBits.MessageContent,
4141
GatewayIntentBits.DirectMessages,
4242
GatewayIntentBits.GuildVoiceStates,
43+
GatewayIntentBits.GuildMessageReactions,
4344
],
44-
partials: [Partials.Channel],
45+
partials: [Partials.Channel, Partials.Message, Partials.Reaction, Partials.User],
4546
}) as BotClient;
4647
client.commands = new Collection();
4748

0 commit comments

Comments
 (0)