discord-multipurpose-bot/commands/games/wordassociation.js

112 lines
3.3 KiB
JavaScript
Raw Normal View History

2024-09-08 00:15:41 +01:00
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
const axios = require("axios");
const WordAssociation = require("../../models/WordAssociation");
const MAX_FIELDS = 25; // Maximum number of fields in an embed
const CACHE_EXPIRY = 30 * 24 * 60 * 60 * 1000; // 1 month
const fetchAssociatedWordsFromAPI = async (word) => {
try {
const response = await axios.get(
`https://api.datamuse.com/words?rel_trg=${word}`
);
return response.data.slice(0, MAX_FIELDS); // Limit the number of associated words
} catch (error) {
console.error("Error fetching associated words from API:", error);
throw new Error("Error fetching associated words");
}
};
const getAssociatedWords = async (word) => {
try {
let wordAssociation = await WordAssociation.findOne({ word });
if (
wordAssociation &&
Date.now() - new Date(wordAssociation.last_updated).getTime() <
CACHE_EXPIRY
) {
return wordAssociation.associatedWords;
}
// Fetch from API if not cached or cache expired
const associatedWords = await fetchAssociatedWordsFromAPI(word);
// Save or update cache
if (wordAssociation) {
wordAssociation.associatedWords = associatedWords.map(
(entry) => entry.word
);
wordAssociation.last_updated = new Date();
await wordAssociation.save();
} else {
await WordAssociation.create({
word,
associatedWords: associatedWords.map((entry) => entry.word),
last_updated: new Date(),
});
}
return associatedWords.map((entry) => entry.word);
} catch (error) {
console.error("Error getting associated words:", error);
throw new Error("Error retrieving associated words");
}
};
const createWordAssociationEmbed = (word, associatedWords) => {
return new EmbedBuilder()
.setColor("#0099ff")
.setTitle("Word Association")
.setDescription(`Words associated with **${word}**:`)
.addFields(
associatedWords.map((word, index) => ({
name: `Option ${index + 1}`,
value: word,
inline: true,
}))
)
.setTimestamp();
};
module.exports = {
data: new SlashCommandBuilder()
.setName("wordassoc")
.setDescription("Find words associated with a given word")
.addStringOption((option) =>
option
.setName("word")
.setDescription("The word to find associations for")
.setRequired(true)
),
async execute(interaction) {
const word = interaction.options.getString("word");
try {
const associatedWords = await getAssociatedWords(word);
if (associatedWords.length === 0) {
return interaction.reply({
content: `No associated words found for **${word}**.`,
ephemeral: true,
});
}
const wordAssociationEmbed = createWordAssociationEmbed(
word,
associatedWords
);
await interaction.reply({ embeds: [wordAssociationEmbed] });
} catch (error) {
console.error("Error executing word association command:", error);
await interaction.reply({
content:
"There was an error fetching associated words. Please try again later.",
ephemeral: true,
});
}
},
};