#!/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 * as path from "path"; 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\nSource 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 === "general" && channel.type === "text") .send("'Sup, I'm the AwesomeSciBo bot!") .catch(console.error); }); client.on("message", async (message) => { if (message.author.bot) { return; } const formattedMessage = message.content.toLowerCase().replace(/\s+/g, ""); if (formattedMessage.startsWith("dobe")) { switch (formattedMessage) { case "dobehelping": sendHelpMessage(); break; case "doberoundgen": generateRound(false); break; case "doberoundgendm": generateRound(true); break; case "dobescoring": startScoring(); break; case "dobetop": showLeaderboard(); break; case "dobehappy": dontWorryBeHappy(); break; case "dobeservers": showServerNumber(); break; case "dobeiss": showIssLocation(); break; default: otherCommands(); } } async function otherCommands() { if ( message.content.toLowerCase().startsWith("do be announcing") && message.author.id === process.argv[3] ) { const announcement = message.content.substring(17); client.guilds.cache.forEach((guild) => { const channel = guild.channels.cache.find( (channelGeneral) => channelGeneral.name === "general" ); if (channel) { if (channel.type === "text") { channel.send(announcement).catch(console.error); } } }); } else if (message.content.toLowerCase().startsWith("do be training")) { // BEGIN CHANGES if (message.content === "do be training") { axios.get("https://scibowldb.com/api/questions/random").then(data => { const messageAuthorFilter = (m) => m.author.id === message.author.id; message .reply(data.data.question.tossup_question) .then(() => { message.channel.awaitMessages(messageAuthorFilter, { max: 1, time: 30000, errors: ["time"], }); }) .then(resMessage => { const responseAuthorID = resMessage.first().author.id; }); }); } else { const subject = message.content.substring(15); let subjectURL; switch (subject) { case "astro": case "astronomy": subjectURL = `https://moose.lcsrc.org/subjects/astronomy.json`; break; case "bio": case "biology": subjectURL = `https://moose.lcsrc.org/subjects/biology.json`; break; case "ess": case "earth science": case "es": subjectURL = `https://moose.lcsrc.org/subjects/ess.json`; break; case "chem": case "chemistry": subjectURL = `https://moose.lcsrc.org/subjects/chemistry.json`; break; case "phys": case "physics": subjectURL = `https://moose.lcsrc.org/subjects/physics.json`; break; case "math": subjectURL = `https://moose.lcsrc.org/subjects/math.json`; break; case "energy": subjectURL = `https://moose.lcsrc.org/subjects/energy.json`; break; default: message.channel.send("Not a valid subject!"); return; } const authorId = message.author.id; fetch(subjectURL) .then((response) => response.json()) .then((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(); const userDocScore = userScore.findOne({authorID: authorId}).select("score"); let score = userDocScore || 0; 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 === "❌") { answerMsg.reply(`nice try! Your score is now ${score.toString()}`); } 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(); } answerMsg.reply(`nice job! Your score is now ${score.toString()}`); } }) .catch((collected) => {}); }) .catch((collected, error) => { message.reply("\n**ANSWER TIMEOUT**"); }); }); }) .catch(console.error); } } else { if (formattedMessage.startsWith("dobescoring" || "dobetraining")) { return; } message.channel.send( "That didn't quite make sense! Please use `do be helping` to see the available commands." ); } } async function sendHelpMessage() { message.channel.send( new Discord.MessageEmbed().setTitle("Help").setDescription(helpMessage) ); } async function generateRound(isDM) { fs.writeFile("index.html", "