diff --git a/src/commands/about.ts b/src/commands/about.ts
index cd7c6e6..9b4f277 100644
--- a/src/commands/about.ts
+++ b/src/commands/about.ts
@@ -1,58 +1,72 @@
-import { SlashCommandBuilder } from '@discordjs/builders';
-import { MessageEmbed, CommandInteraction } from 'discord.js';
-
-import gitlog from 'gitlog';
-
-import userScore from '../models/userScore';
-
-import { paginateInteraction } from '../helpers/util/pagination';
-
-export const data = new SlashCommandBuilder()
- .setName('about')
- .setDescription('Commands regarding the creation/development of the bot');
-
-export async function execute(interaction: CommandInteraction) {
- await interaction.deferReply();
-
- const client = interaction.client;
- const embeds: MessageEmbed[] = [];
-
- const contributorEmbed = new MessageEmbed().setTitle('Contributors')
- .addField('Creator', '<@745063586422063214> [ADawesomeguy#3602]', true)
- .addField('Contributors', '<@650525101048987649> [tEjAs#8127]\n<@426864344463048705> [tetrident#9396]', true) // Add more contributors here, first one is Abheek, second one is Tejas
- .setTimestamp()
- .setColor('#ffffff');
- embeds.push(contributorEmbed);
-
- const gitRepoLocation = __dirname;
-
- const commits = gitlog({
- repo: gitRepoLocation,
- number: 5,
- fields: ['hash', 'abbrevHash', 'subject', 'authorName', 'authorDateRel'],
- });
-
- const changelogEmbed = new MessageEmbed()
- .setAuthor({ name: interaction.user.tag, iconURL: interaction.user.displayAvatarURL() })
- .setTitle('Changelog')
- .setColor('#ffffff')
- .setTimestamp();
-
- commits.forEach(commit => {
- changelogEmbed.addField(commit.abbrevHash, `> \`Hash:\`${commit.hash}\n> \`Subject:\`${commit.subject}\n> \`Author:\`${commit.authorName}\n> \`Date:\`${commit.authorDateRel}\n> \`Link\`: [GitHub](https://github.com/ADawesomeguy/AwesomeSciBo/commit/${commit.hash})\n`);
- });
- embeds.push(changelogEmbed);
-
- await client.guilds.fetch();
- const trainingDocuments = await userScore.countDocuments({});
- const aboutBotEmbed = new MessageEmbed()
- .setAuthor({ name: interaction.user.tag, iconURL: interaction.user.displayAvatarURL() })
- .setTitle('About AwesomeSciBo')
- .addField('Servers', `${client.guilds.cache.size}`, true)
- .addField('Training Users', `${trainingDocuments}`, true)
- .setTimestamp();
-
- embeds.push(aboutBotEmbed);
-
- paginateInteraction(interaction, embeds);
-}
+import { SlashCommandBuilder } from "@discordjs/builders";
+import { MessageEmbed, CommandInteraction } from "discord.js";
+
+import gitlog from "gitlog";
+
+import userScore from "../models/userScore";
+
+import { paginateInteraction } from "../helpers/util/pagination";
+
+export const data = new SlashCommandBuilder()
+ .setName("about")
+ .setDescription("Commands regarding the creation/development of the bot");
+
+export async function execute(interaction: CommandInteraction) {
+ await interaction.deferReply();
+
+ const client = interaction.client;
+ const embeds: MessageEmbed[] = [];
+
+ const contributorEmbed = new MessageEmbed()
+ .setTitle("Contributors")
+ .addField("Creator", "<@745063586422063214> [ADawesomeguy#3602]", true)
+ .addField(
+ "Contributors",
+ "<@650525101048987649> [tEjAs#8127]\n<@426864344463048705> [tetrident#9396]",
+ true
+ ) // Add more contributors here, first one is Abheek, second one is Tejas
+ .setTimestamp()
+ .setColor("#ffffff");
+ embeds.push(contributorEmbed);
+
+ const gitRepoLocation = __dirname;
+
+ const commits = gitlog({
+ repo: gitRepoLocation,
+ number: 5,
+ fields: ["hash", "abbrevHash", "subject", "authorName", "authorDateRel"],
+ });
+
+ const changelogEmbed = new MessageEmbed()
+ .setAuthor({
+ name: interaction.user.tag,
+ iconURL: interaction.user.displayAvatarURL(),
+ })
+ .setTitle("Changelog")
+ .setColor("#ffffff")
+ .setTimestamp();
+
+ commits.forEach((commit) => {
+ changelogEmbed.addField(
+ commit.abbrevHash,
+ `> \`Hash:\`${commit.hash}\n> \`Subject:\`${commit.subject}\n> \`Author:\`${commit.authorName}\n> \`Date:\`${commit.authorDateRel}\n> \`Link\`: [GitHub](https://github.com/ADawesomeguy/AwesomeSciBo/commit/${commit.hash})\n`
+ );
+ });
+ embeds.push(changelogEmbed);
+
+ await client.guilds.fetch();
+ const trainingDocuments = await userScore.countDocuments({});
+ const aboutBotEmbed = new MessageEmbed()
+ .setAuthor({
+ name: interaction.user.tag,
+ iconURL: interaction.user.displayAvatarURL(),
+ })
+ .setTitle("About AwesomeSciBo")
+ .addField("Servers", `${client.guilds.cache.size}`, true)
+ .addField("Training Users", `${trainingDocuments}`, true)
+ .setTimestamp();
+
+ embeds.push(aboutBotEmbed);
+
+ paginateInteraction(interaction, embeds);
+}
diff --git a/src/commands/help.ts b/src/commands/help.ts
index ae7bb2a..20b2d1d 100644
--- a/src/commands/help.ts
+++ b/src/commands/help.ts
@@ -1,16 +1,18 @@
-import { SlashCommandBuilder } from '@discordjs/builders';
-import { MessageEmbed, CommandInteraction } from 'discord.js';
-
-export const data = new SlashCommandBuilder()
- .setName('help')
- .setDescription('Replies with a help message explaining what the bot can do');
-
-export async function execute(interaction: CommandInteraction) {
- await interaction.deferReply();
- await interaction.deferReply();
-
- const helpEmbed = new MessageEmbed()
- .setDescription('AwesomeSciBo has migrated to using slash commands! You can take a look at the different commands by typing `/` and clicking on the AwesomeSciBo icon.')
- .setColor('#ffffff');
- interaction.followUp({ embeds: [helpEmbed] });
-}
\ No newline at end of file
+import { SlashCommandBuilder } from "@discordjs/builders";
+import { MessageEmbed, CommandInteraction } from "discord.js";
+
+export const data = new SlashCommandBuilder()
+ .setName("help")
+ .setDescription("Replies with a help message explaining what the bot can do");
+
+export async function execute(interaction: CommandInteraction) {
+ await interaction.deferReply();
+ await interaction.deferReply();
+
+ const helpEmbed = new MessageEmbed()
+ .setDescription(
+ "AwesomeSciBo has migrated to using slash commands! You can take a look at the different commands by typing `/` and clicking on the AwesomeSciBo icon."
+ )
+ .setColor("#ffffff");
+ interaction.followUp({ embeds: [helpEmbed] });
+}
diff --git a/src/commands/rounds.ts b/src/commands/rounds.ts
index 0d90b14..004357b 100644
--- a/src/commands/rounds.ts
+++ b/src/commands/rounds.ts
@@ -1,125 +1,178 @@
-import { SlashCommandBuilder } from '@discordjs/builders';
-import { MessageEmbed, CommandInteraction } from 'discord.js';
-
-import axios from 'axios';
-
-import log from '../helpers/log';
-import generatedRound from '../models/generatedRound';
-
-export const data = new SlashCommandBuilder()
- .setName('rounds')
- .setDescription('Commands regarding the generation of rounds')
- .addSubcommand(subcommand => {
- subcommand
- .setName('generate')
- .setDescription('Generates a round with randomized questions from https://scibowldb.com/');
- return subcommand;
- })
- .addSubcommand(subcommand => {
- subcommand
- .setName('list')
- .setDescription('Lists your 5 most recently generated rounds with links');
- return subcommand;
- })
- .addSubcommand(subcommand => {
- subcommand
- .setName('hit')
- .setDescription('Shows the total number of rounds hit as well as the number for the specific user');
- return subcommand;
- });
-
-export async function execute(interaction: CommandInteraction) {
- const action = interaction.options.getSubcommand();
- switch (action) {
- case 'generate': {
- interaction.deferReply({ ephemeral: true });
-
- let finalizedHTML = '
ROUND GENERATED BY AWESOMESCIBO USING THE SCIBOWLDB API
';
- let tossup_question: string;
- let question_category: string;
- let tossup_format: string;
- let tossup_answer: string;
- let bonus_question: string;
- let bonus_format: string;
- let bonus_answer: string;
- let htmlContent = '';
- await axios.post('https://scibowldb.com/api/questions', { categories: ['BIOLOGY', 'PHYSICS', 'CHEMISTRY', 'EARTH AND SPACE', 'ASTRONOMY', 'MATH'] })
- .then((response) => {
- for (let i = 1; i < 26; i++) {
- const questionData = response.data.questions[Math.floor(Math.random() * response.data.questions.length)];
- tossup_question = questionData.tossup_question;
- tossup_answer = questionData.tossup_answer;
- question_category = questionData.category;
- tossup_format = questionData.tossup_format;
- bonus_question = questionData.bonus_question;
- bonus_answer = questionData.bonus_answer;
- bonus_format = questionData.bonus_format;
- htmlContent = '
TOSS-UP
\n
' + `${i}) ${question_category}` + ' ' + `${tossup_format}` + ' ' + tossup_question + '
' + 'ANSWER: ' + tossup_answer + '
';
- htmlContent += '
BONUS
\n
' + `${i}) ${question_category}` + ' ' + `${bonus_format}` + ' ' + bonus_question + '
' + 'ANSWER: ' + bonus_answer + '
';
- htmlContent = htmlContent.replace(/\n/g, '
');
- finalizedHTML += htmlContent;
- }
-
- const newGeneratedRound = new generatedRound({
- htmlContent: finalizedHTML,
- requestedBy: interaction.user.id,
- authorTag: interaction.user.tag,
- timestamp: new Date().toISOString(),
- });
-
- newGeneratedRound.save((err, round) => {
- if (err) {
- log({ logger: 'rounds', content: `Saving round to DB failed: ${err}`, level: 'error' });
- return;
- }
- interaction.followUp({
- content: `Here's your round: https://api.adawesome.tech/round/${round._id.toString()}`,
- ephemeral: true,
- });
- });
- });
- break;
- }
-
- case 'list': {
- interaction.deferReply({ ephemeral: true });
-
- let roundsList = await generatedRound.find({ requestedBy: interaction.user.id }).sort({ timestamp: -1 });
- let finalMessage = '';
- if (!roundsList) {
- interaction.followUp('You haven\'t requested any rounds!');
- return;
- }
-
- if (roundsList.length > 5) {
- roundsList = roundsList.slice(0, 5);
- }
-
- roundsList.forEach(async (item, index) => {
- finalMessage += `${index + 1}. [${item.timestamp.split('T')[0]}](https://api.adawesome.tech/round/${item._id.toString()})\n`;
- });
-
- const roundsListEmbed = new MessageEmbed()
- .setAuthor({ name: interaction.user.tag, iconURL: interaction.user.displayAvatarURL() })
- .setTitle('Last 5 rounds requested')
- .setDescription(finalMessage)
- .setTimestamp();
-
- interaction.followUp({
- embeds: [roundsListEmbed],
- ephemeral: true,
- });
- break;
- }
-
- case 'hit': {
- await interaction.deferReply();
-
- const totalCount = await generatedRound.countDocuments({});
- const userCount = await generatedRound.countDocuments({ requestedBy: interaction.user.id });
-
- interaction.followUp(`Total Hits: ${totalCount}\nYour Hits: ${userCount}`);
- break;
- }
- }
-}
\ No newline at end of file
+import { SlashCommandBuilder } from "@discordjs/builders";
+import { MessageEmbed, CommandInteraction } from "discord.js";
+
+import axios from "axios";
+
+import log from "../helpers/log";
+import generatedRound from "../models/generatedRound";
+
+export const data = new SlashCommandBuilder()
+ .setName("rounds")
+ .setDescription("Commands regarding the generation of rounds")
+ .addSubcommand((subcommand) => {
+ subcommand
+ .setName("generate")
+ .setDescription(
+ "Generates a round with randomized questions from https://scibowldb.com/"
+ );
+ return subcommand;
+ })
+ .addSubcommand((subcommand) => {
+ subcommand
+ .setName("list")
+ .setDescription("Lists your 5 most recently generated rounds with links");
+ return subcommand;
+ })
+ .addSubcommand((subcommand) => {
+ subcommand
+ .setName("hit")
+ .setDescription(
+ "Shows the total number of rounds hit as well as the number for the specific user"
+ );
+ return subcommand;
+ });
+
+export async function execute(interaction: CommandInteraction) {
+ const action = interaction.options.getSubcommand();
+ switch (action) {
+ case "generate": {
+ interaction.deferReply({ ephemeral: true });
+
+ let finalizedHTML =
+ " ROUND GENERATED BY AWESOMESCIBO USING THE SCIBOWLDB API
";
+ let tossup_question: string;
+ let question_category: string;
+ let tossup_format: string;
+ let tossup_answer: string;
+ let bonus_question: string;
+ let bonus_format: string;
+ let bonus_answer: string;
+ let htmlContent = "";
+ await axios
+ .post("https://scibowldb.com/api/questions", {
+ categories: [
+ "BIOLOGY",
+ "PHYSICS",
+ "CHEMISTRY",
+ "EARTH AND SPACE",
+ "ASTRONOMY",
+ "MATH",
+ ],
+ })
+ .then((response) => {
+ for (let i = 1; i < 26; i++) {
+ const questionData =
+ response.data.questions[
+ Math.floor(Math.random() * response.data.questions.length)
+ ];
+ tossup_question = questionData.tossup_question;
+ tossup_answer = questionData.tossup_answer;
+ question_category = questionData.category;
+ tossup_format = questionData.tossup_format;
+ bonus_question = questionData.bonus_question;
+ bonus_answer = questionData.bonus_answer;
+ bonus_format = questionData.bonus_format;
+ htmlContent =
+ "
TOSS-UP
\n
" +
+ `${i}) ${question_category}` +
+ " " +
+ `${tossup_format}` +
+ " " +
+ tossup_question +
+ "
" +
+ "ANSWER: " +
+ tossup_answer +
+ "
";
+ htmlContent +=
+ "
BONUS
\n
" +
+ `${i}) ${question_category}` +
+ " " +
+ `${bonus_format}` +
+ " " +
+ bonus_question +
+ "
" +
+ "ANSWER: " +
+ bonus_answer +
+ "
";
+ htmlContent = htmlContent.replace(/\n/g, "
");
+ finalizedHTML += htmlContent;
+ }
+
+ const newGeneratedRound = new generatedRound({
+ htmlContent: finalizedHTML,
+ requestedBy: interaction.user.id,
+ authorTag: interaction.user.tag,
+ timestamp: new Date().toISOString(),
+ });
+
+ newGeneratedRound.save((err, round) => {
+ if (err) {
+ log({
+ logger: "rounds",
+ content: `Saving round to DB failed: ${err}`,
+ level: "error",
+ });
+ return;
+ }
+ interaction.followUp({
+ content: `Here's your round: https://api.adawesome.tech/round/${round._id.toString()}`,
+ ephemeral: true,
+ });
+ });
+ });
+ break;
+ }
+
+ case "list": {
+ interaction.deferReply({ ephemeral: true });
+
+ let roundsList = await generatedRound
+ .find({ requestedBy: interaction.user.id })
+ .sort({ timestamp: -1 });
+ let finalMessage = "";
+ if (!roundsList) {
+ interaction.followUp("You haven't requested any rounds!");
+ return;
+ }
+
+ if (roundsList.length > 5) {
+ roundsList = roundsList.slice(0, 5);
+ }
+
+ roundsList.forEach(async (item, index) => {
+ finalMessage += `${index + 1}. [${
+ item.timestamp.split("T")[0]
+ }](https://api.adawesome.tech/round/${item._id.toString()})\n`;
+ });
+
+ const roundsListEmbed = new MessageEmbed()
+ .setAuthor({
+ name: interaction.user.tag,
+ iconURL: interaction.user.displayAvatarURL(),
+ })
+ .setTitle("Last 5 rounds requested")
+ .setDescription(finalMessage)
+ .setTimestamp();
+
+ interaction.followUp({
+ embeds: [roundsListEmbed],
+ ephemeral: true,
+ });
+ break;
+ }
+
+ case "hit": {
+ await interaction.deferReply();
+
+ const totalCount = await generatedRound.countDocuments({});
+ const userCount = await generatedRound.countDocuments({
+ requestedBy: interaction.user.id,
+ });
+
+ interaction.followUp(
+ `Total Hits: ${totalCount}\nYour Hits: ${userCount}`
+ );
+ break;
+ }
+ }
+}
diff --git a/src/commands/score.ts b/src/commands/score.ts
index 2408e4b..3c4d973 100644
--- a/src/commands/score.ts
+++ b/src/commands/score.ts
@@ -1,43 +1,47 @@
-import { SlashCommandBuilder } from '@discordjs/builders';
-import { CommandInteraction, MessageEmbed } from 'discord.js';
-
-import log from '../helpers/log';
-import userScore from '../models/userScore';
-
-export const data = new SlashCommandBuilder()
- .setName('score')
- .setDescription('Returns the score of the current user or another')
- .addUserOption(option => {
- option
- .setName('user')
- .setDescription('The user to find the score for')
- .setRequired(false);
-
- return option;
- });
-
-export async function execute(interaction: CommandInteraction) {
- const scoreEmbed = new MessageEmbed()
- .setColor('#ffffff');
-
- const user = interaction.options.getUser('user') || interaction.user;
- userScore.findOne({ authorID: user.id }, async (err, score) => {
- if (err) {
- log({ logger: 'db', content: `Unable to obtain user: ${err}`, level: 'info' });
- }
-
- if (!score) {
- await interaction.reply({
- content: 'Unfortunately, that user does not seem to have used AwesomeSciBo yet.',
- ephemeral: true,
- });
- return;
- }
-
- scoreEmbed
- .setAuthor({ name: user.tag, iconURL: user.displayAvatarURL() })
- .setDescription(`Score: \`${score.score}\``);
-
- await interaction.reply({ embeds: [scoreEmbed] });
- });
-}
+import { SlashCommandBuilder } from "@discordjs/builders";
+import { CommandInteraction, MessageEmbed } from "discord.js";
+
+import log from "../helpers/log";
+import userScore from "../models/userScore";
+
+export const data = new SlashCommandBuilder()
+ .setName("score")
+ .setDescription("Returns the score of the current user or another")
+ .addUserOption((option) => {
+ option
+ .setName("user")
+ .setDescription("The user to find the score for")
+ .setRequired(false);
+
+ return option;
+ });
+
+export async function execute(interaction: CommandInteraction) {
+ const scoreEmbed = new MessageEmbed().setColor("#ffffff");
+
+ const user = interaction.options.getUser("user") || interaction.user;
+ userScore.findOne({ authorID: user.id }, async (err, score) => {
+ if (err) {
+ log({
+ logger: "db",
+ content: `Unable to obtain user: ${err}`,
+ level: "info",
+ });
+ }
+
+ if (!score) {
+ await interaction.reply({
+ content:
+ "Unfortunately, that user does not seem to have used AwesomeSciBo yet.",
+ ephemeral: true,
+ });
+ return;
+ }
+
+ scoreEmbed
+ .setAuthor({ name: user.tag, iconURL: user.displayAvatarURL() })
+ .setDescription(`Score: \`${score.score}\``);
+
+ await interaction.reply({ embeds: [scoreEmbed] });
+ });
+}
diff --git a/src/commands/settings.ts b/src/commands/settings.ts
index a0bc130..97c290d 100644
--- a/src/commands/settings.ts
+++ b/src/commands/settings.ts
@@ -1,251 +1,289 @@
-import { SlashCommandBuilder } from '@discordjs/builders';
-import { Message, MessageActionRow, MessageSelectMenu } from 'discord.js';
-import { CommandInteraction, MessageEmbed } from 'discord.js';
-import log from '../helpers/log';
-import userConfig from '../models/userConfig';
+import { SlashCommandBuilder } from "@discordjs/builders";
+import { Message, MessageActionRow, MessageSelectMenu } from "discord.js";
+import { CommandInteraction, MessageEmbed } from "discord.js";
+import log from "../helpers/log";
+import userConfig from "../models/userConfig";
export const data = new SlashCommandBuilder()
- .setName('settings')
- .setDescription('BETA - settings configuration')
- .addSubcommand(subcommand => {
- subcommand
- .setName('subject')
- .setDescription('Changes subject of problems');
- return subcommand;
- })
- .addSubcommand(subcommand => {
- subcommand
- .setName('display')
- .setDescription('Displays current settings');
- return subcommand;
- })
- .addSubcommand(subcommand => {
- subcommand
- .setName('gradelevels')
- .setDescription('Changes grade level of problems');
- return subcommand;
- });
+ .setName("settings")
+ .setDescription("BETA - settings configuration")
+ .addSubcommand((subcommand) => {
+ subcommand.setName("subject").setDescription("Changes subject of problems");
+ return subcommand;
+ })
+ .addSubcommand((subcommand) => {
+ subcommand.setName("display").setDescription("Displays current settings");
+ return subcommand;
+ })
+ .addSubcommand((subcommand) => {
+ subcommand
+ .setName("gradelevels")
+ .setDescription("Changes grade level of problems");
+ return subcommand;
+ });
export async function execute(interaction: CommandInteraction) {
- const action = interaction.options.getSubcommand();
- switch (action) {
- case 'display': {
- await interaction.deferReply();
- const settingsEmbed = new MessageEmbed()
- .setColor('#ffffff');
+ const action = interaction.options.getSubcommand();
+ switch (action) {
+ case "display": {
+ await interaction.deferReply();
+ const settingsEmbed = new MessageEmbed().setColor("#ffffff");
- const user = interaction.options.getUser('user') || interaction.user;
+ const user = interaction.options.getUser("user") || interaction.user;
- settingsEmbed
- .setAuthor({ name: user.tag, iconURL: user.displayAvatarURL() })
- .setDescription('Current selections: ');
- const menu = new MessageActionRow()
- .addComponents(
- new MessageSelectMenu()
- .setCustomId('selectdisp')
- .setPlaceholder('Nothing selected')
- .addOptions([
- {
- label: 'subjects',
- description: 'subjects',
- value: 'subjects',
- },
- {
- label: 'gradelevels',
- description: 'grade levels',
- value: 'gradelevels',
- },
- ]),
- );
+ settingsEmbed
+ .setAuthor({ name: user.tag, iconURL: user.displayAvatarURL() })
+ .setDescription("Current selections: ");
+ const menu = new MessageActionRow().addComponents(
+ new MessageSelectMenu()
+ .setCustomId("selectdisp")
+ .setPlaceholder("Nothing selected")
+ .addOptions([
+ {
+ label: "subjects",
+ description: "subjects",
+ value: "subjects",
+ },
+ {
+ label: "gradelevels",
+ description: "grade levels",
+ value: "gradelevels",
+ },
+ ])
+ );
- interaction.followUp({
- embeds: [/* settingsEmbed*/],
- components: [menu],
- })
- .then((dispMsg => {
- const w = dispMsg as Message;
- const dispFilter = i => ['selectdisp'].includes(i.customId) && i.user.id == interaction.user.id; // <== ATTENTION! First argument...
- w.awaitMessageComponent({ filter: dispFilter, componentType: 'SELECT_MENU' })
- .then(async dispChoice => {
- const vals = dispChoice.values;
- const config = await userConfig.findById(interaction.user.id);
- if (!config) {
- await interaction.editReply({
- content: 'You don\'t have a configuration!',
- embeds: [],
- components: [],
- });
- }
- else if (vals.length === 1 && vals.at(0) === 'subjects') {
- await interaction.editReply({
- content: `Current subjects setting: ${config.subjects.toString().split(',').join(', ')}`,
- components: [],
- });
- }
- else if (vals.length === 1 && vals.at(0) === 'gradelevels') {
- await interaction.editReply({
- content: `Current grade level setting: ${config.gradeLevels.toString().split(',').join(', ')}`,
- components: [],
- });
- }
- else {
- err => log({
- logger: '\'Error occurred: /settings:display did not equal subjects or gradelevels.\'',
- content: `${err}`,
- level: 'error',
- });
- }
- });
- }));
- break;
- }
- case 'gradelevels': {
- await interaction.deferReply();
+ interaction
+ .followUp({
+ embeds: [
+ /* settingsEmbed*/
+ ],
+ components: [menu],
+ })
+ .then((dispMsg) => {
+ const w = dispMsg as Message;
+ const dispFilter = (i) =>
+ ["selectdisp"].includes(i.customId) &&
+ i.user.id == interaction.user.id; // <== ATTENTION! First argument...
+ w.awaitMessageComponent({
+ filter: dispFilter,
+ componentType: "SELECT_MENU",
+ }).then(async (dispChoice) => {
+ const vals = dispChoice.values;
+ const config = await userConfig.findById(interaction.user.id);
+ if (!config) {
+ await interaction.editReply({
+ content: "You don't have a configuration!",
+ embeds: [],
+ components: [],
+ });
+ } else if (vals.length === 1 && vals.at(0) === "subjects") {
+ await interaction.editReply({
+ content: `Current subjects setting: ${config.subjects
+ .toString()
+ .split(",")
+ .join(", ")}`,
+ components: [],
+ });
+ } else if (vals.length === 1 && vals.at(0) === "gradelevels") {
+ await interaction.editReply({
+ content: `Current grade level setting: ${config.gradeLevels
+ .toString()
+ .split(",")
+ .join(", ")}`,
+ components: [],
+ });
+ } else {
+ (err) =>
+ log({
+ logger:
+ "'Error occurred: /settings:display did not equal subjects or gradelevels.'",
+ content: `${err}`,
+ level: "error",
+ });
+ }
+ });
+ });
+ break;
+ }
+ case "gradelevels": {
+ await interaction.deferReply();
- const settingsEmbed = new MessageEmbed()
- .setColor('#ffffff');
+ const settingsEmbed = new MessageEmbed().setColor("#ffffff");
- const user = interaction.options.getUser('user') || interaction.user;
+ const user = interaction.options.getUser("user") || interaction.user;
- settingsEmbed
- .setAuthor({ name: user.tag, iconURL: user.displayAvatarURL() })
- .setDescription('Current level settings: ');
- const menu = new MessageActionRow()
- .addComponents(
- new MessageSelectMenu()
- .setCustomId('selectlvl')
- .setPlaceholder('Nothing selected')
- .setMinValues(1)
- .setMaxValues(2)
- .addOptions([
- {
- label: 'Middle School',
- description: 'Middle school level problems',
- value: 'MS',
- },
- {
- label: 'High School',
- description: 'High school level problems',
- value: 'HS',
- },
- ]),
- );
+ settingsEmbed
+ .setAuthor({ name: user.tag, iconURL: user.displayAvatarURL() })
+ .setDescription("Current level settings: ");
+ const menu = new MessageActionRow().addComponents(
+ new MessageSelectMenu()
+ .setCustomId("selectlvl")
+ .setPlaceholder("Nothing selected")
+ .setMinValues(1)
+ .setMaxValues(2)
+ .addOptions([
+ {
+ label: "Middle School",
+ description: "Middle school level problems",
+ value: "MS",
+ },
+ {
+ label: "High School",
+ description: "High school level problems",
+ value: "HS",
+ },
+ ])
+ );
- interaction.followUp({
- embeds: [/* settingsEmbed*/],
- components: [menu],
- })
- .then((lvlMsg => {
- const w = lvlMsg as Message;
- const lvlFilter = i => ['selectlvl'].includes(i.customId) && i.user.id == interaction.user.id; // <== ATTENTION! First argument...
- w.awaitMessageComponent({ filter: lvlFilter, componentType: 'SELECT_MENU' })
- .then(async lvlChoice => {
- const vals = lvlChoice.values;
- const levels = new Array();
- await userConfig.findOneAndUpdate({ _id: interaction.user.id }, { gradeLevels: vals }, {
- upsert: true,
- new: true,
- });
- await vals.forEach(v => {
- switch (v) {
- case 'MS':
- levels.push('Middle School');
- break;
- case 'HS':
- levels.push('High School');
- }
- });
- await interaction.editReply({
- content: `Level set to: ${levels.toString().split(',').join(', ')}`,
- embeds: [],
- components: [],
- });
- });
- }));
- break;
- }
- case 'subject': {
- await interaction.deferReply();
+ interaction
+ .followUp({
+ embeds: [
+ /* settingsEmbed*/
+ ],
+ components: [menu],
+ })
+ .then((lvlMsg) => {
+ const w = lvlMsg as Message;
+ const lvlFilter = (i) =>
+ ["selectlvl"].includes(i.customId) &&
+ i.user.id == interaction.user.id; // <== ATTENTION! First argument...
+ w.awaitMessageComponent({
+ filter: lvlFilter,
+ componentType: "SELECT_MENU",
+ }).then(async (lvlChoice) => {
+ const vals = lvlChoice.values;
+ const levels = new Array();
+ await userConfig.findOneAndUpdate(
+ { _id: interaction.user.id },
+ { gradeLevels: vals },
+ {
+ upsert: true,
+ new: true,
+ }
+ );
+ await vals.forEach((v) => {
+ switch (v) {
+ case "MS":
+ levels.push("Middle School");
+ break;
+ case "HS":
+ levels.push("High School");
+ }
+ });
+ await interaction.editReply({
+ content: `Level set to: ${levels
+ .toString()
+ .split(",")
+ .join(", ")}`,
+ embeds: [],
+ components: [],
+ });
+ });
+ });
+ break;
+ }
+ case "subject": {
+ await interaction.deferReply();
- const settingsEmbed = new MessageEmbed()
- .setColor('#ffffff');
+ const settingsEmbed = new MessageEmbed().setColor("#ffffff");
- const user = interaction.options.getUser('user') || interaction.user;
+ const user = interaction.options.getUser("user") || interaction.user;
- settingsEmbed
- .setAuthor({ name: user.tag, iconURL: user.displayAvatarURL() })
- .setDescription('Current subject settings: ');
- const menu = new MessageActionRow()
- .addComponents(
- new MessageSelectMenu()
- .setCustomId('selectsubject')
- .setPlaceholder('Nothing selected')
- .setMinValues(1)
- .setMaxValues(7)
- .addOptions([
- {
- label: 'Astronomy',
- description: 'Astronomy',
- value: 'ASTRONOMY',
- },
- {
- label: 'Biology',
- description: 'Biology',
- value: 'BIOLOGY',
- },
- {
- label: 'Earth Science',
- description: 'Earth Science',
- value: 'EARTH SCIENCE',
- },
- {
- label: 'Chemistry',
- description: 'Chemistry',
- value: 'CHEMISTRY',
- },
- {
- label: 'Physics',
- description: 'Physics',
- value: 'PHYSICS',
- },
- {
- label: 'Mathematics',
- description: 'Mathematics',
- value: 'MATH',
- },
- {
- label: 'Energy',
- description: 'Energy',
- value: 'ENERGY',
- },
- ]),
- );
+ settingsEmbed
+ .setAuthor({ name: user.tag, iconURL: user.displayAvatarURL() })
+ .setDescription("Current subject settings: ");
+ const menu = new MessageActionRow().addComponents(
+ new MessageSelectMenu()
+ .setCustomId("selectsubject")
+ .setPlaceholder("Nothing selected")
+ .setMinValues(1)
+ .setMaxValues(7)
+ .addOptions([
+ {
+ label: "Astronomy",
+ description: "Astronomy",
+ value: "ASTRONOMY",
+ },
+ {
+ label: "Biology",
+ description: "Biology",
+ value: "BIOLOGY",
+ },
+ {
+ label: "Earth Science",
+ description: "Earth Science",
+ value: "EARTH SCIENCE",
+ },
+ {
+ label: "Chemistry",
+ description: "Chemistry",
+ value: "CHEMISTRY",
+ },
+ {
+ label: "Physics",
+ description: "Physics",
+ value: "PHYSICS",
+ },
+ {
+ label: "Mathematics",
+ description: "Mathematics",
+ value: "MATH",
+ },
+ {
+ label: "Energy",
+ description: "Energy",
+ value: "ENERGY",
+ },
+ ])
+ );
- interaction.followUp({
- embeds: [/* settingsEmbed*/],
- components: [menu],
- })
- .then((subjectMsg => {
- const subjectFilter = i => ['selectsubject'].includes(i.customId) && i.user.id == interaction.user.id; // <== ATTENTION! First argument...
- (subjectMsg as Message).awaitMessageComponent({ filter: subjectFilter, componentType: 'SELECT_MENU' })
- .then(async subjectChoice => {
- const vals = subjectChoice.values;
- await userConfig.findOneAndUpdate({ _id: interaction.user.id }, { subjects: vals }, {
- upsert: true,
- new: true,
- });
- const subjects = new Array();
- await vals.forEach(v => {
- subjects.push(v.toLowerCase().split(' ').map(w => w[0].toUpperCase() + w.substring(1)).join(' '));
- });
- await interaction.editReply({
- content: `Subjects set to: ${subjects.toString().split(',').join(', ')}`,
- components: [],
- embeds: [],
- });
- });
- }));
- break;
- }
- }
+ interaction
+ .followUp({
+ embeds: [
+ /* settingsEmbed*/
+ ],
+ components: [menu],
+ })
+ .then((subjectMsg) => {
+ const subjectFilter = (i) =>
+ ["selectsubject"].includes(i.customId) &&
+ i.user.id == interaction.user.id; // <== ATTENTION! First argument...
+ (subjectMsg as Message)
+ .awaitMessageComponent({
+ filter: subjectFilter,
+ componentType: "SELECT_MENU",
+ })
+ .then(async (subjectChoice) => {
+ const vals = subjectChoice.values;
+ await userConfig.findOneAndUpdate(
+ { _id: interaction.user.id },
+ { subjects: vals },
+ {
+ upsert: true,
+ new: true,
+ }
+ );
+ const subjects = new Array();
+ await vals.forEach((v) => {
+ subjects.push(
+ v
+ .toLowerCase()
+ .split(" ")
+ .map((w) => w[0].toUpperCase() + w.substring(1))
+ .join(" ")
+ );
+ });
+ await interaction.editReply({
+ content: `Subjects set to: ${subjects
+ .toString()
+ .split(",")
+ .join(", ")}`,
+ components: [],
+ embeds: [],
+ });
+ });
+ });
+ break;
+ }
+ }
}
diff --git a/src/commands/top.ts b/src/commands/top.ts
index 1ddd36a..3e08a4c 100644
--- a/src/commands/top.ts
+++ b/src/commands/top.ts
@@ -1,63 +1,75 @@
-import { SlashCommandBuilder } from '@discordjs/builders';
-import { CommandInteraction, MessageEmbed } from 'discord.js';
-
-import log from '../helpers/log';
-import userScore from '../models/userScore';
-
-export const data = new SlashCommandBuilder()
- .setName('top')
- .setDescription('Lists top ten scores across servers and in the current server');
-
-export async function execute(interaction: CommandInteraction) {
- await interaction.deferReply();
-
- userScore
- .find({})
- .sort({ score: -1 }) // Sort by descending order
- .exec(async (err, obj) => {
- if (err) {
- log({ logger: 'top', content: `Getting top players failed: ${err}`, level: 'error' });
- console.log(err);
- }
-
- if (obj.length < 10) {
- // Need at least 10 scores for top 10
- return interaction.followUp(
- `There are only ${obj.length} users, we need at least 10!`,
- );
- }
-
- const embeds: MessageEmbed[] = [];
- let lbMessageContent = '';
-
- for (let i = 0; i < 10; i++) {
- lbMessageContent += `${i + 1}: <@${obj[i].authorID}>: ${obj[i].score}\n`; // Loop through each user and add their name and score to leaderboard content
- }
-
- const leaderboardEmbed = new MessageEmbed()
- .setTitle('Top Ten!')
- .setDescription(lbMessageContent)
- .setColor('#ffffff');
-
- embeds.push(leaderboardEmbed);
-
- let sMessageContent = '';
- const members = await interaction.guild?.members.fetch();
-
- const serverLeaderBoardArray = await obj.filter(o => members?.some(m => m.user.id === o.authorID));
- if (serverLeaderBoardArray.length > 10) {
- for (let i = 0; i < 10; i++) {
- sMessageContent += `${i + 1}: <@${serverLeaderBoardArray[i].authorID}>: ${serverLeaderBoardArray[i].score}\n`;
- }
-
- const sLeaderboardEmbed = new MessageEmbed()
- .setTitle(`Top Ten in ${interaction.guild?.name}!`)
- .setDescription(sMessageContent)
- .setColor('#ffffff');
-
- embeds.push(sLeaderboardEmbed);
- }
-
- interaction.followUp({ embeds: embeds });
- });
-}
+import { SlashCommandBuilder } from "@discordjs/builders";
+import { CommandInteraction, MessageEmbed } from "discord.js";
+
+import log from "../helpers/log";
+import userScore from "../models/userScore";
+
+export const data = new SlashCommandBuilder()
+ .setName("top")
+ .setDescription(
+ "Lists top ten scores across servers and in the current server"
+ );
+
+export async function execute(interaction: CommandInteraction) {
+ await interaction.deferReply();
+
+ userScore
+ .find({})
+ .sort({ score: -1 }) // Sort by descending order
+ .exec(async (err, obj) => {
+ if (err) {
+ log({
+ logger: "top",
+ content: `Getting top players failed: ${err}`,
+ level: "error",
+ });
+ console.log(err);
+ }
+
+ if (obj.length < 10) {
+ // Need at least 10 scores for top 10
+ return interaction.followUp(
+ `There are only ${obj.length} users, we need at least 10!`
+ );
+ }
+
+ const embeds: MessageEmbed[] = [];
+ let lbMessageContent = "";
+
+ for (let i = 0; i < 10; i++) {
+ lbMessageContent += `${i + 1}: <@${obj[i].authorID}>: ${
+ obj[i].score
+ }\n`; // Loop through each user and add their name and score to leaderboard content
+ }
+
+ const leaderboardEmbed = new MessageEmbed()
+ .setTitle("Top Ten!")
+ .setDescription(lbMessageContent)
+ .setColor("#ffffff");
+
+ embeds.push(leaderboardEmbed);
+
+ let sMessageContent = "";
+ const members = await interaction.guild?.members.fetch();
+
+ const serverLeaderBoardArray = await obj.filter((o) =>
+ members?.some((m) => m.user.id === o.authorID)
+ );
+ if (serverLeaderBoardArray.length > 10) {
+ for (let i = 0; i < 10; i++) {
+ sMessageContent += `${i + 1}: <@${
+ serverLeaderBoardArray[i].authorID
+ }>: ${serverLeaderBoardArray[i].score}\n`;
+ }
+
+ const sLeaderboardEmbed = new MessageEmbed()
+ .setTitle(`Top Ten in ${interaction.guild?.name}!`)
+ .setDescription(sMessageContent)
+ .setColor("#ffffff");
+
+ embeds.push(sLeaderboardEmbed);
+ }
+
+ interaction.followUp({ embeds: embeds });
+ });
+}
diff --git a/src/commands/train.ts b/src/commands/train.ts
index f398d6d..7f57201 100644
--- a/src/commands/train.ts
+++ b/src/commands/train.ts
@@ -1,259 +1,322 @@
-import { SlashCommandBuilder } from '@discordjs/builders';
-import { MessageEmbed, MessageActionRow, MessageButton, CommandInteraction, Message } from 'discord.js';
-
-import { decode } from 'html-entities';
-import axios from 'axios';
-
-import userScore from '../models/userScore';
-import userConfig from '../models/userConfig';
-
-import log from '../helpers/log.js';
-import { updateScore } from '../helpers/db.js';
-
-export const data = new SlashCommandBuilder()
- .setName('train')
- .setDescription('Sends a training question to be answered')
- .addStringOption(option => {
- option
- .setName('subject')
- .setDescription('Optional subject to be used as a filter')
- .setRequired(false)
- .addChoices(
- { name: 'astro', value: 'astro' },
- { name: 'bio', value: 'bio' },
- { name: 'chem', value: 'chem' },
- { name: 'ess', value: 'ess' },
- { name: 'phys', value: 'phys' },
- { name: 'math', value: 'math' },
- { name: 'energy', value: 'energy' },
- )
- .setRequired(false);
- return option;
- });
-
-export async function execute(interaction: CommandInteraction) {
- await interaction.deferReply();
-
- const subject = interaction.options.get('subject') ? interaction.options.get('subject')?.value : null;
- const authorId = interaction.user.id;
- let score: number;
- userScore
- .findOne({ authorID: authorId })
- .lean()
- .then((obj: { score: number; }, err: unknown) => {
- if (!obj) {
- score = 0;
- const firstTimeEmbed = new MessageEmbed()
- .setAuthor({
- name: interaction.client.user?.tag ? interaction.client.user?.tag : '',
- iconURL: interaction.client.user?.displayAvatarURL(),
- })
- .setDescription('Hey! It seems like it\'s your first time using AwesomeSciBo. Here\'s some information regarding the bot if you need it (for issues, contributions, etc.):')
- .addField('Creator', '<@745063586422063214> [@abheekd#3602]')
- .addField('GitHub', '[Link](https://github.com/ADawesomeguy/AwesomeSciBo) (a star couldn\'t hurt...)')
- .setColor('#ffffff')
- .setTimestamp();
- interaction.user.send({ embeds: [firstTimeEmbed] })
- .catch(err => log({ logger: 'train', content: `${err}`, level: 'error' }));
- }
- else if (obj) {
- score = obj.score;
- }
- else {
- log({ logger: 'train', content: `Getting user score failed: ${err}`, level: 'error' });
- }
- });
-
- let categoryArray: string[] = [];
- const allCategories = ['BIOLOGY', 'PHYSICS', 'CHEMISTRY', 'EARTH AND SPACE', 'ASTRONOMY', 'MATH'];
- const configCategories = await userConfig.findById(interaction.user.id);
-
- switch (subject) {
- case null:
- categoryArray = (configCategories ? (configCategories.subjects || allCategories) : allCategories);
- break;
- case 'astro':
- case 'astronomy':
- categoryArray = ['ASTRONOMY'];
- break;
- case 'bio':
- case 'biology':
- categoryArray = ['BIOLOGY'];
- break;
- case 'ess':
- case 'earth science':
- case 'es':
- categoryArray = ['EARTH SCIENCE'];
- break;
- case 'chem':
- case 'chemistry':
- categoryArray = ['CHEMISTRY'];
- break;
- case 'phys':
- case 'physics':
- categoryArray = ['PHYSICS'];
- break;
- case 'math':
- categoryArray = ['MATH'];
- break;
- case 'energy':
- categoryArray = ['ENERGY'];
- break;
- default:
- interaction.followUp({
- embeds: [new MessageEmbed()
- .setDescription('<:red_x:816791117671825409> Not a valid subject!')
- .setColor('#ffffff')],
- });
- return;
- }
-
- axios
- .post('https://scibowldb.com/api/questions/random', { categories: categoryArray })
- .then((res) => {
- const questionData = res.data.question;
- const tossupQuestion = questionData.tossup_question;
- const tossupAnswer = questionData.tossup_answer;
- const tossupFormat = questionData.tossup_format;
- let answers = tossupAnswer.split(' (ACCEPT: ');
- if (answers.length > 1) {
- answers[1] = answers[1].slice(0, answers[1].length - 1); // If there are multiple elements, it means there was an 'accept' and therefore a trailing ')' which should be removed
- answers = [answers[0], ...answers[1].split(new RegExp(' OR ', 'i'))]; // Use the first element plus the last element split by 'OR' case insensitive
- }
- interaction.followUp({ content: decode(tossupQuestion), fetchReply: true })
- .then(q => {
- const questionMessage = q as Message;
- const sourceButton = new MessageActionRow()
- .addComponents(
- new MessageButton()
- .setURL(questionData.uri)
- .setLabel('Source')
- .setStyle('LINK'),
- );
- switch (tossupFormat) {
- case 'Short Answer': {
- // eslint-disable-next-line no-case-declarations
- const messageFilter = m => m.author.id === interaction.user.id || m.author.id === interaction.client.user?.id;
- interaction.channel?.awaitMessages({
- filter: messageFilter,
- max: 1,
- })
- .then(collected => {
- const answerMsg = collected.first();
-
- if (answerMsg?.author.id === interaction.client.user?.id) return;
-
- let predicted = '';
- if (answerMsg?.content.toLowerCase() === tossupAnswer.toLowerCase() || answers.includes(answerMsg?.content.toUpperCase())) {
- predicted = 'correct';
- }
- else {
- predicted = 'incorrect';
- }
-
- if (predicted === 'correct') {
- updateScore(true, score, authorId).then((msgToReply) =>
- answerMsg?.reply(msgToReply),
- );
- }
- else {
- const overrideEmbed = new MessageEmbed()
- .setAuthor({
- name: answerMsg?.author.tag ? answerMsg.author.tag : '',
- iconURL: answerMsg?.author.displayAvatarURL(),
- })
- .addField('Correct answer', `\`${tossupAnswer}\``)
- .setDescription('It seems your answer was incorrect. Please react with <:override:955265585086857236> to override your answer if you think you got it right.')
- .setColor('#ffffff')
- .setTimestamp();
- const overrideButton = new MessageActionRow()
- .addComponents(
- new MessageButton()
- .setCustomId('override')
- .setEmoji('<:override:955265585086857236>')
- .setStyle('SECONDARY'),
- );
- answerMsg?.channel.send({
- embeds: [overrideEmbed],
- components: [overrideButton],
- })
- .then(overrideMsg => {
- const overrideFilter = i => {
- return (
- ['override'].includes(i.customId) &&
- i.user.id === answerMsg.author.id
- );
- };
- overrideMsg
- .awaitMessageComponent({
- filter: overrideFilter,
- })
- .then(i => {
- updateScore(true, score, authorId).then(async msgToReply => {
- await i.reply(msgToReply);
- overrideMsg.edit({ components: [] });
- });
- }).catch(err => log({
- logger: 'train',
- content: `Failed to override score: ${err}`,
- level: 'error',
- }));
- }).catch(err => log({
- logger: 'train',
- content: `Failed to send override message: ${err}`,
- level: 'error',
- }));
- }
- interaction.editReply({ components: [sourceButton] });
- }).catch(err => log({ logger: 'train', content: `${err}`, level: 'error' }));
- break;
- }
- case 'Multiple Choice': {
- const choices = new MessageActionRow()
- .addComponents(
- new MessageButton()
- .setCustomId('w')
- .setLabel('W')
- .setStyle('SECONDARY'),
- new MessageButton()
- .setCustomId('x')
- .setLabel('X')
- .setStyle('SECONDARY'),
- new MessageButton()
- .setCustomId('y')
- .setLabel('Y')
- .setStyle('SECONDARY'),
- new MessageButton()
- .setCustomId('z')
- .setLabel('Z')
- .setStyle('SECONDARY'),
- );
- interaction.editReply({ components: [choices] });
- const mcFilter = i => ['w', 'x', 'y', 'z'].includes(i.customId) && i.user.id === interaction.user.id;
- questionMessage.awaitMessageComponent({ filter: mcFilter })
- .then(mcChoice => {
- if (tossupAnswer.charAt(0).toLowerCase() === mcChoice.customId) {
- updateScore(true, score, authorId).then((msgToReply) =>
- mcChoice.reply(msgToReply),
- );
- }
- else {
- const incorrectEmbed = new MessageEmbed()
- .setAuthor({
- name: interaction.user.tag,
- iconURL: interaction.user.displayAvatarURL(),
- })
- .addField('Correct answer', `\`${tossupAnswer}\``)
- .setDescription(`It seems your answer ${mcChoice.customId.toUpperCase()} was incorrect.`)
- .setColor('#ffffff')
- .setTimestamp();
- mcChoice.reply({ embeds: [incorrectEmbed] });
- }
- interaction.editReply({ components: [sourceButton] });
- });
- break;
- }
- }
- }).catch(err => log({ logger: 'train', content: `${err}`, level: 'error' }));
- }).catch(err => log({ logger: 'train', content: `${err}`, level: 'error' }));
-}
+import { SlashCommandBuilder } from "@discordjs/builders";
+import {
+ MessageEmbed,
+ MessageActionRow,
+ MessageButton,
+ CommandInteraction,
+ Message,
+} from "discord.js";
+
+import { decode } from "html-entities";
+import axios from "axios";
+
+import userScore from "../models/userScore";
+import userConfig from "../models/userConfig";
+
+import log from "../helpers/log.js";
+import { updateScore } from "../helpers/db.js";
+
+export const data = new SlashCommandBuilder()
+ .setName("train")
+ .setDescription("Sends a training question to be answered")
+ .addStringOption((option) => {
+ option
+ .setName("subject")
+ .setDescription("Optional subject to be used as a filter")
+ .setRequired(false)
+ .addChoices(
+ { name: "astro", value: "astro" },
+ { name: "bio", value: "bio" },
+ { name: "chem", value: "chem" },
+ { name: "ess", value: "ess" },
+ { name: "phys", value: "phys" },
+ { name: "math", value: "math" },
+ { name: "energy", value: "energy" }
+ )
+ .setRequired(false);
+ return option;
+ });
+
+export async function execute(interaction: CommandInteraction) {
+ await interaction.deferReply();
+
+ const subject = interaction.options.get("subject")
+ ? interaction.options.get("subject")?.value
+ : null;
+ const authorId = interaction.user.id;
+ let score: number;
+ userScore
+ .findOne({ authorID: authorId })
+ .lean()
+ .then((obj: { score: number }, err: unknown) => {
+ if (!obj) {
+ score = 0;
+ const firstTimeEmbed = new MessageEmbed()
+ .setAuthor({
+ name: interaction.client.user?.tag
+ ? interaction.client.user?.tag
+ : "",
+ iconURL: interaction.client.user?.displayAvatarURL(),
+ })
+ .setDescription(
+ "Hey! It seems like it's your first time using AwesomeSciBo. Here's some information regarding the bot if you need it (for issues, contributions, etc.):"
+ )
+ .addField("Creator", "<@745063586422063214> [@abheekd#3602]")
+ .addField(
+ "GitHub",
+ "[Link](https://github.com/ADawesomeguy/AwesomeSciBo) (a star couldn't hurt...)"
+ )
+ .setColor("#ffffff")
+ .setTimestamp();
+ interaction.user
+ .send({ embeds: [firstTimeEmbed] })
+ .catch((err) =>
+ log({ logger: "train", content: `${err}`, level: "error" })
+ );
+ } else if (obj) {
+ score = obj.score;
+ } else {
+ log({
+ logger: "train",
+ content: `Getting user score failed: ${err}`,
+ level: "error",
+ });
+ }
+ });
+
+ let categoryArray: string[] = [];
+ const allCategories = [
+ "BIOLOGY",
+ "PHYSICS",
+ "CHEMISTRY",
+ "EARTH AND SPACE",
+ "ASTRONOMY",
+ "MATH",
+ ];
+ const configCategories = await userConfig.findById(interaction.user.id);
+
+ switch (subject) {
+ case null:
+ categoryArray = configCategories
+ ? configCategories.subjects || allCategories
+ : allCategories;
+ break;
+ case "astro":
+ case "astronomy":
+ categoryArray = ["ASTRONOMY"];
+ break;
+ case "bio":
+ case "biology":
+ categoryArray = ["BIOLOGY"];
+ break;
+ case "ess":
+ case "earth science":
+ case "es":
+ categoryArray = ["EARTH SCIENCE"];
+ break;
+ case "chem":
+ case "chemistry":
+ categoryArray = ["CHEMISTRY"];
+ break;
+ case "phys":
+ case "physics":
+ categoryArray = ["PHYSICS"];
+ break;
+ case "math":
+ categoryArray = ["MATH"];
+ break;
+ case "energy":
+ categoryArray = ["ENERGY"];
+ break;
+ default:
+ interaction.followUp({
+ embeds: [
+ new MessageEmbed()
+ .setDescription("<:red_x:816791117671825409> Not a valid subject!")
+ .setColor("#ffffff"),
+ ],
+ });
+ return;
+ }
+
+ axios
+ .post("https://scibowldb.com/api/questions/random", {
+ categories: categoryArray,
+ })
+ .then((res) => {
+ const questionData = res.data.question;
+ const tossupQuestion = questionData.tossup_question;
+ const tossupAnswer = questionData.tossup_answer;
+ const tossupFormat = questionData.tossup_format;
+ let answers = tossupAnswer.split(" (ACCEPT: ");
+ if (answers.length > 1) {
+ answers[1] = answers[1].slice(0, answers[1].length - 1); // If there are multiple elements, it means there was an 'accept' and therefore a trailing ')' which should be removed
+ answers = [answers[0], ...answers[1].split(new RegExp(" OR ", "i"))]; // Use the first element plus the last element split by 'OR' case insensitive
+ }
+ interaction
+ .followUp({ content: decode(tossupQuestion), fetchReply: true })
+ .then((q) => {
+ const questionMessage = q as Message;
+ const sourceButton = new MessageActionRow().addComponents(
+ new MessageButton()
+ .setURL(questionData.uri)
+ .setLabel("Source")
+ .setStyle("LINK")
+ );
+ switch (tossupFormat) {
+ case "Short Answer": {
+ // eslint-disable-next-line no-case-declarations
+ const messageFilter = (m) =>
+ m.author.id === interaction.user.id ||
+ m.author.id === interaction.client.user?.id;
+ interaction.channel
+ ?.awaitMessages({
+ filter: messageFilter,
+ max: 1,
+ })
+ .then((collected) => {
+ const answerMsg = collected.first();
+
+ if (answerMsg?.author.id === interaction.client.user?.id)
+ return;
+
+ let predicted = "";
+ if (
+ answerMsg?.content.toLowerCase() ===
+ tossupAnswer.toLowerCase() ||
+ answers.includes(answerMsg?.content.toUpperCase())
+ ) {
+ predicted = "correct";
+ } else {
+ predicted = "incorrect";
+ }
+
+ if (predicted === "correct") {
+ updateScore(true, score, authorId).then((msgToReply) =>
+ answerMsg?.reply(msgToReply)
+ );
+ } else {
+ const overrideEmbed = new MessageEmbed()
+ .setAuthor({
+ name: answerMsg?.author.tag ? answerMsg.author.tag : "",
+ iconURL: answerMsg?.author.displayAvatarURL(),
+ })
+ .addField("Correct answer", `\`${tossupAnswer}\``)
+ .setDescription(
+ "It seems your answer was incorrect. Please react with <:override:955265585086857236> to override your answer if you think you got it right."
+ )
+ .setColor("#ffffff")
+ .setTimestamp();
+ const overrideButton = new MessageActionRow().addComponents(
+ new MessageButton()
+ .setCustomId("override")
+ .setEmoji("<:override:955265585086857236>")
+ .setStyle("SECONDARY")
+ );
+ answerMsg?.channel
+ .send({
+ embeds: [overrideEmbed],
+ components: [overrideButton],
+ })
+ .then((overrideMsg) => {
+ const overrideFilter = (i) => {
+ return (
+ ["override"].includes(i.customId) &&
+ i.user.id === answerMsg.author.id
+ );
+ };
+ overrideMsg
+ .awaitMessageComponent({
+ filter: overrideFilter,
+ })
+ .then((i) => {
+ updateScore(true, score, authorId).then(
+ async (msgToReply) => {
+ await i.reply(msgToReply);
+ overrideMsg.edit({ components: [] });
+ }
+ );
+ })
+ .catch((err) =>
+ log({
+ logger: "train",
+ content: `Failed to override score: ${err}`,
+ level: "error",
+ })
+ );
+ })
+ .catch((err) =>
+ log({
+ logger: "train",
+ content: `Failed to send override message: ${err}`,
+ level: "error",
+ })
+ );
+ }
+ interaction.editReply({ components: [sourceButton] });
+ })
+ .catch((err) =>
+ log({ logger: "train", content: `${err}`, level: "error" })
+ );
+ break;
+ }
+ case "Multiple Choice": {
+ const choices = new MessageActionRow().addComponents(
+ new MessageButton()
+ .setCustomId("w")
+ .setLabel("W")
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setCustomId("x")
+ .setLabel("X")
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setCustomId("y")
+ .setLabel("Y")
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setCustomId("z")
+ .setLabel("Z")
+ .setStyle("SECONDARY")
+ );
+ interaction.editReply({ components: [choices] });
+ const mcFilter = (i) =>
+ ["w", "x", "y", "z"].includes(i.customId) &&
+ i.user.id === interaction.user.id;
+ questionMessage
+ .awaitMessageComponent({ filter: mcFilter })
+ .then((mcChoice) => {
+ if (
+ tossupAnswer.charAt(0).toLowerCase() === mcChoice.customId
+ ) {
+ updateScore(true, score, authorId).then((msgToReply) =>
+ mcChoice.reply(msgToReply)
+ );
+ } else {
+ const incorrectEmbed = new MessageEmbed()
+ .setAuthor({
+ name: interaction.user.tag,
+ iconURL: interaction.user.displayAvatarURL(),
+ })
+ .addField("Correct answer", `\`${tossupAnswer}\``)
+ .setDescription(
+ `It seems your answer ${mcChoice.customId.toUpperCase()} was incorrect.`
+ )
+ .setColor("#ffffff")
+ .setTimestamp();
+ mcChoice.reply({ embeds: [incorrectEmbed] });
+ }
+ interaction.editReply({ components: [sourceButton] });
+ });
+ break;
+ }
+ }
+ })
+ .catch((err) =>
+ log({ logger: "train", content: `${err}`, level: "error" })
+ );
+ })
+ .catch((err) =>
+ log({ logger: "train", content: `${err}`, level: "error" })
+ );
+}
diff --git a/src/deploy-commands.js b/src/deploy-commands.js
index a56e0b3..f531fa8 100644
--- a/src/deploy-commands.js
+++ b/src/deploy-commands.js
@@ -1,20 +1,23 @@
#!/usr/bin/env node
const fs = require('node:fs');
-const {REST} = require('@discordjs/rest');
-const {Routes} = require('discord-api-types/v9');
-const {clientId, token} = require('./helpers/env');
+const { REST } = require('@discordjs/rest');
+const { Routes } = require('discord-api-types/v9');
+const { clientId, token } = require('./helpers/env');
const commands = [];
-const commandFiles = fs.readdirSync(__dirname + '/commands').filter(file => file.endsWith('.js'));
+const commandFiles = fs
+ .readdirSync(__dirname + '/commands')
+ .filter((file) => file.endsWith('.js'));
for (const file of commandFiles) {
- const command = require(`${__dirname}/commands/${file}`);
- commands.push(command.data.toJSON());
+ const command = require(`${__dirname}/commands/${file}`);
+ commands.push(command.data.toJSON());
}
-const rest = new REST({version: '9'}).setToken(token);
+const rest = new REST({ version: '9' }).setToken(token);
-rest.put(Routes.applicationCommands(clientId), {body: commands})
- .then(() => console.log('Successfully registered application commands.'))
- .catch(console.error);
+rest
+ .put(Routes.applicationCommands(clientId), { body: commands })
+ .then(() => console.log('Successfully registered application commands.'))
+ .catch(console.error);
diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts
index 6692a94..0c4c61a 100644
--- a/src/events/interactionCreate.ts
+++ b/src/events/interactionCreate.ts
@@ -1,23 +1,29 @@
-import log from '../helpers/log';
+import log from "../helpers/log";
-export const name = 'interactionCreate';
+export const name = "interactionCreate";
export const once = false;
export async function execute(interaction) {
- const client = interaction.client;
+ const client = interaction.client;
- if (!interaction.isCommand()) return;
+ if (!interaction.isCommand()) return;
- const command = client.commands.get(interaction.commandName);
+ const command = client.commands.get(interaction.commandName);
- if (!command) return;
+ if (!command) return;
- try {
- await command.execute(interaction);
- }
- catch (error) {
- log({ logger: 'interaction', content: `Interaction ${interaction.commandName} failed!`, level: 'error' });
- await interaction.followUp({ content: 'There was an error while executing this command!', ephemeral: true });
- }
+ try {
+ await command.execute(interaction);
+ } catch (error) {
+ log({
+ logger: "interaction",
+ content: `Interaction ${interaction.commandName} failed!`,
+ level: "error",
+ });
+ await interaction.followUp({
+ content: "There was an error while executing this command!",
+ ephemeral: true,
+ });
+ }
}
diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts
index 3898e04..fa21848 100644
--- a/src/events/messageCreate.ts
+++ b/src/events/messageCreate.ts
@@ -1,36 +1,36 @@
-import axios from 'axios';
-import { MessageEmbed } from 'discord.js';
-import { decode } from 'html-entities';
+import axios from "axios";
+import { MessageEmbed } from "discord.js";
+import { decode } from "html-entities";
-import { testingGuild } from '../helpers/env';
+import { testingGuild } from "../helpers/env";
-export const name = 'messageCreate';
+export const name = "messageCreate";
export const once = false;
export async function execute(message) {
- if (message.author.bot || message.guild.id != testingGuild) return;
+ if (message.author.bot || message.guild.id != testingGuild) return;
- if (message.content.startsWith('!q')) {
- const questionId = message.content.split(' ')[1];
- axios
- .get(`https://scibowldb.com/api/questions/${questionId}`)
- .then((res) => {
- const data = res.data.question;
- const tossupQuestion = data.tossup_question;
- const tossupAnswer = data.tossup_answer;
- let answers = tossupAnswer.split(' (ACCEPT: ');
- if (answers.length > 1) {
- answers[1] = answers[1].slice(0, answers[1].length - 1); // If there are multiple elements, it means there was an 'accept' and therefore a trailing ')' which should be removed
- answers = [answers[0], ...answers[1].split(new RegExp(' OR ', 'i'))]; // Use the first element plus the last element split by 'OR' case insensitive
- }
- const dataEmbed = new MessageEmbed()
- .setTitle('Data')
- .setDescription(`\`\`\`json\n${JSON.stringify(data, null, 2)}\`\`\``);
- message.reply({
- content: decode(tossupQuestion) + `\n\nAnswers: [${answers}]`,
- embeds: [dataEmbed],
- });
- });
- }
-}
\ No newline at end of file
+ if (message.content.startsWith("!q")) {
+ const questionId = message.content.split(" ")[1];
+ axios
+ .get(`https://scibowldb.com/api/questions/${questionId}`)
+ .then((res) => {
+ const data = res.data.question;
+ const tossupQuestion = data.tossup_question;
+ const tossupAnswer = data.tossup_answer;
+ let answers = tossupAnswer.split(" (ACCEPT: ");
+ if (answers.length > 1) {
+ answers[1] = answers[1].slice(0, answers[1].length - 1); // If there are multiple elements, it means there was an 'accept' and therefore a trailing ')' which should be removed
+ answers = [answers[0], ...answers[1].split(new RegExp(" OR ", "i"))]; // Use the first element plus the last element split by 'OR' case insensitive
+ }
+ const dataEmbed = new MessageEmbed()
+ .setTitle("Data")
+ .setDescription(`\`\`\`json\n${JSON.stringify(data, null, 2)}\`\`\``);
+ message.reply({
+ content: decode(tossupQuestion) + `\n\nAnswers: [${answers}]`,
+ embeds: [dataEmbed],
+ });
+ });
+ }
+}
diff --git a/src/events/ready.ts b/src/events/ready.ts
index f816b31..9ff98b1 100644
--- a/src/events/ready.ts
+++ b/src/events/ready.ts
@@ -1,16 +1,17 @@
-import * as db from '../helpers/db';
-import { mongoUri } from '../helpers/env';
-import log from '../helpers/log';
+import * as db from "../helpers/db";
+import { mongoUri } from "../helpers/env";
+import log from "../helpers/log";
-export const name = 'ready';
+export const name = "ready";
export const once = true;
export async function execute(client) {
- await db.connect(mongoUri);
- log({ logger: 'status', content: `Logged in as ${client.user.tag}!`, level: 'info' });
- client.user.setActivity(
- 'for /help',
- { type: 'WATCHING' },
- );
+ await db.connect(mongoUri);
+ log({
+ logger: "status",
+ content: `Logged in as ${client.user.tag}!`,
+ level: "info",
+ });
+ client.user.setActivity("for /help", { type: "WATCHING" });
}
diff --git a/src/helpers/db.ts b/src/helpers/db.ts
index 26c2a15..7cde3d4 100644
--- a/src/helpers/db.ts
+++ b/src/helpers/db.ts
@@ -1,51 +1,67 @@
-import mongoose from 'mongoose';
-
-import log from '../helpers/log';
-import userScore from '../models/userScore';
-
-export async function updateScore(isCorrect: boolean, score: number, authorId: string) {
- if (!isCorrect) {
- return `Nice try! Your score is still ${score}.`;
- }
- else {
- // TODO: Error handling
- const doc = await userScore.findOne({
- authorID: authorId,
- });
- if (!doc) {
- const newUserScore = new userScore({
- authorID: authorId,
- score: score + 4,
- });
- newUserScore.save(err => {
- if (err) {
- log({ logger: 'db', content: `Error creating new user ${authorId} for scoring`, level: 'error' });
- }
- else {
- log({ logger: 'db', content: `Successfully created user ${authorId} for scoring`, level: 'debug' });
- }
- });
- }
- else {
- doc.score = doc.score + 4;
- doc.save();
- }
-
- return `Great job! Your score is now ${score + 4}.`;
- }
-}
-
-export async function connect(mongoUri) {
- mongoose
- .connect(mongoUri, {
- useUnifiedTopology: true,
- useNewUrlParser: true,
- })
- .then(() => log({ logger: 'db', content: `Connected to the database at ${mongoUri}!`, level: 'info' }))
- .catch(err => log({
- logger: 'db',
- content: `Failed to connect to the database at ${mongoUri}: ${err}`,
- level: 'fatal',
- }));
-}
-
+import mongoose from "mongoose";
+
+import log from "../helpers/log";
+import userScore from "../models/userScore";
+
+export async function updateScore(
+ isCorrect: boolean,
+ score: number,
+ authorId: string
+) {
+ if (!isCorrect) {
+ return `Nice try! Your score is still ${score}.`;
+ } else {
+ // TODO: Error handling
+ const doc = await userScore.findOne({
+ authorID: authorId,
+ });
+ if (!doc) {
+ const newUserScore = new userScore({
+ authorID: authorId,
+ score: score + 4,
+ });
+ newUserScore.save((err) => {
+ if (err) {
+ log({
+ logger: "db",
+ content: `Error creating new user ${authorId} for scoring`,
+ level: "error",
+ });
+ } else {
+ log({
+ logger: "db",
+ content: `Successfully created user ${authorId} for scoring`,
+ level: "debug",
+ });
+ }
+ });
+ } else {
+ doc.score = doc.score + 4;
+ doc.save();
+ }
+
+ return `Great job! Your score is now ${score + 4}.`;
+ }
+}
+
+export async function connect(mongoUri) {
+ mongoose
+ .connect(mongoUri, {
+ useUnifiedTopology: true,
+ useNewUrlParser: true,
+ })
+ .then(() =>
+ log({
+ logger: "db",
+ content: `Connected to the database at ${mongoUri}!`,
+ level: "info",
+ })
+ )
+ .catch((err) =>
+ log({
+ logger: "db",
+ content: `Failed to connect to the database at ${mongoUri}: ${err}`,
+ level: "fatal",
+ })
+ );
+}
diff --git a/src/helpers/env.ts b/src/helpers/env.ts
index 79f63b4..8f79d7a 100644
--- a/src/helpers/env.ts
+++ b/src/helpers/env.ts
@@ -1,6 +1,7 @@
-import 'dotenv/config';
+import "dotenv/config";
-export const clientId = process.env.CLIENT_ID || '';
-export const testingGuild = process.env.TESTING_GUILD || '';
-export const token = process.env.TOKEN || '';
-export const mongoUri = process.env.MONGO_URI = 'mongodb://mongo:27017/AWESOME';
+export const clientId = process.env.CLIENT_ID || "";
+export const testingGuild = process.env.TESTING_GUILD || "";
+export const token = process.env.TOKEN || "";
+export const mongoUri = (process.env.MONGO_URI =
+ "mongodb://mongo:27017/AWESOME");
diff --git a/src/helpers/log.ts b/src/helpers/log.ts
index 07995e4..bc9a156 100644
--- a/src/helpers/log.ts
+++ b/src/helpers/log.ts
@@ -1,29 +1,29 @@
-import log4js from 'log4js';
+import log4js from "log4js";
-export default function(config) {
- const logger = log4js.getLogger(config.logger);
- logger.level = 'debug';
- switch (config.level) {
- case 'trace':
- logger.trace(config.content);
- break;
- case 'debug':
- logger.debug(config.content);
- break;
- case 'info':
- logger.info(config.content);
- break;
- case 'warn':
- logger.warn(config.content);
- break;
- case 'error':
- logger.error(config.content);
- break;
- case 'fatal':
- logger.fatal(config.content);
- break;
- default:
- logger.debug(config.content);
- break;
- }
-}
\ No newline at end of file
+export default function (config) {
+ const logger = log4js.getLogger(config.logger);
+ logger.level = "debug";
+ switch (config.level) {
+ case "trace":
+ logger.trace(config.content);
+ break;
+ case "debug":
+ logger.debug(config.content);
+ break;
+ case "info":
+ logger.info(config.content);
+ break;
+ case "warn":
+ logger.warn(config.content);
+ break;
+ case "error":
+ logger.error(config.content);
+ break;
+ case "fatal":
+ logger.fatal(config.content);
+ break;
+ default:
+ logger.debug(config.content);
+ break;
+ }
+}
diff --git a/src/helpers/util/pagination.ts b/src/helpers/util/pagination.ts
index b296fb5..36f5342 100644
--- a/src/helpers/util/pagination.ts
+++ b/src/helpers/util/pagination.ts
@@ -1,87 +1,113 @@
-import { CommandInteraction, Message, MessageActionRow, MessageButton, MessageEmbed } from 'discord.js';
+import {
+ CommandInteraction,
+ Message,
+ MessageActionRow,
+ MessageButton,
+ MessageEmbed,
+} from "discord.js";
-export async function paginateMessage(message: Message, embeds: MessageEmbed[]) {
- let index = 0;
+export async function paginateMessage(
+ message: Message,
+ embeds: MessageEmbed[]
+) {
+ let index = 0;
- const row = new MessageActionRow;
- row.addComponents(
- new MessageButton()
- .setCustomId('paginator-left')
- .setEmoji('868552005977788466')
- .setStyle('SECONDARY'),
- new MessageButton()
- .setCustomId('paginator-right')
- .setEmoji('868551772887711754')
- .setStyle('SECONDARY')
- );
+ const row = new MessageActionRow();
+ row.addComponents(
+ new MessageButton()
+ .setCustomId("paginator-left")
+ .setEmoji("868552005977788466")
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setCustomId("paginator-right")
+ .setEmoji("868551772887711754")
+ .setStyle("SECONDARY")
+ );
- await message.reply({ content: `Page 1 of ${embeds.length}:`, embeds: [embeds[index]], components: [row] })
- .then(async paginatorMessage => {
- const filter = m => m.author.id === message.author.id;
+ await message
+ .reply({
+ content: `Page 1 of ${embeds.length}:`,
+ embeds: [embeds[index]],
+ components: [row],
+ })
+ .then(async (paginatorMessage) => {
+ const filter = (m) => m.author.id === message.author.id;
- const paginatorCollector = paginatorMessage.createMessageComponentCollector({
- componentType: 'BUTTON',
- filter: filter,
- });
+ const paginatorCollector =
+ paginatorMessage.createMessageComponentCollector({
+ componentType: "BUTTON",
+ filter: filter,
+ });
- paginatorCollector.on('collect', async i => {
- switch (i.customId) {
- case 'paginator-left':
- index--;
- if (index < 0) index = embeds.length - 1;
- break;
- case 'paginator-right':
- index++;
- if (index > embeds.length - 1) index = 0;
- break;
- }
- paginatorMessage.edit({ content: `Page ${index + 1} of ${embeds.length}:`, embeds: [embeds[index]] });
- });
- });
+ paginatorCollector.on("collect", async (i) => {
+ switch (i.customId) {
+ case "paginator-left":
+ index--;
+ if (index < 0) index = embeds.length - 1;
+ break;
+ case "paginator-right":
+ index++;
+ if (index > embeds.length - 1) index = 0;
+ break;
+ }
+ paginatorMessage.edit({
+ content: `Page ${index + 1} of ${embeds.length}:`,
+ embeds: [embeds[index]],
+ });
+ });
+ });
}
-export async function paginateInteraction(interaction: CommandInteraction, embeds: MessageEmbed[]) {
- let index = 0;
+export async function paginateInteraction(
+ interaction: CommandInteraction,
+ embeds: MessageEmbed[]
+) {
+ let index = 0;
- const row = new MessageActionRow;
- row.addComponents(
- new MessageButton()
- .setCustomId('paginator-left')
- .setEmoji('868552005977788466')
- .setStyle('SECONDARY'),
- new MessageButton()
- .setCustomId('paginator-right')
- .setEmoji('868551772887711754')
- .setStyle('SECONDARY')
- );
+ const row = new MessageActionRow();
+ row.addComponents(
+ new MessageButton()
+ .setCustomId("paginator-left")
+ .setEmoji("868552005977788466")
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setCustomId("paginator-right")
+ .setEmoji("868551772887711754")
+ .setStyle("SECONDARY")
+ );
- await interaction.followUp({
- content: `Page 1 of ${embeds.length}:`,
- embeds: [embeds[index]],
- components: [row],
- fetchReply: true,
- })
- .then(async p => {
- const paginatorMessage = p as Message;
- const filter = i => i.user.id === interaction.user.id;
+ await interaction
+ .followUp({
+ content: `Page 1 of ${embeds.length}:`,
+ embeds: [embeds[index]],
+ components: [row],
+ fetchReply: true,
+ })
+ .then(async (p) => {
+ const paginatorMessage = p as Message;
+ const filter = (i) => i.user.id === interaction.user.id;
- const paginatorCollector = paginatorMessage.createMessageComponentCollector({
- componentType: 'BUTTON',
- filter: filter,
- });
+ const paginatorCollector =
+ paginatorMessage.createMessageComponentCollector({
+ componentType: "BUTTON",
+ filter: filter,
+ });
- paginatorCollector.on('collect', async i => {
- switch (i.customId) {
- case 'paginator-left':
- index--;
- if (index < 0) index = embeds.length - 1;
- break;
- case 'paginator-right':
- index++;
- if (index > embeds.length - 1) index = 0;
- break;
- }
- await i.update({ content: `Page ${index + 1} of ${embeds.length}:`, embeds: [embeds[index]] });
- });
- });
-}
\ No newline at end of file
+ paginatorCollector.on("collect", async (i) => {
+ switch (i.customId) {
+ case "paginator-left":
+ index--;
+ if (index < 0) index = embeds.length - 1;
+ break;
+ case "paginator-right":
+ index++;
+ if (index > embeds.length - 1) index = 0;
+ break;
+ }
+ await i.update({
+ content: `Page ${index + 1} of ${embeds.length}:`,
+ embeds: [embeds[index]],
+ });
+ });
+ });
+}
diff --git a/src/index.ts b/src/index.ts
index 1567f02..831e906 100755
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,38 +1,54 @@
#!/usr/bin/env node
-import fs from 'node:fs';
-import { Client, Collection, Intents } from 'discord.js';
-import { token } from './helpers/env';
-import log from './helpers/log';
+import fs from "node:fs";
+import { Client, Collection, Intents } from "discord.js";
+import { token } from "./helpers/env";
+import log from "./helpers/log";
const client = new Client({
- intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MESSAGE_REACTIONS, Intents.FLAGS.GUILD_MEMBERS, Intents.FLAGS.DIRECT_MESSAGES, Intents.FLAGS.DIRECT_MESSAGE_REACTIONS],
+ intents: [
+ Intents.FLAGS.GUILDS,
+ Intents.FLAGS.GUILD_MESSAGES,
+ Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
+ Intents.FLAGS.GUILD_MEMBERS,
+ Intents.FLAGS.DIRECT_MESSAGES,
+ Intents.FLAGS.DIRECT_MESSAGE_REACTIONS,
+ ],
});
-client['commands'] = new Collection();
+client["commands"] = new Collection();
-const commandFiles = fs.readdirSync(`${__dirname}/commands`).filter(file => file.endsWith('.js'));
-const eventFiles = fs.readdirSync(`${__dirname}/events`).filter(file => file.endsWith('.js'));
+const commandFiles = fs
+ .readdirSync(`${__dirname}/commands`)
+ .filter((file) => file.endsWith(".js"));
+const eventFiles = fs
+ .readdirSync(`${__dirname}/events`)
+ .filter((file) => file.endsWith(".js"));
for (const file of commandFiles) {
- import(`${__dirname}/commands/${file}`)
- .then(command => {
- client['commands'].set(command.data.name, command);
- log({ logger: 'command', content: `Registered command ${file}!`, level: 'info' });
- });
+ import(`${__dirname}/commands/${file}`).then((command) => {
+ client["commands"].set(command.data.name, command);
+ log({
+ logger: "command",
+ content: `Registered command ${file}!`,
+ level: "info",
+ });
+ });
}
for (const file of eventFiles) {
- import(`${__dirname}/events/${file}`)
- .then(event => {
- if (event.once) {
- client.once(event.name, (...args) => event.execute(...args));
- }
- else {
- client.on(event.name, (...args) => event.execute(...args));
- }
- log({ logger: 'event', content: `Registered event ${file}!`, level: 'info' });
- });
+ import(`${__dirname}/events/${file}`).then((event) => {
+ if (event.once) {
+ client.once(event.name, (...args) => event.execute(...args));
+ } else {
+ client.on(event.name, (...args) => event.execute(...args));
+ }
+ log({
+ logger: "event",
+ content: `Registered event ${file}!`,
+ level: "info",
+ });
+ });
}
client.login(token);
diff --git a/src/models/generatedRound.ts b/src/models/generatedRound.ts
index 0fbd5f2..ad895b7 100644
--- a/src/models/generatedRound.ts
+++ b/src/models/generatedRound.ts
@@ -1,22 +1,22 @@
-import mongoose from 'mongoose';
+import mongoose from "mongoose";
const generatedRoundSchema = new mongoose.Schema({
- htmlContent: {
- type: String,
- required: true,
- },
- requestedBy: {
- type: String,
- required: true,
- },
- authorTag: {
- type: String,
- required: true,
- },
- timestamp: {
- type: String,
- required: true,
- },
+ htmlContent: {
+ type: String,
+ required: true,
+ },
+ requestedBy: {
+ type: String,
+ required: true,
+ },
+ authorTag: {
+ type: String,
+ required: true,
+ },
+ timestamp: {
+ type: String,
+ required: true,
+ },
});
-export default mongoose.model('GeneratedRound', generatedRoundSchema);
+export default mongoose.model("GeneratedRound", generatedRoundSchema);
diff --git a/src/models/userConfig.ts b/src/models/userConfig.ts
index 5beff3f..9443e02 100644
--- a/src/models/userConfig.ts
+++ b/src/models/userConfig.ts
@@ -1,17 +1,17 @@
-import mongoose from 'mongoose';
+import mongoose from "mongoose";
const userConfigSchema = new mongoose.Schema({
- _id: String,
- subjects: {
- type: [String],
- required: true,
- default: null,
- },
- gradeLevels: {
- type: [String],
- required: true,
- default: null,
- },
+ _id: String,
+ subjects: {
+ type: [String],
+ required: true,
+ default: null,
+ },
+ gradeLevels: {
+ type: [String],
+ required: true,
+ default: null,
+ },
});
-export default mongoose.model('UserConfig', userConfigSchema);
+export default mongoose.model("UserConfig", userConfigSchema);
diff --git a/src/models/userScore.ts b/src/models/userScore.ts
index 3ef9a9a..37f8c1a 100644
--- a/src/models/userScore.ts
+++ b/src/models/userScore.ts
@@ -1,14 +1,14 @@
-import mongoose from 'mongoose';
+import mongoose from "mongoose";
const userScoreSchema = new mongoose.Schema({
- authorID: {
- type: String,
- required: true,
- },
- score: {
- type: Number,
- required: true,
- },
+ authorID: {
+ type: String,
+ required: true,
+ },
+ score: {
+ type: Number,
+ required: true,
+ },
});
-export default mongoose.model('UserScore', userScoreSchema);
+export default mongoose.model("UserScore", userScoreSchema);