mirror of
https://github.com/aydenjahola/discord-multipurpose-bot.git
synced 2024-11-22 08:45:55 +00:00
add anime & manga option to the trivia command and add clear leaderboard command
This commit is contained in:
parent
70ac364608
commit
379afca76b
3 changed files with 171 additions and 128 deletions
|
@ -12,7 +12,17 @@ let lastApiCall = 0;
|
||||||
module.exports = {
|
module.exports = {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName("trivia")
|
.setName("trivia")
|
||||||
.setDescription("Play a trivia game about video games"),
|
.setDescription("Play a trivia game")
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option
|
||||||
|
.setName("category")
|
||||||
|
.setDescription("Choose a trivia category")
|
||||||
|
.setRequired(true)
|
||||||
|
.addChoices(
|
||||||
|
{ name: "Video Games", value: "15" },
|
||||||
|
{ name: "Anime & Manga", value: "31" }
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
async execute(interaction, client) {
|
async execute(interaction, client) {
|
||||||
const userId = interaction.user.id;
|
const userId = interaction.user.id;
|
||||||
|
@ -20,16 +30,19 @@ module.exports = {
|
||||||
const guild = interaction.guild;
|
const guild = interaction.guild;
|
||||||
const timeLimit = 30000; // Time limit for answering in milliseconds
|
const timeLimit = 30000; // Time limit for answering in milliseconds
|
||||||
|
|
||||||
try {
|
const categoryId = interaction.options.getString("category");
|
||||||
|
const categoryName = categoryId === "15" ? "Video Games" : "Anime & Manga";
|
||||||
|
|
||||||
// Fetch a trivia question from the cache or the API
|
// Fetch a trivia question from the cache or the API
|
||||||
let triviaQuestion = await TriviaQuestion.findOne({
|
let triviaQuestion = await TriviaQuestion.findOne({
|
||||||
last_served: { $lt: new Date(Date.now() - QUESTION_EXPIRY) }, // Fetch questions not served recently
|
last_served: { $lt: new Date(Date.now() - QUESTION_EXPIRY) }, // Fetch questions not served recently
|
||||||
|
category: categoryName, // Filter by category
|
||||||
}).sort({ last_served: 1 });
|
}).sort({ last_served: 1 });
|
||||||
|
|
||||||
if (!triviaQuestion || Date.now() - lastApiCall >= API_INTERVAL) {
|
if (!triviaQuestion || Date.now() - lastApiCall >= API_INTERVAL) {
|
||||||
// Fetch a new trivia question from OTDB
|
// Fetch a new trivia question from OTDB
|
||||||
const response = await axios.get(
|
const response = await axios.get(
|
||||||
"https://opentdb.com/api.php?amount=1&category=15" // Category 15 is for Video Games
|
`https://opentdb.com/api.php?amount=1&category=${categoryId}`
|
||||||
);
|
);
|
||||||
|
|
||||||
triviaQuestion = response.data.results[0];
|
triviaQuestion = response.data.results[0];
|
||||||
|
@ -40,12 +53,14 @@ module.exports = {
|
||||||
question: decode(triviaQuestion.question),
|
question: decode(triviaQuestion.question),
|
||||||
correct_answer: decode(triviaQuestion.correct_answer),
|
correct_answer: decode(triviaQuestion.correct_answer),
|
||||||
incorrect_answers: triviaQuestion.incorrect_answers.map(decode),
|
incorrect_answers: triviaQuestion.incorrect_answers.map(decode),
|
||||||
|
category: categoryName, // Include the category
|
||||||
last_served: null, // Initially not served
|
last_served: null, // Initially not served
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fetch the newly created question
|
// Fetch the newly created question
|
||||||
triviaQuestion = await TriviaQuestion.findOne({
|
triviaQuestion = await TriviaQuestion.findOne({
|
||||||
question: decode(triviaQuestion.question),
|
question: decode(triviaQuestion.question),
|
||||||
|
category: categoryName, // Filter by category
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,9 +72,14 @@ module.exports = {
|
||||||
const question = decode(triviaQuestion.question);
|
const question = decode(triviaQuestion.question);
|
||||||
const correctAnswer = decode(triviaQuestion.correct_answer);
|
const correctAnswer = decode(triviaQuestion.correct_answer);
|
||||||
const incorrectAnswers = triviaQuestion.incorrect_answers.map(decode);
|
const incorrectAnswers = triviaQuestion.incorrect_answers.map(decode);
|
||||||
const allAnswers = [...incorrectAnswers, correctAnswer].sort(
|
let allAnswers = [...incorrectAnswers, correctAnswer];
|
||||||
() => Math.random() - 0.5
|
|
||||||
);
|
// Handle True/False questions specifically
|
||||||
|
if (triviaQuestion.type === "boolean") {
|
||||||
|
allAnswers = ["True", "False"];
|
||||||
|
}
|
||||||
|
|
||||||
|
allAnswers = allAnswers.sort(() => Math.random() - 0.5); // Shuffle answers
|
||||||
|
|
||||||
// Create a mapping of numbers to answers
|
// Create a mapping of numbers to answers
|
||||||
const answerMap = allAnswers.reduce((map, answer, index) => {
|
const answerMap = allAnswers.reduce((map, answer, index) => {
|
||||||
|
@ -86,12 +106,11 @@ module.exports = {
|
||||||
});
|
});
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: `<@${userId}>`,
|
|
||||||
embeds: [triviaEmbed],
|
embeds: [triviaEmbed],
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a message collector specific to the user
|
// Create a message collector specific to the user
|
||||||
const filter = (response) => {
|
const answerFilter = (response) => {
|
||||||
const userInput = response.content.trim();
|
const userInput = response.content.trim();
|
||||||
const userAnswerNumber = parseInt(userInput, 10);
|
const userAnswerNumber = parseInt(userInput, 10);
|
||||||
const userAnswerText =
|
const userAnswerText =
|
||||||
|
@ -106,13 +125,13 @@ module.exports = {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const collector = interaction.channel.createMessageCollector({
|
const answerCollector = interaction.channel.createMessageCollector({
|
||||||
filter,
|
filter: answerFilter,
|
||||||
max: 1,
|
max: 1,
|
||||||
time: timeLimit,
|
time: timeLimit,
|
||||||
});
|
});
|
||||||
|
|
||||||
collector.on("collect", async (message) => {
|
answerCollector.on("collect", async (message) => {
|
||||||
const userInput = message.content.trim();
|
const userInput = message.content.trim();
|
||||||
const userAnswerNumber = parseInt(userInput, 10);
|
const userAnswerNumber = parseInt(userInput, 10);
|
||||||
const userAnswer = answerMap[userAnswerNumber] || userInput;
|
const userAnswer = answerMap[userAnswerNumber] || userInput;
|
||||||
|
@ -145,26 +164,12 @@ module.exports = {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
collector.on("end", (collected, reason) => {
|
answerCollector.on("end", (collected, reason) => {
|
||||||
if (reason === "time") {
|
if (reason === "time") {
|
||||||
interaction.followUp(
|
interaction.followUp(
|
||||||
`<@${userId}> Time's up! You didn't answer in time.`
|
`<@${userId}> Time's up! You didn't answer in time.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
console.error("Error executing trivia command:", error);
|
|
||||||
if (error.response && error.response.status === 429) {
|
|
||||||
await interaction.reply({
|
|
||||||
content: `<@${userId}> The trivia API rate limit has been exceeded. Please try in 5 seconds.`,
|
|
||||||
ephemeral: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
await interaction.reply({
|
|
||||||
content: `<@${userId}> There was an error while executing this command!`,
|
|
||||||
ephemeral: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
37
commands/moderation/clearLeaderboard.js
Normal file
37
commands/moderation/clearLeaderboard.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
const { SlashCommandBuilder } = require("discord.js");
|
||||||
|
const Leaderboard = require("../../models/Leaderboard");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName("clearleaderboard")
|
||||||
|
.setDescription("Clears all entries in the trivia leaderboard"),
|
||||||
|
isModOnly: true,
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
try {
|
||||||
|
const requiredRoleId = process.env.MOD_ROLE_ID;
|
||||||
|
if (!interaction.member.roles.cache.has(requiredRoleId)) {
|
||||||
|
await interaction.reply({
|
||||||
|
content: "You do not have the required role to use this command!",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the leaderboard
|
||||||
|
await Leaderboard.deleteMany({});
|
||||||
|
|
||||||
|
// Notify the mod who executed the command
|
||||||
|
await interaction.reply({
|
||||||
|
content: "The leaderboard has been cleared successfully.",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error executing clearleaderboard command:", error);
|
||||||
|
await interaction.reply({
|
||||||
|
content: "There was an error while executing this command!",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
|
@ -4,6 +4,7 @@ const triviaQuestionSchema = new mongoose.Schema({
|
||||||
question: String,
|
question: String,
|
||||||
correct_answer: String,
|
correct_answer: String,
|
||||||
incorrect_answers: [String],
|
incorrect_answers: [String],
|
||||||
|
category: String,
|
||||||
last_served: Date, // Track when the question was last served
|
last_served: Date, // Track when the question was last served
|
||||||
timestamp: { type: Date, default: Date.now },
|
timestamp: { type: Date, default: Date.now },
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue