From 821d2aec5418a96b3e5402710241ab75958a2017 Mon Sep 17 00:00:00 2001 From: Abheek Dhawan <67982792+ADawesomeguy@users.noreply.github.com> Date: Sat, 26 Jun 2021 18:42:09 -0500 Subject: [PATCH] Feature slash commands (#10) * Switch training and helping to slash commands * Remove intents * Change formatting slightly * Stop bot from registering slash commands multiple times * Fix intents * Have slash commands register as they weren't in every server * Add privileged intents * Remove privileged intents (not needed) and use interaction.user.id as member is undefined in DMs * Use set instead of create for slash commands * Capitalize first letter of command descriptions * Convert round command to slash commands * Fix setting commands to use the entire array instead of looping through it * Remove default response if message starts with "do be" * Use full form body instead of storing it in variable * Replace separate round commands with single round command using subcommands * Fix round commands * Add description for rounds command * Use rounds function instead of generateRound function * Use interaction.user instead of undefined interaction.author * Remove mention from generated message * Replace message.author with interaction.user * Move embed to options * Make generated round message ephemeral * Get rid of generating message * Make generated round message ephemeral * Add hits to rounds command * Register rounds hit as a command * Add top command to slash commands * Use interaction.user instead of nonexistent interaction.author * Fix callback catch blocks to perform actions other than logging to the console * Attempt to fix catch blocks always replying with errors * Attempt to fix catch blocks always replying with errors * Capitalize first letter of subject option description * Add slash command for changelog * Add about commands as slash commands * Add ISS to slash commands * Remove ISS from regular commands * Add about bot command * Change question timeout to 2 minutes * Make sure to reply with the about bot embed * Add source to question * Update contributors * Prevent AwesomeSciBo from losing its mind if there's no #general * Update join message and set slash commands on guild join * Remove misplaced semicolon * Remove server-specific commands * Remove message event but not functions * Update .gitignore * Change help message --- .gitignore | 1 + bot/awesomescibo.js | 671 ++++++++++++++++++++++-------------------- bot/package-lock.json | 77 ++--- bot/package.json | 2 +- 4 files changed, 384 insertions(+), 367 deletions(-) diff --git a/.gitignore b/.gitignore index fb11a82..afcae91 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ bot/README.md .env userScore config.json +.DS_Store diff --git a/bot/awesomescibo.js b/bot/awesomescibo.js index f596ec6..5ab3218 100755 --- a/bot/awesomescibo.js +++ b/bot/awesomescibo.js @@ -1,7 +1,9 @@ #!/usr/bin/env node const Discord = require("discord.js"); +const Intents = Discord.Intents; const client = new Discord.Client({ + intents: ["GUILDS", "GUILD_MESSAGES", "GUILD_MESSAGE_REACTIONS", "DIRECT_MESSAGES", "DIRECT_MESSAGE_REACTIONS"/*, "GUILD_MEMBERS", "GUILD_PRESENCES"*/], partials: ["MESSAGE", "CHANNEL", "REACTION"], intents: ["GUILDS", "GUILD_MESSAGES"] }); @@ -12,10 +14,87 @@ const generatedRound = require("./mongooseModels/mongooseGeneratedRoundModel.js" const mongoose = require("mongoose"); const gitlog = require("gitlog").default; -const helpMessage = - "`do be helping`: display this help message\n`do be roundgen`: send a pdf round to the channel\n`do be scoring`: start a scoring session\n > `do be scoring (a/b)(4/10)`: add points to Team A or Team B\n > `do be scoring stop`: end scoring session and post final points\n > `do be servers`: send the number of servers this bot is a part of\n > `do be iss`: show the current location of the International Space Station\n`do be training`: send a quick practice problem (you **must** react to your answer, or the bot will yell at you)\n > subject options: astro, phys, chem, math, bio, ess, energy\n`do be top`: list cross-server top 10 players\n `do be about`: List people who contributed to this bot\n Source Code: https://github.com/ADawesomeguy/AwesomeSciBo (don't forget to star!)"; +const helpMessage = "AwesomeSciBo has migrated to using slash commands! You can take a look at the different commands by typing `/` and clicking on the AwesomeSciBo icon." + +const slashCommands = [ + { + "name": "train", + "description": "Sends a single training question to be answered", + "options": [ + { + "type": 3, + "name": "subject", + "description": "Optional subject to be used as a filter", + "default": false, + "required": false + } + ] + }, + { + "name": "help", + "description": "Replies with a help message explaining what the bot can do" + }, + { + "name": "rounds", + "options": [ + { + "type": 1, + "name": "generate", + "description": "Generates a round with randomized questions from https://scibowldb.com/", + "options": [] + }, + { + "type": 1, + "name": "list", + "description": "Lists your 5 most recently generated rounds with links", + "options": [] + }, + { + "type": 1, + "name": "hit", + "description": "Shows the total number of rounds hit as well as the number for the specific user", + "options": [] + } + ], + "description": "Commands regarding rounds generated by AwesomeSciBo" + }, + { + "name": "top", + "description": "Lists top ten scores across servers (server specific leaderboard WIP)" + }, + { + "name": "about", + "options": [ + { + "type": 1, + "name": "contributors", + "description": "Lists contributors to the AwesomeSciBo bot", + "options": [] + }, + { + "type": 1, + "name": "changelog", + "description": "Lists the 5 most recent changes in a \"git log\" type format", + "options": [] + }, + { + "type": 1, + "name": "bot", + "description": "Lists information about AwesomeSciBo", + "options": [] + } + ], + "description": "Commands regarding the creation/development of the bot" + }, + { + "name": "iss", + "description": "Shows the location of the ISS on a map as well as all of the current astronauts within it" + } +] client.once("ready", () => { + client.application.commands.set(slashCommands); + // Connect to MongoDB using mongoose if (!process.env.CI) { mongoose @@ -27,7 +106,7 @@ client.once("ready", () => { // Log client tag and set status console.log(`Logged in as: ${client.user.username}!`); client.user.setActivity( - 'for "do be helping" | Add me to your own server: adat.link/awscibo', + 'for "/helping" | Add me to your own server: adat.link/awscibo', { type: "WATCHING" } ); }) @@ -36,19 +115,22 @@ client.once("ready", () => { }); client.on("guildCreate", (guild) => { - guild.channels.cache + //guild.commands.set(slashCommands); + const welcomeChannel = guild.channels.cache .find( (channel) => // Find channel by name - channel.name === process.env.WELCOME_CHANNEL && channel.type === "text" + channel.name === "general" && channel.type === "text" ) - .send("'Sup, I'm the AwesomeSciBo bot!") - .catch(console.error); + if (welcomeChannel) { + welcomeChannel.send("'Sup, I'm the AwesomeSciBo bot! Use `/help` to learn more about me!") + .catch(console.error); + } }); async function updateScore(isCorrect, score, authorId) { if (!isCorrect) { - return `nice try! Your score is still ${score}.`; + return `Nice try! Your score is still ${score}.`; } else { score += 4; if (score == 4) { @@ -69,219 +151,141 @@ async function updateScore(isCorrect, score, authorId) { doc.save(); } - return `great job! Your score is now ${score}.`; + return `Great job! Your score is now ${score}.`; } } -async function otherCommands(message) { - if ( - message.content.toLowerCase().startsWith("do be announcing") && - (message.author.id === process.env.ABHEEK_USER_ID || - message.author.id === process.env.TEJAS_USER_ID) - ) { - const announcement = message.content.substring(17); - client.guilds.cache.forEach((guild) => { - const channel = guild.channels.cache.find( - (channelGeneral) => - channelGeneral.name === process.env.ANNOUNCING_CHANNEL - ); - if (channel) { - if (channel.type === "text") { - channel.send(announcement).catch(console.error); - } +function training(subject, interaction) { + const authorId = interaction.user.id; + let score; + userScore + .findOne({ authorID: authorId }) + .lean() + .then((obj, err) => { + if (!obj) { + score = 0; + } else if (obj) { + score = obj.score; + } else { + console.log(err); } }); - } else if (message.content.toLowerCase().startsWith("do be training")) { - const authorId = message.author.id; - let score; - userScore - .findOne({ authorID: authorId }) - .lean() - .then((obj, err) => { - if (!obj) { - score = 0; - } else if (obj) { - score = obj.score; - } else { - console.log(err); - } - }); - const subject = message.content.substring(15); - let categoryArray = []; - - switch (subject) { - case "": - categoryArray = ["BIOLOGY", "PHYSICS", "CHEMISTRY", "EARTH AND SPACE", "ASTRONOMY", "MATH"]; - 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: - message.channel.send("Not a valid subject!"); - return; - } - axios - .post("https://scibowldb.com/api/questions/random", { categories: categoryArray }) - .then((res) => { - data = res.data.question; - const messageFilter = (m) => m.author.id === authorId; - message.reply(data.tossup_question).then(() => { - message.channel - .awaitMessages(messageFilter, { - max: 1, - time: 30000, - errors: ["time"], - }) - .then((answerMsg) => { - answerMsg = answerMsg.first(); - - let predicted = null; - if (data.tossup_format === "Multiple Choice") { - if ( - answerMsg.content.charAt(0).toLowerCase() === - data.tossup_answer.charAt(0).toLowerCase() - ) { - predicted = "correct"; - } else { - predicted = "incorrect"; - } + let categoryArray = []; + + switch (subject) { + case null: + categoryArray = ["BIOLOGY", "PHYSICS", "CHEMISTRY", "EARTH AND SPACE", "ASTRONOMY", "MATH"]; + 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.reply("Not a valid subject!"); + return; + } + + axios + .post("https://scibowldb.com/api/questions/random", { categories: categoryArray }) + .then((res) => { + data = res.data.question; + const messageFilter = (m) => m.author.id === authorId; + interaction.reply(data.tossup_question + `\n\n||Source: ${data.uri}||`).then(() => { + interaction.channel.awaitMessages(messageFilter, { + max: 1, + time: 120000, + errors: ["time"], + }) + .then((answerMsg) => { + answerMsg = answerMsg.first(); + + let predicted = null; + if (data.tossup_format === "Multiple Choice") { + if ( + answerMsg.content.charAt(0).toLowerCase() === + data.tossup_answer.charAt(0).toLowerCase() + ) { + predicted = "correct"; } else { - if ( - answerMsg.content.toLowerCase() === - data.tossup_answer.toLowerCase() - ) { - predicted = "correct"; - } else { - predicted = "incorrect"; - } + predicted = "incorrect"; } - - if (predicted === "correct") { - updateScore(true, score, authorId).then((msgToReply) => - answerMsg.reply(msgToReply) - ); + } else { + if ( + answerMsg.content.toLowerCase() === + data.tossup_answer.toLowerCase() + ) { + predicted = "correct"; } else { - const overrideEmbed = new Discord.MessageEmbed() - .setAuthor(answerMsg.author.tag, answerMsg.author.displayAvatarURL()) - .addField("Correct answer", `\`${data.tossup_answer}\``) - .setDescription(`It seems your answer was incorrect. Please react with <:override:842778128966615060> to override your answer if you think you got it right.`) - .setTimestamp(); - const overrideMsg = answerMsg.channel.send( - overrideEmbed - ) - .then(overrideMsg => { - overrideMsg.react("<:override:842778128966615060>"); - const filter = (reaction, user) => { - return ( - ["override"].includes(reaction.emoji.name) && - user.id === answerMsg.author.id - ); - }; - overrideMsg - .awaitReactions(filter, { - max: 1, - time: 600000, - errors: ["time"], - }) - .then((userReaction) => { - updateScore(true, score, authorId).then((msgToReply) => - answerMsg.reply(msgToReply) - ); - }); - }) + predicted = "incorrect"; } - }) - .catch(console.error); - }); - }) - .catch(console.error); - } else { - // Not any of the commands supported - message.channel.send( - "That didn't quite make sense! Please use `do be helping` to see the available commands." - ); - } -} + } + + if (predicted === "correct") { + updateScore(true, score, authorId).then((msgToReply) => + answerMsg.reply(msgToReply) + ); + } else { + const overrideEmbed = new Discord.MessageEmbed() + .setAuthor(answerMsg.author.tag, answerMsg.author.displayAvatarURL()) + .addField("Correct answer", `\`${data.tossup_answer}\``) + .setDescription(`It seems your answer was incorrect. Please react with <:override:842778128966615060> to override your answer if you think you got it right.`) + .setTimestamp(); + const overrideMsg = answerMsg.channel.send( + overrideEmbed + ) + .then(overrideMsg => { + overrideMsg.react("<:override:842778128966615060>"); + const filter = (reaction, user) => { + return ( + ["override"].includes(reaction.emoji.name) && + user.id === answerMsg.author.id + ); + }; + overrideMsg + .awaitReactions(filter, { + max: 1, + }) + .then((userReaction) => { + updateScore(true, score, authorId).then((msgToReply) => + answerMsg.reply(msgToReply) + ); + }).catch(console.error); + }).catch(console.error); + } + }).catch(error => { if (error) interaction.editReply("Sorry, the question timed out waiting for an answer.") }); + }).catch(console.error); + }).catch(error => { if (error) interaction.reply("Sorry, there was a problem fetching the question. Please try again!") }); + } -function sendHelpMessage(message) { - message.channel.send( - new Discord.MessageEmbed().setTitle("Help").setDescription(helpMessage) - ); +function sendHelpMessage(interaction) { + const helpEmbed = new Discord.MessageEmbed().setDescription(helpMessage).setColor("ffffff"); + interaction.reply(helpEmbed); } -async function generateRound(message) { - const generatingMessage = message.channel.send("Generating..."); - let i; - let finalizedHTML = '

ROUND GENERATED BY AWESOMESCIBO USING THE SCIBOWLDB API

'; - let tossup_question; - let question_category; - let tossup_format; - let tossup_answer; - let bonus_question; - let bonus_format; - let bonus_answer; - let htmlContent = ""; - await axios.post("https://scibowldb.com/api/questions", { categories: ["BIOLOGY", "PHYSICS", "CHEMISTRY", "EARTH AND SPACE", "ASTRONOMY", "MATH"] }) - .then((response) => { - for (i = 1; i < 26; i++) { - data = response.data.questions[Math.floor(Math.random() * response.data.questions.length)]; - tossup_question = data.tossup_question; - tossup_answer = data.tossup_answer; - question_category = data.category; - tossup_format = data.tossup_format; - bonus_question = data.bonus_question; - bonus_answer = data.bonus_answer; - bonus_format = data.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; - } - newGeneratedRound = new generatedRound({ - htmlContent: finalizedHTML, - requestedBy: message.author.id, - authorTag: message.author.tag, - timestamp: new Date().toISOString(), - }); - newGeneratedRound.save((err, round) => { - if (err) { - console.log(err); - return; - } - message.channel.messages.fetch(generatingMessage.id) - .then(generatingMessage => { - const msg = generatingMessage.first(); - msg.edit(`${message.author}, here's your round: https://api.adawesome.tech/round/${round._id.toString()}`); - }); - }); - }); - } - async function startScoring(message) { let scoreA = 0; let scoreB = 0; @@ -293,35 +297,35 @@ async function startScoring(message) { time: 1500000, }); collector.on("collect", (m) => { - if (m.content.toLowerCase() === "do be scoring a 4") { + if (m.content.toLowerCase() === "/scoring a 4") { // A team gets toss-up m.delete({ timeout: 1000 }).catch(console.error); scoreA += 4; scoreboard.channel.send( `Here's the score:\nTeam A: ${scoreA}\nTeam B: ${scoreB}` ); - } else if (m.content.toLowerCase() === "do be scoring a 10") { + } else if (m.content.toLowerCase() === "/scoring a 10") { // A team gets bonus m.delete({ timeout: 1000 }).catch(console.error); scoreA += 10; scoreboard.channel.send( `Here's the score:\nTeam A: ${scoreA}\nTeam B: ${scoreB}` ); - } else if (m.content.toLowerCase() === "do be scoring b 4") { + } else if (m.content.toLowerCase() === "/scoring b 4") { // B team gets toss up m.delete({ timeout: 1000 }).catch(console.error); scoreB += 4; scoreboard.channel.send( `Here's the score:\nTeam A: ${scoreA}\nTeam B: ${scoreB}` ); - } else if (m.content.toLowerCase() === "do be scoring b 10") { + } else if (m.content.toLowerCase() === "/scoring b 10") { // B team gets bonus m.delete({ timeout: 1000 }).catch(console.error); scoreB += 10; scoreboard.channel.send( `Here's the score:\nTeam A: ${scoreA}\nTeam B: ${scoreB}` ); - } else if (m.content === "do be scoring stop") { + } else if (m.content === "/scoring stop") { m.delete({ timeout: 1000 }).catch(console.error); scoreboard.delete({ timeout: 1000 }); m.channel.send( @@ -346,11 +350,11 @@ function showServerNumber(message) { message.channel.send(client.guilds.cache.size); } -async function showIssLocation(message) { +async function showIssLocation(interaction) { await fetch("http://api.open-notify.org/iss-now.json") .then((request) => request.json()) .then((data) => { - message.channel.send( + interaction.reply( new Discord.MessageEmbed() .setTitle("The current location of the ISS!") .setImage( @@ -358,10 +362,10 @@ async function showIssLocation(message) { ) .setURL("https://spotthestation.nasa.gov/tracking_map.cfm") ); - }); + }).catch(error => { if (error) interaction.editReply("Unable to fetch data. Please try again!") }); } -function showLeaderboard(message) { +function showLeaderboard(interaction) { let messageContent = ""; userScore .find({}) @@ -369,20 +373,20 @@ function showLeaderboard(message) { .exec((err, obj) => { if (err) { console.log(err); - return message.reply( + return interaction.reply( "Uh oh! :( There was an internal error. Please try again." ); } if (obj.length < 10) { // Need at least 10 scores for top 10 - return message.reply( + return interaction.reply( `There are only ${obj.length} users, we need at least 10!` ); } for (let i = 0; i < 10; i++) { messageContent += `${i + 1}: <@${obj[i].authorID}>: ${obj[i].score}\n`; // Loop through each user and add their name and score to leaderboard content } - message.channel.send( + interaction.reply( new Discord.MessageEmbed() .setTitle("Top Ten!") .setDescription(messageContent) @@ -390,121 +394,148 @@ function showLeaderboard(message) { }); } -function aboutMessage(message) { - message.channel.send( - new Discord.MessageEmbed().setTitle("Contributors: ").setDescription(` - <@745063586422063214> [ADawesomeguy#2235] - <@650525101048987649> [tEjAs#8127] - `) // Add more contributors here, first one is Abheek, second one is Tejas - ); -} - -async function userRounds(message) { - let rounds = await generatedRound.find({ requestedBy: message.author.id }).sort({ timestamp: -1 }); - let finalMessage = ""; - if (!rounds) { - message.reply("you haven't requested any rounds!"); - return; - } - - if (rounds.length > 5) { - rounds = rounds.slice(0, 5); - } - - rounds.forEach(async (item, index) => { - finalMessage += `${index + 1}. [${item.timestamp.split("T")[0]}](https://api.adawesome.tech/round/${item._id.toString()})\n`; - }); +async function about(action, interaction) { + if (action === "contributors") { + interaction.reply( + new Discord.MessageEmbed().setTitle("Contributors") + .addField("Creator", `<@745063586422063214> [ADawesomeguy#2235]`, true) + .addField("Contributors", `<@650525101048987649> [tEjAs#8127]\n<@426864344463048705> [tetrident#9396]`, true) // Add more contributors here, first one is Abheek, second one is Tejas + .setTimestamp() + ); + } else if (action === "changelog") { + let parentFolder = __dirname.split("/"); + parentFolder.pop(); + parentFolder = parentFolder.join("/"); + + const commits = gitlog({ + repo: parentFolder, + number: 5, + fields: ["hash", "abbrevHash", "subject", "authorName", "authorDateRel"], + }); - const roundsEmbed = new Discord.MessageEmbed() - .setAuthor(message.author.tag, message.author.displayAvatarURL()) - .setTitle(`Last 5 rounds requested by ${message.author.tag}`) - .setDescription(finalMessage) + const changelogEmbed = new Discord.MessageEmbed() + .setAuthor(interaction.user.tag, interaction.user.displayAvatarURL()) + .setTitle("Changelog") .setTimestamp(); - message.channel.send(roundsEmbed); -} + 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`); + }); -async function hits(message) { - let totalCount = await generatedRound.countDocuments({}); - let userCount = await generatedRound.countDocuments({ requestedBy: message.author.id }); + interaction.reply(changelogEmbed); + } else if (action === "bot") { + const aboutBotEmbed = new Discord.MessageEmbed() + .setAuthor(interaction.user.tag, interaction.user.displayAvatarURL()) + .setTitle("About AwesomeSciBo") + .addField("Servers", client.guilds.cache.size, true) + .addField("Training Users", await userScore.countDocuments({}), true) + .setTimestamp(); - message.channel.send(`Total Hits: ${totalCount}\nYour Hits: ${userCount}`); + interaction.reply(aboutBotEmbed); + } } -async function changelog(message) { - let parentFolder = __dirname.split("/"); - parentFolder.pop(); - parentFolder = parentFolder.join("/"); +async function rounds(action, interaction) { + if (action === "generate") { + let i; + let finalizedHTML = '

ROUND GENERATED BY AWESOMESCIBO USING THE SCIBOWLDB API

'; + let tossup_question; + let question_category; + let tossup_format; + let tossup_answer; + let bonus_question; + let bonus_format; + let bonus_answer; + let htmlContent = ""; + await axios.post("https://scibowldb.com/api/questions", { categories: ["BIOLOGY", "PHYSICS", "CHEMISTRY", "EARTH AND SPACE", "ASTRONOMY", "MATH"] }) + .then((response) => { + for (i = 1; i < 26; i++) { + data = response.data.questions[Math.floor(Math.random() * response.data.questions.length)]; + tossup_question = data.tossup_question; + tossup_answer = data.tossup_answer; + question_category = data.category; + tossup_format = data.tossup_format; + bonus_question = data.bonus_question; + bonus_answer = data.bonus_answer; + bonus_format = data.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; + } + newGeneratedRound = new generatedRound({ + htmlContent: finalizedHTML, + requestedBy: interaction.user.id, + authorTag: interaction.user.tag, + timestamp: new Date().toISOString(), + }); + newGeneratedRound.save((err, round) => { + if (err) { + console.log(err); + return; + } + interaction.reply(`Here's your round: https://api.adawesome.tech/round/${round._id.toString()}`, { ephemeral: true }); + }); + }); + } else if (action === "list"){ + let rounds = await generatedRound.find({ requestedBy: interaction.user.id }).sort({ timestamp: -1 }); + let finalMessage = ""; + if (!rounds) { + interaction.reply("You haven't requested any rounds!"); + return; + } - const commits = gitlog({ - repo: parentFolder, - number: 5, - fields: ["hash", "abbrevHash", "subject", "authorName", "authorDateRel"], - }); + if (rounds.length > 5) { + rounds = rounds.slice(0, 5); + } - const changelogEmbed = new Discord.MessageEmbed() - .setAuthor(message.author.tag, message.author.displayAvatarURL()) - .setTitle("Changelog") - .setTimestamp(); + rounds.forEach(async (item, index) => { + finalMessage += `${index + 1}. [${item.timestamp.split("T")[0]}](https://api.adawesome.tech/round/${item._id.toString()})\n`; + }); - 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`); - }); + const roundsEmbed = new Discord.MessageEmbed() + .setAuthor(interaction.user.tag, interaction.user.displayAvatarURL()) + .setTitle(`Last 5 rounds requested by ${interaction.user.tag}`) + .setDescription(finalMessage) + .setTimestamp(); - message.channel.send(changelogEmbed); -} + interaction.reply({ + embeds: [roundsEmbed], + ephemeral: true + }); + } else if (action === "hit"){ + let totalCount = await generatedRound.countDocuments({}); + let userCount = await generatedRound.countDocuments({ requestedBy: interaction.user.id }); -client.on("message", async (message) => { - if (message.author.bot) { - return; + interaction.reply(`Total Hits: ${totalCount}\nYour Hits: ${userCount}`); } +} - // Temporary logging purposes - - const formattedMessage = message.content.toLowerCase().replace(/ /g, ""); - if (formattedMessage.startsWith("dobe")) { - console.log(`${message.author.tag} > ${message.content}`); - // Bot prefix is "do be" - switch (formattedMessage) { - case "dobehelping": // Display help message - sendHelpMessage(message); - break; - case "doberoundgen": // Generate round publicly - generateRound(message); - break; - case "dobescoring": // Start scoring - startScoring(message); - break; - case "dobetop": // Top 10 scores - showLeaderboard(message); - break; - case "dobehappy": // Send happy message - dontWorryBeHappy(message); - break; - case "dobeservers": // Shows number of servers bot is in - showServerNumber(message); - break; - case "dobeiss": // Show location of ISS - showIssLocation(message); - break; - case "dobeabout": // Show about message of bot - aboutMessage(message); - break; - case "dobemyrounds": - userRounds(message); - break; - case "dobehits": - hits(message); - break; - case "dobechangelog": - changelog(message); - break; - default: - // Do be training - otherCommands(message); - } +client.on("interaction", interaction => { + // If the interaction isn't a slash command, return + if (!interaction.isCommand()) return; + + switch(interaction.commandName) { + case "help": + sendHelpMessage(interaction); + break; + case "train": + training(interaction.options[0] ? interaction.options[0].value : null, interaction); + break; + case "rounds": + rounds(interaction.options[0].name, interaction); + break; + case "top": + showLeaderboard(interaction); + break; + case "about": + about(interaction.options[0].name, interaction); + break; + case "iss": + showIssLocation(interaction); + break; } -}); +}) client .login(process.env.TOKEN) diff --git a/bot/package-lock.json b/bot/package-lock.json index b056fdb..d8e2cc6 100644 --- a/bot/package-lock.json +++ b/bot/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache 2.0", "dependencies": { "axios": "^0.21.1", - "discord.js": "^12.5.1", + "discord.js": "github:discordjs/discord.js", "dotenv": "^8.2.0", "eslint": "^7.21.0", "fs": "^0.0.1-security", @@ -393,21 +393,18 @@ } }, "node_modules/discord.js": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.1.tgz", - "integrity": "sha512-VwZkVaUAIOB9mKdca0I5MefPMTQJTNg0qdgi1huF3iwsFwJ0L5s/Y69AQe+iPmjuV6j9rtKoG0Ta0n9vgEIL6w==", + "resolved": "git+ssh://git@github.com/discordjs/discord.js.git#c7334363b36c5f7f1c7880fe77a2e9b2eb1a6442", "dependencies": { "@discordjs/collection": "^0.1.6", "@discordjs/form-data": "^3.0.1", "abort-controller": "^3.0.0", "node-fetch": "^2.6.1", "prism-media": "^1.2.2", - "setimmediate": "^1.0.5", "tweetnacl": "^1.0.3", "ws": "^7.3.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/doctrine": { @@ -907,19 +904,19 @@ "optional": true }, "node_modules/mime-db": { - "version": "1.46.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", - "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==", + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.29", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", - "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", "dependencies": { - "mime-db": "1.46.0" + "mime-db": "1.47.0" }, "engines": { "node": ">= 0.6" @@ -1108,9 +1105,9 @@ } }, "node_modules/prism-media": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.7.tgz", - "integrity": "sha512-thS1z3L6BDmf724sqLC73bHGjSYArFTYHa7cqInyS3EdDNTHKgDCXy7l+IhRvlnX7aFNiUb8jJcC+R8ezxwgMA==" + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.9.tgz", + "integrity": "sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q==" }, "node_modules/process-nextick-args": { "version": "2.0.1", @@ -1223,11 +1220,6 @@ "node": ">=10" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1450,9 +1442,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/ws": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", - "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", "engines": { "node": ">=8.3.0" } @@ -1771,16 +1763,14 @@ "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==" }, "discord.js": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.1.tgz", - "integrity": "sha512-VwZkVaUAIOB9mKdca0I5MefPMTQJTNg0qdgi1huF3iwsFwJ0L5s/Y69AQe+iPmjuV6j9rtKoG0Ta0n9vgEIL6w==", + "version": "git+ssh://git@github.com/discordjs/discord.js.git#c7334363b36c5f7f1c7880fe77a2e9b2eb1a6442", + "from": "discord.js@github:discordjs/discord.js", "requires": { "@discordjs/collection": "^0.1.6", "@discordjs/form-data": "^3.0.1", "abort-controller": "^3.0.0", "node-fetch": "^2.6.1", "prism-media": "^1.2.2", - "setimmediate": "^1.0.5", "tweetnacl": "^1.0.3", "ws": "^7.3.1" } @@ -2175,16 +2165,16 @@ "optional": true }, "mime-db": { - "version": "1.46.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", - "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==" + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" }, "mime-types": { - "version": "2.1.29", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", - "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", "requires": { - "mime-db": "1.46.0" + "mime-db": "1.47.0" } }, "minimatch": { @@ -2334,9 +2324,9 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, "prism-media": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.7.tgz", - "integrity": "sha512-thS1z3L6BDmf724sqLC73bHGjSYArFTYHa7cqInyS3EdDNTHKgDCXy7l+IhRvlnX7aFNiUb8jJcC+R8ezxwgMA==" + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.9.tgz", + "integrity": "sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q==" }, "process-nextick-args": { "version": "2.0.1", @@ -2424,11 +2414,6 @@ "lru-cache": "^6.0.0" } }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -2616,9 +2601,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "ws": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", - "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==" + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" }, "yallist": { "version": "4.0.0", diff --git a/bot/package.json b/bot/package.json index f7bb0c7..533f7e2 100644 --- a/bot/package.json +++ b/bot/package.json @@ -1,7 +1,7 @@ { "dependencies": { "axios": "^0.21.1", - "discord.js": "^12.5.1", + "discord.js": "github:discordjs/discord.js", "dotenv": "^8.2.0", "eslint": "^7.21.0", "fs": "^0.0.1-security",