restructure commands dir and add scramble and random fact

This commit is contained in:
Ayden Jahola 2024-09-07 23:49:03 +01:00
parent ec59d3dca2
commit 971e339896
No known key found for this signature in database
GPG key ID: 71DD90AE4AE92742
6 changed files with 193 additions and 15 deletions

View file

@ -0,0 +1,37 @@
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
const axios = require("axios");
module.exports = {
data: new SlashCommandBuilder()
.setName("randomfact")
.setDescription("Get a random fun fact"),
async execute(interaction) {
try {
// Fetch a random fact from the Useless Facts API
const response = await axios.get(
"https://uselessfacts.jsph.pl/random.json?language=en"
);
const fact = response.data.text;
// Create the embed
const embed = new EmbedBuilder()
.setColor("#0099ff")
.setTitle("Random Fun Fact")
.setDescription(fact)
.setTimestamp()
.setFooter({
text: interaction.guild.name,
iconURL: interaction.guild.iconURL(),
});
await interaction.reply({ embeds: [embed] });
} catch (error) {
console.error("Error fetching a random fact:", error);
await interaction.reply({
content: "Sorry, I was unable to fetch a random fact.",
ephemeral: true,
});
}
},
};

131
commands/games/scramble.js Normal file
View file

@ -0,0 +1,131 @@
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
const axios = require("axios");
const ScrambledWord = require("../../models/ScrambledWord"); // Your database model for scrambled words
const ACTIVE_GAMES = new Set(); // Track users with ongoing games
const fetchRandomWord = async () => {
try {
const response = await axios.get(
"https://random-word-api.herokuapp.com/word?number=1"
);
return response.data[0];
} catch (error) {
console.error("Error fetching a random word:", error);
throw new Error("Error fetching a word");
}
};
const scrambleWord = (word) => {
return word
.split("")
.sort(() => Math.random() - 0.5)
.join("");
};
const createScrambleEmbed = (scrambledWord, guild, timeLimit) => {
return new EmbedBuilder()
.setColor("#0099ff")
.setTitle("Word Scramble")
.setDescription(
`Unscramble the letters to find the word: **${scrambledWord}**`
)
.setTimestamp()
.setFooter({
text: `${guild.name} | Answer within ${timeLimit / 1000} seconds`,
iconURL: guild.iconURL(), // Server avatar
});
};
const handleScrambleAnswer = async (
interaction,
originalWord,
userId,
timeLimit
) => {
try {
const filter = (response) =>
response.author.id === userId &&
response.content.trim().toLowerCase() === originalWord.toLowerCase();
const collector = interaction.channel.createMessageCollector({
filter,
max: 1,
time: timeLimit,
});
collector.on("collect", async () => {
await interaction.followUp(
`🎉 Congratulations <@${userId}>! You unscrambled the word: **${originalWord}**.`
);
ACTIVE_GAMES.delete(userId);
});
collector.on("end", async (collected, reason) => {
if (reason === "time") {
await interaction.followUp(
`⏰ Time's up <@${userId}>! The correct word was **${originalWord}**.`
);
ACTIVE_GAMES.delete(userId);
}
});
} catch (error) {
console.error("Error processing collected answer:", error);
await interaction.followUp({
content: `There was an error processing your answer, <@${userId}>.`,
ephemeral: true,
});
ACTIVE_GAMES.delete(userId);
}
};
module.exports = {
data: new SlashCommandBuilder()
.setName("scramble")
.setDescription("Play a word scramble game"),
async execute(interaction) {
const userId = interaction.user.id;
const guild = interaction.guild;
const timeLimit = 30000; // 30 seconds
if (ACTIVE_GAMES.has(userId)) {
return interaction.reply({
content:
"You already have an ongoing word scramble game. Please finish it before starting a new one.",
ephemeral: true,
});
}
ACTIVE_GAMES.add(userId);
try {
const originalWord = await fetchRandomWord();
const scrambledWord = scrambleWord(originalWord);
// Save to database
await ScrambledWord.create({
word: originalWord,
scrambled: scrambledWord,
created_at: new Date(),
});
const scrambleEmbed = createScrambleEmbed(
scrambledWord,
guild,
timeLimit
);
await interaction.reply({ embeds: [scrambleEmbed] });
await handleScrambleAnswer(interaction, originalWord, userId, timeLimit);
} catch (error) {
console.error("Error executing scramble command:", error);
await interaction.reply({
content:
"An error occurred while starting the word scramble game. Please try again later.",
ephemeral: true,
});
ACTIVE_GAMES.delete(userId);
}
},
};

View file

@ -6,7 +6,7 @@ const { decode } = require("html-entities");
const API_INTERVAL = 5000; // 5 seconds const API_INTERVAL = 5000; // 5 seconds
const QUESTION_EXPIRY = 30 * 24 * 60 * 60 * 1000; // 1 month const QUESTION_EXPIRY = 30 * 24 * 60 * 60 * 1000; // 1 month
const ONGOING_TRIVIA = new Set(); // Track users with ongoing trivia const ACTIVE_GAMES = new Set(); // Track users with ongoing trivia
const LAST_API_CALL = { time: 0 }; // Track last API call const LAST_API_CALL = { time: 0 }; // Track last API call
const CATEGORY_MAP = { const CATEGORY_MAP = {
@ -168,8 +168,8 @@ const handleAnswerCollection = async (
let resultMessage = let resultMessage =
userAnswer === correctAnswer userAnswer === correctAnswer
? "Correct!" ? "🎉 Correct!"
: `Incorrect! the correct answer is **${correctAnswer}.**`; : `Incorrect! the correct answer is **${correctAnswer}.**`;
let userScore = await Leaderboard.findOne({ userId }); let userScore = await Leaderboard.findOne({ userId });
if (!userScore) { if (!userScore) {
@ -195,14 +195,14 @@ const handleAnswerCollection = async (
`${resultMessage} <@${userId}> You've answered ${userScore.correctAnswers} questions correctly out of ${userScore.gamesPlayed} games. Your current streak is **${userScore.streak}**.` `${resultMessage} <@${userId}> You've answered ${userScore.correctAnswers} questions correctly out of ${userScore.gamesPlayed} games. Your current streak is **${userScore.streak}**.`
); );
ONGOING_TRIVIA.delete(userId); ACTIVE_GAMES.delete(userId);
} catch (error) { } catch (error) {
console.error("Error processing collected answer:", error); console.error("Error processing collected answer:", error);
await interaction.followUp({ await interaction.followUp({
content: "There was an error processing your answer.", content: "There was an error processing your answer.",
ephemeral: true, ephemeral: true,
}); });
ONGOING_TRIVIA.delete(userId); ACTIVE_GAMES.delete(userId);
} }
}); });
@ -217,7 +217,7 @@ const handleAnswerCollection = async (
} }
await interaction.followUp( await interaction.followUp(
`<@${userId}> Time's up! The correct answer is **${correctAnswer}**. Your current streak is **${userScore.streak}**.` `<@${userId}> Time's up! The correct answer is **${correctAnswer}**. Your current streak is **${userScore.streak}**.`
); );
} catch (error) { } catch (error) {
console.error("Error resetting streak after time limit:", error); console.error("Error resetting streak after time limit:", error);
@ -227,7 +227,7 @@ const handleAnswerCollection = async (
}); });
} }
ONGOING_TRIVIA.delete(userId); ACTIVE_GAMES.delete(userId);
} }
}); });
} catch (error) { } catch (error) {
@ -236,7 +236,7 @@ const handleAnswerCollection = async (
content: "There was an error handling your response.", content: "There was an error handling your response.",
ephemeral: true, ephemeral: true,
}); });
ONGOING_TRIVIA.delete(userId); ACTIVE_GAMES.delete(userId);
} }
}; };
@ -263,7 +263,7 @@ 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
if (ONGOING_TRIVIA.has(userId)) { if (ACTIVE_GAMES.has(userId)) {
return interaction.reply({ return interaction.reply({
content: content:
"You already have an ongoing trivia game. Please finish it before starting a new one.", "You already have an ongoing trivia game. Please finish it before starting a new one.",
@ -271,7 +271,7 @@ module.exports = {
}); });
} }
ONGOING_TRIVIA.add(userId); ACTIVE_GAMES.add(userId);
try { try {
const categoryId = interaction.options.getString("category"); const categoryId = interaction.options.getString("category");
@ -331,7 +331,7 @@ module.exports = {
"Trivia API hit the rate limit or encountered an issue. Please try again in 5 seconds.", "Trivia API hit the rate limit or encountered an issue. Please try again in 5 seconds.",
ephemeral: true, ephemeral: true,
}); });
ONGOING_TRIVIA.delete(userId); ACTIVE_GAMES.delete(userId);
} }
}, },
}; };

9
models/ScrambledWord.js Normal file
View file

@ -0,0 +1,9 @@
const mongoose = require("mongoose");
const scrambledWordSchema = new mongoose.Schema({
word: { type: String, required: true },
scrambled: { type: String, required: true },
created_at: { type: Date, required: true },
});
module.exports = mongoose.model("ScrambledWord", scrambledWordSchema);

View file

@ -1,14 +1,15 @@
{ {
"name": "esports-bot", "name": "multipurpose-discord-bot",
"version": "1.0.0", "version": "1.0.0",
"author": "Ayden Jahola",
"description": "A multipurpose discord bot",
"github": "https://github.com/aydenjahola/discord-multipurpose-bot",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"keywords": [], "keywords": [],
"author": "", "license": "MIT",
"license": "ISC",
"description": "",
"dependencies": { "dependencies": {
"axios": "^1.7.7", "axios": "^1.7.7",
"discord.js": "^14.15.3", "discord.js": "^14.15.3",