#!/usr/bin/env node import * as Discord from "discord.js"; import { execSync } from "child_process"; const client = new Discord.Client({ partials: ["MESSAGE", "CHANNEL", "REACTION"], }); import fetch from "node-fetch"; import * as fs from "fs"; import axios from "axios"; import userScore from "./mongooseModels/mongooseUserScoreModel.js"; import {} from "dotenv/config.js"; import mongoose from "mongoose"; const helpMessage = "`do be helping`: display this help message\n`do be roundgen`: send a pdf round to the channel\n`do be roundgen dm`: dm a pdf round to you\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!)"; client.once("ready", () => { mongoose .connect(process.env.MONGO_URI, { useUnifiedTopology: true, useNewUrlParser: true, }) .then(() => { console.log(client.user.username); client.user.setActivity( 'for "do be helping" | Add me to your own server: adat.link/awscibo', { type: "WATCHING" } ); }) .catch((err) => console.log(err)); }); client.on("guildCreate", (guild) => { guild.channels.cache .find( (channel) => channel.name === process.env.WELCOME_CHANNEL && channel.type === "text" ) .send("'Sup, I'm the AwesomeSciBo bot!") .catch(console.error); }); function getSubjectUrl(subject) { return `https://moose.lcsrc.org/subjects/${subject}.json`; } async function updateScore(isCorrect, score, authorId) { if (!isCorrect) { return `Nice try! Your score is still ${score}.`; } else { score += 4; if (score == 4) { const newUserScore = new userScore({ authorID: authorId, score: score, }); newUserScore.save((err) => err ? console.log("Error creating new user for scoring") : console.log("Sucessfully created user to score.") ); } else { const doc = await userScore.findOne({ authorID: authorId, }); doc.score = doc.score + 4; doc.save(); console.log("Succesfully updated 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); } } }); } 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); } }); if (message.content === "do be training") { axios.get("https://scibowldb.com/api/questions/random").then((res) => { const data = res.data; const messageAuthorFilter = (m) => m.author.id === message.author.id; message.reply(data.question.tossup_question).then(() => { message.channel .awaitMessages(messageAuthorFilter, { max: 1, time: 30000, errors: ["time"], }) .then((answerMsg) => { answerMsg = answerMsg.first(); let predicted = null; if (data.question.tossup_format === "Multiple Choice") { if ( answerMsg.content.charAt(0).toLowerCase() === data.question.tossup_answer.charAt(0).toLowerCase() ) { predicted = "correct"; } else { predicted = "incorrect"; } } else { if ( answerMsg.content.toLowerCase() === data.question.tossup_answer.toLowerCase() ) { predicted = "correct"; } else { predicted = "incorrect"; } } answerMsg.channel.send( `Correct answer: **${data.question.tossup_answer}**. Predicted: **${predicted}**. Please react to your answer!` ); answerMsg.react("✅"); answerMsg.react("❌"); const filter = (reaction, user) => { return ( ["❌", "✅"].includes(reaction.emoji.name) && user.id === answerMsg.author.id ); }; answerMsg .awaitReactions(filter, { max: 1, time: 600000, errors: ["time"], }) .then((userReaction) => { const reaction = userReaction.first(); if (reaction.emoji.name === "❌") { updateScore(false, score, authorId).then((msgToReply) => answerMsg.reply(msgToReply) ); } else { updateScore(true, score, authorId).then((msgToReply) => answerMsg.reply(msgToReply) ); } }); }); }); }); } else { const subject = message.content.substring(15); let subjectURL; switch (subject) { case "astro": case "astronomy": subjectURL = getSubjectUrl("astronomy"); break; case "bio": case "biology": subjectURL = getSubjectUrl("biology"); break; case "ess": case "earth science": case "es": subjectURL = getSubjectUrl("ess"); break; case "chem": case "chemistry": subjectURL = getSubjectUrl("astronomy"); break; case "phys": case "physics": subjectURL = getSubjectUrl("physics"); break; case "math": subjectURL = getSubjectUrl("math"); break; case "energy": subjectURL = getSubjectUrl("energy"); break; default: message.channel.send("Not a valid subject!"); return; } axios .get(subjectURL) .then((res) => { const data = res.data; const questionNum = Math.floor(Math.random() * data.length); const messageFilter = (m) => m.author.id === authorId; message.reply(data[questionNum].tossup_question).then(() => { message.channel .awaitMessages(messageFilter, { max: 1, time: 30000, errors: ["time"], }) .then((answerMsg) => { answerMsg = answerMsg.first(); let predicted = null; if (data[questionNum].tossup_format === "Multiple Choice") { if ( answerMsg.content.charAt(0).toLowerCase() === data[questionNum].tossup_answer.charAt(0).toLowerCase() ) { predicted = "correct"; } else { predicted = "incorrect"; } } else { if ( answerMsg.content.toLowerCase() === data[questionNum].tossup_answer.toLowerCase() ) { predicted = "correct"; } else { predicted = "incorrect"; } } answerMsg.channel.send( `Correct answer: **${data[questionNum].tossup_answer}**. Predicted: **${predicted}**. Please react to your answer!` ); answerMsg.react("✅"); answerMsg.react("❌"); const reactionFilter = (reaction, user) => { return ( ["❌", "✅"].includes(reaction.emoji.name) && user.id === answerMsg.author.id ); }; answerMsg .awaitReactions(reactionFilter, { max: 1, time: 600000, errors: ["time"], }) .then(async (userReaction) => { const reaction = userReaction.first(); if (reaction.emoji.name == "❌") { updateScore(false, score, authorId).then((msgToReply) => answerMsg.reply(msgToReply) ); } else { updateScore(true, score, authorId).then((msgToReply) => answerMsg.reply(msgToReply) ); } }) .catch((collected) => {}); // Reaction message filter }) .catch((collected, error) => { message.reply("\n**ANSWER TIMEOUT**"); }); }); }) .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." ); } } function sendHelpMessage(message) { message.channel.send( new Discord.MessageEmbed().setTitle("Help").setDescription(helpMessage) ); } async function generateRound(message, isDM) { fs.writeFile("index.html", "