Implement overdue giveaway recovery and enhance giveaway command handling

- Added functionality to recover overdue giveaways during bot startup, ensuring that giveaways that have passed their end time are processed correctly.
- Introduced `cancelGiveawayJob` to safely remove scheduled jobs, preventing issues with locked jobs.
- Updated giveaway command handling to trim IDs and validate existence within the guild context, improving error handling and user feedback.
- Enhanced the role picker component to normalize search queries and handle errors more gracefully, improving user experience.
- Implemented caching strategies for guild roles to avoid stale or empty responses, ensuring more reliable data retrieval.
This commit is contained in:
TheOnlyMace
2026-07-24 21:49:20 +02:00
parent c7fb3d7041
commit 57cdf847f5
10 changed files with 301 additions and 51 deletions

View File

@@ -6,6 +6,7 @@ import { requirePermission } from '../../permissions.js';
import { parseDuration } from '../moderation/duration.js';
import { giveawayCommandData } from './command-definitions.js';
import {
cancelGiveawayJob,
deleteGiveaway,
endGiveaway,
GiveawayError,
@@ -100,14 +101,23 @@ const giveawayCommand: SlashCommand = {
try {
if (sub === 'end') {
const id = interaction.options.getString('id', true);
const id = interaction.options.getString('id', true).trim();
const giveaway = await context.prisma.giveaway.findUnique({ where: { id } });
if (!giveaway || giveaway.guildId !== interaction.guildId) {
throw new GiveawayError('not_found');
}
await cancelGiveawayJob(id);
await endGiveaway(context, id);
await interaction.reply({ content: t(locale, 'giveaway.ended'), ephemeral: true });
return;
}
if (sub === 'reroll') {
const id = interaction.options.getString('id', true);
const id = interaction.options.getString('id', true).trim();
const existing = await context.prisma.giveaway.findUnique({ where: { id } });
if (!existing || existing.guildId !== interaction.guildId) {
throw new GiveawayError('not_found');
}
const updated = await rerollGiveaway(context, id, locale);
await interaction.reply({
content: tf(locale, 'giveaway.rerolled', {
@@ -136,14 +146,22 @@ const giveawayCommand: SlashCommand = {
}
if (sub === 'delete') {
const id = interaction.options.getString('id', true);
const id = interaction.options.getString('id', true).trim();
const existing = await context.prisma.giveaway.findUnique({ where: { id } });
if (!existing || existing.guildId !== interaction.guildId) {
throw new GiveawayError('not_found');
}
await deleteGiveaway(context, id);
await interaction.reply({ content: t(locale, 'giveaway.deleted'), ephemeral: true });
return;
}
if (sub === 'pause') {
const id = interaction.options.getString('id', true);
const id = interaction.options.getString('id', true).trim();
const existing = await context.prisma.giveaway.findUnique({ where: { id } });
if (!existing || existing.guildId !== interaction.guildId) {
throw new GiveawayError('not_found');
}
const updated = await pauseGiveaway(context, id, locale);
await interaction.reply({
content: t(locale, updated.paused ? 'giveaway.paused' : 'giveaway.resumed'),