91 lines
3.6 KiB
TypeScript
91 lines
3.6 KiB
TypeScript
import { createCommand } from "@shared/lib/utils";
|
|
import { SlashCommandBuilder } from "discord.js";
|
|
import { triviaService } from "@shared/modules/trivia/trivia.service";
|
|
import { getTriviaQuestionView } from "@/modules/trivia/trivia.view";
|
|
import { createErrorEmbed } from "@lib/embeds";
|
|
import { UserError } from "@/lib/errors";
|
|
import { config } from "@shared/lib/config";
|
|
|
|
export const trivia = createCommand({
|
|
data: new SlashCommandBuilder()
|
|
.setName("trivia")
|
|
.setDescription("Play trivia to win currency! Answer correctly within the time limit."),
|
|
execute: async (interaction) => {
|
|
try {
|
|
// Check if user can play BEFORE deferring
|
|
const canPlay = await triviaService.canPlayTrivia(interaction.user.id);
|
|
|
|
if (!canPlay.canPlay) {
|
|
// Cooldown error - ephemeral
|
|
const timestamp = Math.floor(canPlay.nextAvailable!.getTime() / 1000);
|
|
await interaction.reply({
|
|
embeds: [createErrorEmbed(
|
|
`You're on cooldown! Try again <t:${timestamp}:R>.`
|
|
)],
|
|
ephemeral: true
|
|
});
|
|
return;
|
|
}
|
|
|
|
// User can play - defer publicly for trivia question
|
|
await interaction.deferReply();
|
|
|
|
// Start trivia session (deducts entry fee)
|
|
const session = await triviaService.startTrivia(
|
|
interaction.user.id,
|
|
interaction.user.username
|
|
);
|
|
|
|
// Generate Components v2 message
|
|
const { components, flags } = getTriviaQuestionView(session, interaction.user.username);
|
|
|
|
// Reply with Components v2 question
|
|
await interaction.editReply({
|
|
components,
|
|
flags
|
|
});
|
|
|
|
// Set up automatic timeout cleanup
|
|
setTimeout(async () => {
|
|
const stillActive = triviaService.getSession(session.sessionId);
|
|
if (stillActive) {
|
|
// User didn't answer - clean up session with no reward
|
|
try {
|
|
await triviaService.submitAnswer(session.sessionId, interaction.user.id, false);
|
|
} catch (error) {
|
|
// Session already cleaned up, ignore
|
|
}
|
|
}
|
|
}, config.trivia.timeoutSeconds * 1000 + 5000); // 5 seconds grace period
|
|
|
|
} catch (error: any) {
|
|
if (error instanceof UserError) {
|
|
// Check if we've already deferred
|
|
if (interaction.deferred) {
|
|
await interaction.editReply({
|
|
embeds: [createErrorEmbed(error.message)]
|
|
});
|
|
} else {
|
|
await interaction.reply({
|
|
embeds: [createErrorEmbed(error.message)],
|
|
ephemeral: true
|
|
});
|
|
}
|
|
} else {
|
|
console.error("Error in trivia command:", error);
|
|
// Check if we've already deferred
|
|
if (interaction.deferred) {
|
|
await interaction.editReply({
|
|
embeds: [createErrorEmbed("An unexpected error occurred. Please try again later.")]
|
|
});
|
|
} else {
|
|
await interaction.reply({
|
|
embeds: [createErrorEmbed("An unexpected error occurred. Please try again later.")],
|
|
ephemeral: true
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|