From 2ef3633c6b341bcbc7070129c839ab3b9d5c78c9 Mon Sep 17 00:00:00 2001 From: Joehoel <31251240+Joehoel@users.noreply.github.com> Date: Thu, 12 Aug 2021 22:48:59 +0200 Subject: [PATCH 1/2] feat: :sparkles: Add support for slash commands Add support for slash commands: clear, dab, gif, meme, answer, avatar, ping, poll. --- .env.example | 13 ++ package.json | 11 +- src/_commands/admin/clear.ts | 39 +++++ src/_commands/answer.ts | 41 +++++ src/_commands/avatar.ts | 12 ++ src/_commands/fun/dab.ts | 11 ++ src/_commands/fun/gif.ts | 13 ++ src/_commands/fun/meme.ts | 26 +++ src/_commands/ping.ts | 28 +++ src/_commands/poll.ts | 109 ++++++++++++ src/commands/admin/level.ts | 16 +- src/commands/admin/reactionrole.ts | 16 +- src/commands/admin/say.ts | 4 +- src/commands/admin/status.ts | 7 +- src/commands/help.ts | 59 +++---- src/commands/leaderboard.ts | 180 +++++++++++--------- src/commands/meme.ts | 4 +- src/commands/music/autoplay.ts | 6 +- src/commands/music/loop.ts | 2 +- src/commands/music/lyrics.ts | 18 +- src/commands/music/now.ts | 42 ++--- src/commands/music/pause.ts | 2 +- src/commands/music/queue.ts | 14 +- src/commands/music/shuffle.ts | 12 +- src/commands/music/skip.ts | 27 +-- src/commands/music/stop.ts | 2 +- src/commands/ping.ts | 14 +- src/commands/poll.ts | 36 ++-- src/commands/rank.ts | 23 ++- src/commands/remindme.ts | 40 ++--- src/commands/roll.ts | 6 +- src/commands/snipe.ts | 18 +- src/commands/swears.ts | 16 +- src/commands/todo.ts | 16 +- src/commands/typo.ts | 2 +- src/events/interactionCreate.ts | 10 ++ src/events/{message.ts => messageCreate.ts} | 26 +-- src/events/ready.ts | 2 +- src/features/command.ts | 12 +- src/features/dad.ts | 4 +- src/features/filter.ts | 2 +- src/features/index.ts | 1 + src/features/interaction.ts | 8 + src/features/music.ts | 20 +-- src/features/polls.ts | 2 +- src/features/quiz.ts | 38 +++-- src/features/xp.ts | 16 +- src/index.ts | 22 ++- src/lib/helpers.ts | 5 +- src/lib/read.ts | 1 + src/lib/registry.ts | 25 ++- src/modules/Event.ts | 1 + src/modules/ExtendedMessage.ts | 74 ++++---- src/modules/SlashCommand.ts | 54 ++++++ src/typings/client.d.ts | 11 +- src/typings/env.d.ts | 1 + yarn.lock | 155 ++++++++++++++++- 57 files changed, 995 insertions(+), 380 deletions(-) create mode 100644 .env.example create mode 100644 src/_commands/admin/clear.ts create mode 100644 src/_commands/answer.ts create mode 100644 src/_commands/avatar.ts create mode 100644 src/_commands/fun/dab.ts create mode 100644 src/_commands/fun/gif.ts create mode 100644 src/_commands/fun/meme.ts create mode 100644 src/_commands/ping.ts create mode 100644 src/_commands/poll.ts create mode 100644 src/events/interactionCreate.ts rename src/events/{message.ts => messageCreate.ts} (65%) create mode 100644 src/features/interaction.ts create mode 100644 src/modules/SlashCommand.ts diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..3ed5915 --- /dev/null +++ b/.env.example @@ -0,0 +1,13 @@ +TOKEN= +CLIENT_ID= +PREFIX= +PORT= +API_KEY= +MONGO_URI= +NODE_ENV= +DATABASE_URL= +NODE_TLS_REJECT_UNAUTHORIZED= +COOKIE= +GENIUS_TOKEN= +REDIS_PATH= +REDIS_KEY_PREFIX= \ No newline at end of file diff --git a/package.json b/package.json index 92317d7..e174221 100644 --- a/package.json +++ b/package.json @@ -4,16 +4,19 @@ "description": "Discord bot", "main": "src/index.ts", "dependencies": { + "@discordjs/builders": "^0.5.0", "@discordjs/opus": "^0.3.3", + "@discordjs/rest": "^0.1.0-canary.0", "@joehoel/discord-reply": "^1.0.3", "axios": "^0.21.1", "bad-words": "^3.0.4", "consola": "^2.15.0", "cross-fetch": "^3.0.6", + "discord-api-types": "^0.22.0", "discord-paginationembed": "^2.1.0", "discord-reply": "^0.1.2", "discord-xp": "^1.1.14", - "discord.js": "^12.5.1", + "discord.js": "^13.0.1", "distube": "^2.8.8", "dotenv": "^8.2.0", "express": "^4.17.1", @@ -50,6 +53,7 @@ "eslint-plugin-prettier": "3.4.0", "eslint-plugin-react": "7.24.0", "eslint-plugin-react-hooks": "4.2.0", + "gen-env-types": "^1.3.0", "husky": "^6.0.0", "jest-fetch-mock": "^3.0.3", "lint-staged": "11.0.0", @@ -69,7 +73,8 @@ "coverage": "jest --coverage", "typeorm": "ts-node ./node_modules/typeorm/cli.js", "lint": "eslint --fix \"./src/**/*.ts\"", - "prepare": "husky install" + "prepare": "husky install", + "gen-env-types": "gen-env-types .env -o src/typings/env.d.ts -e ." }, "husky": { "hooks": { @@ -86,6 +91,6 @@ "@": "dist" }, "keywords": [], - "author": "", + "author": "Joël Kuijper", "license": "ISC" } diff --git a/src/_commands/admin/clear.ts b/src/_commands/admin/clear.ts new file mode 100644 index 0000000..df2dab7 --- /dev/null +++ b/src/_commands/admin/clear.ts @@ -0,0 +1,39 @@ +import { wait } from "@/lib/helpers"; +import SlashCommand, { CommandType } from "@/modules/SlashCommand"; +import { Message, TextChannel } from "discord.js"; + +export default new SlashCommand({ + name: "clear", + description: "Clear the chat", + options: [ + { + name: "amount", + type: CommandType.NUMBER, + required: true, + description: "Amount of messages to clear from the chat", + }, + ], + async execute(interaction) { + const amount = interaction.options.getNumber("amount")!; + + if (amount > 101) { + return interaction.reply({ content: "You can`t delete more than 100 messages at once!", ephemeral: true }); + } + + if (amount < 1) { + return interaction.reply({ content: "You have to delete at least 1 message!", ephemeral: true }); + } + + await interaction.channel!.messages.fetch({ limit: amount }).then((messages) => { + (interaction.channel as TextChannel).bulkDelete(messages); + }); + + const message = (await interaction.reply({ + content: `Successfully deleted **${amount}** messages!`, + fetchReply: true, + })) as Message; + + await wait(2000); + return message.delete(); + }, +}); diff --git a/src/_commands/answer.ts b/src/_commands/answer.ts new file mode 100644 index 0000000..01e4174 --- /dev/null +++ b/src/_commands/answer.ts @@ -0,0 +1,41 @@ +import { USERS } from "@/lib/contants"; +import { embed } from "@/lib/helpers"; +import SlashCommand, { CommandType } from "@/modules/SlashCommand"; + +export default new SlashCommand({ + name: "answer", + description: "Answer the question of the day", + options: [ + { + name: "answer", + description: "The answer to the question", + type: CommandType.STRING, + required: true, + }, + ], + async execute(interaction) { + const author = interaction.user; + + // Get answer from the interaction + const answer = interaction.options.getString("answer")!; + + // Reply to only the user that submitted the answer + interaction.reply({ ephemeral: true, content: answer }); + + // TODO: Change to USERS.JESSE + const member = await interaction.client.users.fetch(USERS.JOEL); + + // Send answer to Jesse + await member.send({ + embeds: [ + embed({ + description: answer, + author: { + name: author.username, + iconURL: author.displayAvatarURL() ?? author.defaultAvatarURL, + }, + }), + ], + }); + }, +}); diff --git a/src/_commands/avatar.ts b/src/_commands/avatar.ts new file mode 100644 index 0000000..4968ca3 --- /dev/null +++ b/src/_commands/avatar.ts @@ -0,0 +1,12 @@ +import SlashCommand, { CommandType } from "@/modules/SlashCommand"; + +export default new SlashCommand({ + name: "avatar", + description: "Get the avatar URL of the selected user, or your own avatar.", + options: [{ name: "target", description: "The user's avatar to show", type: CommandType.USER }], + execute(interaction) { + const user = interaction.options.getUser("target"); + if (user) return interaction.reply(`${user.username}'s avatar: ${user.displayAvatarURL({ dynamic: true })}`); + return interaction.reply(`Your avatar: ${interaction.user.displayAvatarURL({ dynamic: true })}`); + }, +}); diff --git a/src/_commands/fun/dab.ts b/src/_commands/fun/dab.ts new file mode 100644 index 0000000..346c59d --- /dev/null +++ b/src/_commands/fun/dab.ts @@ -0,0 +1,11 @@ +import { gif } from "@/lib/helpers"; +import SlashCommand from "@/modules/SlashCommand"; + +export default new SlashCommand({ + name: "dab", + description: "Sends a random dab gif in chat", + async execute(interaction) { + const url = await gif("dab"); + interaction.reply(url); + }, +}); diff --git a/src/_commands/fun/gif.ts b/src/_commands/fun/gif.ts new file mode 100644 index 0000000..add6bb4 --- /dev/null +++ b/src/_commands/fun/gif.ts @@ -0,0 +1,13 @@ +import { gif } from "@/lib/helpers"; +import SlashCommand, { CommandType } from "@/modules/SlashCommand"; + +export default new SlashCommand({ + name: "gif", + description: "Sends a random GIF in chat", + options: [{ name: "tag", description: "Tag to search a gif for", type: CommandType.STRING, required: true }], + async execute(interaction) { + const tag = interaction.options.getString("tag")!; + const url = await gif(tag); + interaction.reply(url); + }, +}); diff --git a/src/_commands/fun/meme.ts b/src/_commands/fun/meme.ts new file mode 100644 index 0000000..aff1fa6 --- /dev/null +++ b/src/_commands/fun/meme.ts @@ -0,0 +1,26 @@ +import Reddit from "@/lib/reddit"; +import SlashCommand, { CommandType } from "@/modules/SlashCommand"; +import { MessageEmbed } from "discord.js"; + +export default new SlashCommand({ + name: "meme", + description: "Shows a random lit meme from the provided subreddit (defaults to 'r/dankmemes')", + options: [{ name: "sub", description: "subreddit", type: CommandType.STRING, required: false }], + async execute(interaction) { + const subreddit = interaction.options.getString("sub") ?? "dankmemes"; + + const reddit = new Reddit(subreddit); + const { title, url, date, author, sub, link } = await reddit.getRandomHotPost(); + + const embed = new MessageEmbed() + .setColor("#ffc600") + .setTitle(title) + .setDescription(sub) + .setFooter(author) + .setURL(link) + .setImage(url) + .setTimestamp(date); + + return interaction.reply({ embeds: [embed] }); + }, +}); diff --git a/src/_commands/ping.ts b/src/_commands/ping.ts new file mode 100644 index 0000000..bc1e205 --- /dev/null +++ b/src/_commands/ping.ts @@ -0,0 +1,28 @@ +import { embed } from "@/lib/helpers"; +import SlashCommand from "@/modules/SlashCommand"; +import { Message } from "discord.js"; + +export default new SlashCommand({ + name: "ping", + description: "Pong!", + async execute(interaction) { + const message = (await interaction.reply({ + embeds: [ + embed({ + description: `**Pong!**`, + }), + ], + fetchReply: true, + })) as Message; + + const ping = message.createdTimestamp - interaction.createdTimestamp!; + + await message.edit({ + embeds: [ + embed({ + description: `**Pong!** \`${ping}ms\``, + }), + ], + }); + }, +}); diff --git a/src/_commands/poll.ts b/src/_commands/poll.ts new file mode 100644 index 0000000..b5472ad --- /dev/null +++ b/src/_commands/poll.ts @@ -0,0 +1,109 @@ +import { embed } from "@/lib/helpers"; +import SlashCommand, { CommandType } from "@/modules/SlashCommand"; +import { SlashCommandOptionBase } from "@discordjs/builders/dist/interactions/slashCommands/mixins/CommandOptionBase"; +import { Interaction, Message } from "discord.js"; + +const options = [ + "🇦", + "🇧", + "🇨", + "🇩", + "🇪", + "🇫", + "🇬", + "🇭", + "🇮", + "🇯", + "🇰", + "🇱", + "🇲", + "🇳", + "🇴", + "🇵", + "🇶", + "🇷", + "🇸", + "🇹", + "🇺", + "🇻", + "🇼", + "🇽", + "🇾", + "🇿", +]; + +const pollLog: { [userId: string]: { lastPoll: number } } = {}; + +function canSendPoll(userId: string): boolean { + if (pollLog[userId]) { + const timeSince = Date.now() - pollLog[userId].lastPoll; + if (timeSince < 30000) { + return false; + } + } + return true; +} + +export default new SlashCommand({ + name: "poll", + description: "Create a poll where people can react to vote", + options: [ + { name: "question", description: "question", type: CommandType.STRING }, + { + name: "answer_1", + description: "optional answer", + required: false, + type: CommandType.STRING, + }, + { + name: "answer_2", + description: "optional answer", + required: false, + type: CommandType.STRING, + }, + { + name: "answer_3", + description: "optional answer", + required: false, + type: CommandType.STRING, + }, + { + name: "answer_4", + description: "optional answer", + required: false, + type: CommandType.STRING, + }, + { + name: "answer_5", + description: "optional answer", + required: false, + type: CommandType.STRING, + }, + { + name: "answer_6", + description: "optional answer", + required: false, + type: CommandType.STRING, + }, + ], + async execute(interaction) { + const question = interaction.options.getString("question"); + const author = interaction.user; + + const message = (await interaction.reply({ + embeds: [ + embed({ + title: `${question}`, + footer: { + text: `Poll started by: ${author.username}`, + iconURL: author.avatarURL()!, + }, + }), + ], + fetchReply: true, + })) as Message; + await message.react("👍"); + await message.react("👎"); + await message.react("🤷‍♀️"); + }, +}); diff --git a/src/commands/admin/level.ts b/src/commands/admin/level.ts index 9b858bb..f502c8d 100644 --- a/src/commands/admin/level.ts +++ b/src/commands/admin/level.ts @@ -26,13 +26,15 @@ export default new Command({ switch (type) { case Type.SET: Levels.setLevel(target.id, GUILD_ID, parseInt(lvl)); - return message.channel.send( - embed({ - title: "Level", - description: `Successfully updated ${target}'s level to **${Math.floor(parseInt(lvl))}**`, - timestamp: Date.now(), - }) - ); + return message.channel.send({ + embeds: [ + embed({ + title: "Level", + description: `Successfully updated ${target}'s level to **${Math.floor(parseInt(lvl))}**`, + timestamp: Date.now(), + }), + ], + }); default: break; diff --git a/src/commands/admin/reactionrole.ts b/src/commands/admin/reactionrole.ts index c8bfe39..413d1f8 100644 --- a/src/commands/admin/reactionrole.ts +++ b/src/commands/admin/reactionrole.ts @@ -9,13 +9,15 @@ export default new Command({ aliases: ["rr"], exclusive: true, async execute(_, message) { - const msg = await message.channel.send( - embed({ - title: "Welkom", - description: `Reageer op dit bericht om jezelf een role te geven\n\n ${EMOJIS.MEMBER} - **Member**\n\n ${EMOJIS.SPEEDRUNNER} - **Speedrunner**\n\n ${EMOJIS.POLLER} - **Poller**\n\n ${EMOJIS.CONTESTANT} - **Contestant**\n\n`, - timestamp: undefined, - }) - ); + const msg = await message.channel.send({ + embeds: [ + embed({ + title: "Welkom", + description: `Reageer op dit bericht om jezelf een role te geven\n\n ${EMOJIS.MEMBER} - **Member**\n\n ${EMOJIS.SPEEDRUNNER} - **Speedrunner**\n\n ${EMOJIS.POLLER} - **Poller**\n\n ${EMOJIS.CONTESTANT} - **Contestant**\n\n`, + timestamp: undefined, + }), + ], + }); await msg.react(EMOJIS.MEMBER); await msg.react(EMOJIS.SPEEDRUNNER); await msg.react(EMOJIS.POLLER); diff --git a/src/commands/admin/say.ts b/src/commands/admin/say.ts index bd4f1b0..9e82c2a 100644 --- a/src/commands/admin/say.ts +++ b/src/commands/admin/say.ts @@ -7,8 +7,8 @@ export default new Command({ usage: "", permissions: ["MANAGE_MESSAGES"], aliases: ["s"], - execute(client, message, args) { - message.delete({ timeout: 1000 }); + execute(_, message, args) { + message.delete(); message.channel.send(args.join(" ")); }, }); diff --git a/src/commands/admin/status.ts b/src/commands/admin/status.ts index 79daf15..5193972 100644 --- a/src/commands/admin/status.ts +++ b/src/commands/admin/status.ts @@ -9,11 +9,8 @@ export default new Command({ exclusive: true, async execute(client, message, args) { args.unshift(); - await client.user!.setPresence({ - activity: { - name: args.join(" "), - type: 0, - }, + client.user!.setPresence({ + activities: [{ name: args[0], type: 0 }], }); return message.channel.send(`Changed my status ${message.author}!`); diff --git a/src/commands/help.ts b/src/commands/help.ts index 1e2ca83..cbe16a0 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -18,39 +18,40 @@ export default new Command({ const command = client.commands.get(commandName)! || client.commands.get(client.aliases.get(commandName)!); if (command && isAllowed(command, message.guild!.id)) { - return message.channel.send( - embed({ - title: "Help", - fields: [ - { - name: "Name", - value: `\`${command.name}\``, - }, - { - name: "Aliases", - value: - command.aliases.length >= 1 - ? `\`${command.aliases.join(", ")}\`` - : "This command doesn't have any aliases", - }, - { - name: "Description", - value: `\`${command.description}\``, - }, - { - name: "Usage", - value: command.usage - ? `\`${prefix}${command.name} ${command.usage}\`` - : "This command doesn't have any arguments", - }, - ], - }) - ); + return message.channel.send({ + embeds: [ + embed({ + title: "Help", + fields: [ + { + name: "Name", + value: `\`${command.name}\``, + }, + { + name: "Aliases", + value: + command.aliases.length >= 1 + ? `\`${command.aliases.join(", ")}\`` + : "This command doesn't have any aliases", + }, + { + name: "Description", + value: `\`${command.description}\``, + }, + { + name: "Usage", + value: command.usage + ? `\`${prefix}${command.name} ${command.usage}\`` + : "This command doesn't have any arguments", + }, + ], + }), + ], + }); } } const commands = client.commands - .array() .filter((command) => { return canExecute(message.member!, command) && isAllowed(command, message.guild!.id); }) diff --git a/src/commands/leaderboard.ts b/src/commands/leaderboard.ts index 363314a..57ad64f 100644 --- a/src/commands/leaderboard.ts +++ b/src/commands/leaderboard.ts @@ -29,17 +29,19 @@ export default new Command({ return message.channel.send(`Game ${game.name} already exists`); }); - return message.channel.send( - embed({ - title: "Game created", - fields: [ - { - name: "Game", - value: capitalize(game.name), - }, - ], - }) - ); + return message.channel.send({ + embeds: [ + embed({ + title: "Game created", + fields: [ + { + name: "Game", + value: capitalize(game.name), + }, + ], + }), + ], + }); } if (gameName && leaderboardName) { @@ -48,44 +50,48 @@ export default new Command({ const lb = new Leaderboard({ name: leaderboardName, game: foundGame }); await lb.save(); - return message.channel.send( - embed({ - title: "Leaderboard created", - fields: [ - { - name: "Game", - value: `\`${foundGame.name}\``, - }, - { - name: "Leaderboard", - value: `\`${lb.name}\``, - }, - ], - timestamp: Date.now(), - }) - ); + return message.channel.send({ + embeds: [ + embed({ + title: "Leaderboard created", + fields: [ + { + name: "Game", + value: `\`${foundGame.name}\``, + }, + { + name: "Leaderboard", + value: `\`${lb.name}\``, + }, + ], + timestamp: Date.now(), + }), + ], + }); } else { const game = new Game({ name: gameName }); await game.save(); const lb = new Leaderboard({ name: leaderboardName, game }); await lb.save(); - return message.channel.send( - embed({ - title: "Leaderboard created", - fields: [ - { - name: "Game", - value: game.name, - }, - { - name: "Leaderboard", - value: lb.name, - }, - ], - timestamp: Date.now(), - }) - ); + return message.channel.send({ + embeds: [ + embed({ + title: "Leaderboard created", + fields: [ + { + name: "Game", + value: game.name, + }, + { + name: "Leaderboard", + value: lb.name, + }, + ], + timestamp: Date.now(), + }), + ], + }); } } break; @@ -99,30 +105,32 @@ export default new Command({ { relations: ["game"] } ); const scores = await Score.find({ where: { leaderboard: lb } }); - return message.channel.send( - embed({ - title: capitalize(leaderboardName), - fields: distinctArrayByKey(scores, "user") - .sort((a, b) => { - if (a.score < b.score) return -1; - return 1; - }) - .map((score, i) => { - return { - name: i + 1 + ".", - value: `Score: \`${score.score}\`\n Username: ${ - score.user - }\n Date: \`${score.createdAt.toLocaleString()}\`\n Proof: ${ - score.proof ? `${score.proof}` : "" - }`, - }; - }), - }) - ); + return message.channel.send({ + embeds: [ + embed({ + title: capitalize(leaderboardName), + fields: distinctArrayByKey(scores, "user") + .sort((a, b) => { + if (a.score < b.score) return -1; + return 1; + }) + .map((score, i) => { + return { + name: i + 1 + ".", + value: `Score: \`${score.score}\`\n Username: ${ + score.user + }\n Date: \`${score.createdAt.toLocaleString()}\`\n Proof: ${ + score.proof ? `${score.proof}` : "" + }`, + }; + }), + }), + ], + }); } catch (error) { - return message.channel.send( - embed({ title: "Something went wrong!", description: "Couldn't find that leaderboard" }) - ); + return message.channel.send({ + embeds: [embed({ title: "Something went wrong!", description: "Couldn't find that leaderboard" })], + }); } } if (gameName == "ranks") { @@ -132,19 +140,21 @@ export default new Command({ const leaderboard = await Levels.computeLeaderboard(client, rawLeaderboard, true); // We process the leaderboard. - message.channel.send( - embed({ - title: "Ranks", - fields: leaderboard?.map((user: LeaderboardUser) => { - return { - name: user.position + ".", - value: `User: <@${user.userID}>\nLevel: \`${user.level}\`\nXP: \`${user.xp}/${Levels.xpFor( - user.level + 1 - )}\``, - }; + message.channel.send({ + embeds: [ + embed({ + title: "Ranks", + fields: leaderboard?.map((user: LeaderboardUser) => { + return { + name: user.position + ".", + value: `User: <@${user.userID}>\nLevel: \`${user.level}\`\nXP: \`${user.xp}/${Levels.xpFor( + user.level + 1 + )}\``, + }; + }), }), - }) - ); + ], + }); return; } break; @@ -166,12 +176,14 @@ export default new Command({ user: message.author.toString(), }); await newScore.save(); - return message.channel.send( - new MessageEmbed({ - title: "Successfully submitted score!", - color: "#ffc600", - }) - ); + return message.channel.send({ + embeds: [ + new MessageEmbed({ + title: "Successfully submitted score!", + color: "#ffc600", + }), + ], + }); } else { // Leaderboard doesn't exist return message.channel.send("Couldn't find that leaderboard"); diff --git a/src/commands/meme.ts b/src/commands/meme.ts index 013cbb8..f35201d 100644 --- a/src/commands/meme.ts +++ b/src/commands/meme.ts @@ -7,7 +7,7 @@ export default new Command({ description: "Shows a random lit meme from the provided subreddit (defaults to 'r/dankmemes')", usage: "", aliases: ["m"], - async execute(client, message, [subreddit]) { + async execute(_, message, [subreddit]) { const reddit = new Reddit(subreddit); // const { title, url, date, author, sub, post } = await meme(subreddit); const { title, url, date, author, sub, link } = await reddit.getRandomHotPost(); @@ -21,6 +21,6 @@ export default new Command({ .setImage(url) .setTimestamp(date); - return message.channel.send(embed); + return message.channel.send({ embeds: [embed] }); }, }); diff --git a/src/commands/music/autoplay.ts b/src/commands/music/autoplay.ts index a450f46..124a7f6 100644 --- a/src/commands/music/autoplay.ts +++ b/src/commands/music/autoplay.ts @@ -9,8 +9,8 @@ export default new Command({ execute(client, message) { if (!message.member?.voice.channel) throw new Error("NotInVoice"); const mode = client.music.toggleAutoplay(message); - return message.channel.send( - embed({ title: "Music", description: "Set autoplay mode to `" + (mode ? "On" : "Off") + "`" }) - ); + return message.channel.send({ + embeds: [embed({ title: "Music", description: "Set autoplay mode to `" + (mode ? "On" : "Off") + "`" })], + }); }, }); diff --git a/src/commands/music/loop.ts b/src/commands/music/loop.ts index 0258adc..f5f0cad 100644 --- a/src/commands/music/loop.ts +++ b/src/commands/music/loop.ts @@ -19,6 +19,6 @@ export default new Command({ }, ], }); - return message.channel.send(embed); + return message.channel.send({ embeds: [embed] }); }, }); diff --git a/src/commands/music/lyrics.ts b/src/commands/music/lyrics.ts index c8a8149..ee1b19b 100644 --- a/src/commands/music/lyrics.ts +++ b/src/commands/music/lyrics.ts @@ -23,14 +23,16 @@ export default new Command({ try { const { lyrics, name, artist, album_art, url } = await getLyrics(song); if (lyrics.trim().length) { - return await message.channel.send( - embed({ - title: `${name} - ${artist}`, - description: lyrics, - thumbnail: { url: album_art }, - url, - }) - ); + return await message.channel.send({ + embeds: [ + embed({ + title: `${name} - ${artist}`, + description: lyrics, + thumbnail: { url: album_art }, + url, + }), + ], + }); } } catch (error) { client.logger.error(error); diff --git a/src/commands/music/now.ts b/src/commands/music/now.ts index a925df1..a4fffee 100644 --- a/src/commands/music/now.ts +++ b/src/commands/music/now.ts @@ -12,25 +12,27 @@ export default new Command({ const queue = client.music.getQueue(message); const song = queue.songs[0]; if (song && queue) - return message.channel.send( - new MessageEmbed({ - title: "Music", - color: "#ffc600", - fields: [ - { - name: "Playing", - value: `\`${song.name}\` - \`${song.formattedDuration}\``, - }, - { - name: "Requested by", - value: song.user, - }, - { - name: "Status", - value: status(queue), - }, - ], - }) - ); + return message.channel.send({ + embeds: [ + new MessageEmbed({ + title: "Music", + color: "#ffc600", + fields: [ + { + name: "Playing", + value: `\`${song.name}\` - \`${song.formattedDuration}\``, + }, + { + name: "Requested by", + value: song.user.username, + }, + { + name: "Status", + value: status(queue), + }, + ], + }), + ], + }); }, }); diff --git a/src/commands/music/pause.ts b/src/commands/music/pause.ts index 2603782..5b6cd9f 100644 --- a/src/commands/music/pause.ts +++ b/src/commands/music/pause.ts @@ -8,6 +8,6 @@ export default new Command({ execute(client, message) { if (!message.member?.voice.channel) throw new Error("NotInVoice"); client.music.pause(message); - return message.channel.send(embed({ title: "Music paused/resumed" })); + return message.channel.send({ embeds: [embed({ title: "Music paused/resumed" })] }); }, }); diff --git a/src/commands/music/queue.ts b/src/commands/music/queue.ts index 67ebcac..c447af1 100644 --- a/src/commands/music/queue.ts +++ b/src/commands/music/queue.ts @@ -37,12 +37,14 @@ export default new Command({ client.logger.error(error); } } else { - return message.channel.send( - embed({ - title: "Music", - description: "Queue is empty 🐱", - }) - ); + return message.channel.send({ + embeds: [ + embed({ + title: "Music", + description: "Queue is empty 🐱", + }), + ], + }); } }, }); diff --git a/src/commands/music/shuffle.ts b/src/commands/music/shuffle.ts index 26ce51f..e4a0547 100644 --- a/src/commands/music/shuffle.ts +++ b/src/commands/music/shuffle.ts @@ -11,10 +11,12 @@ export default new Command({ if (!message.member?.voice.channel) throw new Error("NotInVoice"); client.music.shuffle(message); queue.execute(client, message, args); - return message.channel.send( - embed({ - title: "Toggled shuffle", - }) - ); + return message.channel.send({ + embeds: [ + embed({ + title: "Toggled shuffle", + }), + ], + }); }, }); diff --git a/src/commands/music/skip.ts b/src/commands/music/skip.ts index 1ffd7dd..d55729e 100644 --- a/src/commands/music/skip.ts +++ b/src/commands/music/skip.ts @@ -18,12 +18,14 @@ export default new Command({ return client.music.skip(message); } else { const votesRequired = Math.ceil(members.size * 0.6); - const msg = await message.channel.send( - embed({ - title: "Music", - description: `Votes required to skip: ${votesRequired}`, - }) - ); + const msg = await message.channel.send({ + embeds: [ + embed({ + title: "Music", + description: `Votes required to skip: ${votesRequired}`, + }), + ], + }); await msg.react("👍"); await msg.react("👎"); @@ -31,18 +33,19 @@ export default new Command({ if (user.bot) return false; const { channel } = message.guild!.members.cache.get(user.id)!.voice; if (channel) { - return ["👍"].includes(reaction.emoji.name); + return ["👍"].includes(reaction.emoji.name!); } else { return false; } }; try { - const reactions = await msg.awaitReactions(filter, { - max: votesRequired, - time: 10000, - errors: ["time"], - }); + // const reactions = await msg.awaitReactions(filter, { + // max: votesRequired, + // time: 10000, + // errors: ["time"], + // }); + const reactions = await msg.awaitReactions({ max: votesRequired, time: 10000, errors: ["time"], filter }); const totalVotes = reactions.get("👍")!.users.cache.filter((u) => !u.bot); if (totalVotes.size >= votesRequired) { return client.music.skip(message); diff --git a/src/commands/music/stop.ts b/src/commands/music/stop.ts index 8b5dce4..ccd14b5 100644 --- a/src/commands/music/stop.ts +++ b/src/commands/music/stop.ts @@ -22,7 +22,7 @@ export default new Command({ }, ], }); - message.channel.send(embed); + message.channel.send({ embeds: [embed] }); return client.music.stop(message); }, }); diff --git a/src/commands/ping.ts b/src/commands/ping.ts index 039c087..3903a1d 100644 --- a/src/commands/ping.ts +++ b/src/commands/ping.ts @@ -8,13 +8,15 @@ export default new Command({ const send = embed({ description: `**Pong!**`, }); - return message.channel.send(send).then((m) => { + return message.channel.send({ embeds: [send] }).then((m) => { const ping = m.createdTimestamp - message.createdTimestamp; - m.edit( - embed({ - description: `**Pong!** \`${ping}ms\``, - }) - ); + m.edit({ + embeds: [ + embed({ + description: `**Pong!** \`${ping}ms\``, + }), + ], + }); }); }, }); diff --git a/src/commands/poll.ts b/src/commands/poll.ts index f94ae94..60375b7 100644 --- a/src/commands/poll.ts +++ b/src/commands/poll.ts @@ -52,7 +52,7 @@ export default new Command({ admin: false, async execute(client, message) { let args = message.content.match(/"(.+?)"/g)!; - if (!canSendPoll(message.author.id) && !message.member!.hasPermission("ADMINISTRATOR")) { + if (!canSendPoll(message.author.id) && !message.member!.permissions.has("ADMINISTRATOR")) { return message.channel.send(`${message.author} please wait before sending another poll.`); } else if (args.length === 1) { // yes no unsure question @@ -63,13 +63,15 @@ export default new Command({ const id = `#${question.toUpperCase()?.substr(0, 1) + Math.floor(Math.random() * 100)}`; await message.delete(); return message.channel - .send( - new MessageEmbed() - .setColor("#ffc600") - .setTitle(`${question}`) - .setTimestamp() - .setFooter(`Poll started by: ${message.author.username}`, message.author.displayAvatarURL()) - ) + .send({ + embeds: [ + new MessageEmbed() + .setColor("#ffc600") + .setTitle(`${question}`) + .setTimestamp() + .setFooter(`Poll started by: ${message.author.username}`, message.author.displayAvatarURL()), + ], + }) .then(async (pollMessage) => { await pollMessage.react("👍"); await pollMessage.react("👎"); @@ -92,14 +94,16 @@ export default new Command({ }; await message.delete(); return message.channel - .send( - new MessageEmbed() - .setColor("#ffc600") - .setTitle(`${question} ${id}`) - .setDescription(`${questionOptions.map((option, i) => `${options[i]} - ${option}`).join("\n")}`) - .setFooter(`Poll started by: ${message.author.username}`, `${message.author.displayAvatarURL()}`) - .setTimestamp() - ) + .send({ + embeds: [ + new MessageEmbed() + .setColor("#ffc600") + .setTitle(`${question} ${id}`) + .setDescription(`${questionOptions.map((option, i) => `${options[i]} - ${option}`).join("\n")}`) + .setFooter(`Poll started by: ${message.author.username}`, `${message.author.displayAvatarURL()}`) + .setTimestamp(), + ], + }) .then(async (pollMessage) => { for (let i = 0; i < questionOptions.length; i++) { await pollMessage.react(options[i]); diff --git a/src/commands/rank.ts b/src/commands/rank.ts index 7a8e453..3fe2481 100644 --- a/src/commands/rank.ts +++ b/src/commands/rank.ts @@ -12,15 +12,20 @@ export default new Command({ const user = await Levels.fetch(target.id, message!.guild!.id!); // Selects the target from the database. - if (!user) return message.channel.send(embed({ description: "Seems like this user has not earned any xp so far" })); // If there isnt such user in the database, we send a message in general. + if (!user) + return message.channel.send({ + embeds: [embed({ description: "Seems like this user has not earned any xp so far" })], + }); // If there isnt such user in the database, we send a message in general. - return message.channel.send( - embed({ - title: "Rank", - description: `**${target.username}** is currently level \`${user.level}\` \`(${user.xp}/${Levels.xpFor( - user.level + 1 - )})\``, - }) - ); + return message.channel.send({ + embeds: [ + embed({ + title: "Rank", + description: `**${target.username}** is currently level \`${user.level}\` \`(${user.xp}/${Levels.xpFor( + user.level + 1 + )})\``, + }), + ], + }); }, }); diff --git a/src/commands/remindme.ts b/src/commands/remindme.ts index b20aad8..b625317 100644 --- a/src/commands/remindme.ts +++ b/src/commands/remindme.ts @@ -10,26 +10,28 @@ export default new Command({ async execute(_, message, [t, ...msg]) { const time = ms(t); // const user = message.mentions.members?.first()?.user || message.author; - message.channel.send(embed({ title: "Reminder has been set" })); + message.channel.send({ embeds: [embed({ title: "Reminder has been set" })] }); setTimeout(() => { - return message.channel.send( - embed({ - title: "Reminder", - fields: [ - { - name: "Message", - value: msg.join(" "), - inline: true, - }, - { - name: "Link", - value: `[Message](${message.url})`, - inline: true, - }, - ], - timestamp: new Date(Date.now() - time), - }) - ); + return message.channel.send({ + embeds: [ + embed({ + title: "Reminder", + fields: [ + { + name: "Message", + value: msg.join(" "), + inline: true, + }, + { + name: "Link", + value: `[Message](${message.url})`, + inline: true, + }, + ], + timestamp: new Date(Date.now() - time), + }), + ], + }); }, time); }, }); diff --git a/src/commands/roll.ts b/src/commands/roll.ts index b3c84d9..8c297b5 100644 --- a/src/commands/roll.ts +++ b/src/commands/roll.ts @@ -8,13 +8,13 @@ export default new Command({ async execute(_, message, args) { if (args.length == 0) { const coin = random(["Kop", "Munt"]); - return message.channel.send(embed({ title: "Rolled", description: coin })); + return message.channel.send({ embeds: [embed({ title: "Rolled", description: coin })] }); } else if (args.length == 1) { const n = parseInt(args[0]); const number = random(1, n); - return message.channel.send(embed({ title: "Rolled", description: number.toString() })); + return message.channel.send({ embeds: [embed({ title: "Rolled", description: number.toString() })] }); } const choice = random(args); - return message.channel.send(embed({ title: "Rolled", description: choice })); + return message.channel.send({ embeds: [embed({ title: "Rolled", description: choice })] }); }, }); diff --git a/src/commands/snipe.ts b/src/commands/snipe.ts index 96908fa..d02d6e9 100644 --- a/src/commands/snipe.ts +++ b/src/commands/snipe.ts @@ -6,13 +6,15 @@ export default new Command({ description: "Snipe the most recent deleted command", execute(client, message) { const msg = client.snipes.get(message.channel.id); - return message.channel.send( - embed({ - author: { name: msg?.author?.toString(), iconURL: msg?.member?.user.displayAvatarURL() }, - description: msg!.content!, - footer: { text: "🎯 Get sniped lol" }, - timestamp: Date.now(), - }) - ); + return message.channel.send({ + embeds: [ + embed({ + author: { name: msg?.author?.toString(), iconURL: msg?.member?.user.displayAvatarURL() }, + description: msg!.content!, + footer: { text: "🎯 Get sniped lol" }, + timestamp: Date.now(), + }), + ], + }); }, }); diff --git a/src/commands/swears.ts b/src/commands/swears.ts index 960c92c..37c0101 100644 --- a/src/commands/swears.ts +++ b/src/commands/swears.ts @@ -13,12 +13,14 @@ export default new Command({ const user = message.mentions.members?.first()?.user || message.author; - return await message.channel.send( - embed({ - title: "Swears", - author: { name: user.username, iconURL: user.displayAvatarURL() }, - description: `\`${swear?.swears ?? "None"}\``, - }) - ); + return await message.channel.send({ + embeds: [ + embed({ + title: "Swears", + author: { name: user.username, iconURL: user.displayAvatarURL() }, + description: `\`${swear?.swears ?? "None"}\``, + }), + ], + }); }, }); diff --git a/src/commands/todo.ts b/src/commands/todo.ts index 6f7a637..81e4bef 100644 --- a/src/commands/todo.ts +++ b/src/commands/todo.ts @@ -6,13 +6,15 @@ export default new Command({ name: "todo", description: "Add a new todo", exclusive: true, - async execute(client, message, args) { + async execute(_, message) { const todos = await getTodos(); - return message.channel.send( - embed({ - title: "Todo's", - description: `\`\`\`md\n${todos}\`\`\`\n`, - }) - ); + return message.channel.send({ + embeds: [ + embed({ + title: "Todo's", + description: `\`\`\`md\n${todos}\`\`\`\n`, + }), + ], + }); }, }); diff --git a/src/commands/typo.ts b/src/commands/typo.ts index 063d303..9114d17 100644 --- a/src/commands/typo.ts +++ b/src/commands/typo.ts @@ -8,6 +8,6 @@ export default new Command({ exclusive: true, execute(client, message, args) { const target = message.mentions.users.first(); - message.channel.send(embed({ description: `${target}` })); + message.channel.send({ embeds: [embed({ description: `${target}` })] }); }, }); diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts new file mode 100644 index 0000000..a04cf36 --- /dev/null +++ b/src/events/interactionCreate.ts @@ -0,0 +1,10 @@ +import * as features from "@/features"; +import { Interaction } from "discord.js"; +import Event from "../modules/Event"; + +export default new Event({ + name: "interactionCreate", + async run(_, interaction: Interaction) { + await features.interaction(interaction); + }, +}); diff --git a/src/events/message.ts b/src/events/messageCreate.ts similarity index 65% rename from src/events/message.ts rename to src/events/messageCreate.ts index e4cc34c..ff193bf 100644 --- a/src/events/message.ts +++ b/src/events/messageCreate.ts @@ -4,7 +4,7 @@ import * as features from "../features"; import Event from "../modules/Event"; export default new Event({ - name: "message", + name: "messageCreate", async run(client: Client, message: Message) { try { await features.filter(client, message); @@ -14,17 +14,19 @@ export default new Event({ await features.dad(client, message); await features.quiz(client, message); } catch (error) { - await message.channel.send( - embed({ - title: "Something went wrong!", - fields: [ - { - name: "Error", - value: error, - }, - ], - }) - ); + await message.channel.send({ + embeds: [ + embed({ + title: "Something went wrong!", + fields: [ + { + name: "Error", + value: error, + }, + ], + }), + ], + }); throw error; } diff --git a/src/events/ready.ts b/src/events/ready.ts index 349a87d..c65c760 100644 --- a/src/events/ready.ts +++ b/src/events/ready.ts @@ -24,7 +24,7 @@ export default new Event({ client.user?.setPresence({ status: "online", - activity: { name: `with my ${totalMembers} nerds` }, + activities: [{ name: `with my ${totalMembers} nerds` }], }); client.logger.success("Compagnon" + colors.green.bold(" online!")); diff --git a/src/features/command.ts b/src/features/command.ts index 6767300..5843c98 100644 --- a/src/features/command.ts +++ b/src/features/command.ts @@ -3,7 +3,7 @@ import { embed, isAllowed } from "../lib/helpers"; const { PREFIX } = process.env; export default async (client: Client, message: Message) => { - if (message.channel.type == "dm") return; + if (message.channel.type == "DM") return; const prefix = client.config.get(message.guild!.id)?.prefix || PREFIX; // Not a command or author is bot @@ -32,7 +32,7 @@ export default async (client: Client, message: Message) => { } // Check if user is admin for command - if (command.admin && !message.member!.hasPermission("ADMINISTRATOR")) { + if (command.admin && !message.member!.permissions.has("ADMINISTRATOR")) { await message.channel.send(`Sorry, ${message.author}! You must be an admin to execute this command.`); return; } @@ -44,7 +44,7 @@ export default async (client: Client, message: Message) => { } // Check if user has the correct permissions te execute command - if (command.permissions.some((permission) => !message.member!.hasPermission(permission))) { + if (command.permissions.some((permission) => !message.member!.permissions.has(permission))) { await message.channel.send(`Sorry, ${message.author}! You are not allowed to execute that command.`); return; } @@ -67,9 +67,9 @@ export default async (client: Client, message: Message) => { return; } catch (error) { if (error.message === "NotInVoice") { - return message.channel.send( - embed({ title: "Error", description: "You must be in a voice channel to execute that command!" }) - ); + return message.channel.send({ + embeds: [embed({ title: "Error", description: "You must be in a voice channel to execute that command!" })], + }); } client.logger.error(error); await message.reply("There was an error trying to execute that command!"); diff --git a/src/features/dad.ts b/src/features/dad.ts index a3af4e3..03fa642 100644 --- a/src/features/dad.ts +++ b/src/features/dad.ts @@ -4,7 +4,7 @@ import { Client, Message } from "discord.js"; const { PREFIX } = process.env; export default async (client: Client, message: Message) => { - if (message.channel.type == "dm" || message.channel.id === CHANNELS.ANTWOORDEN) return; + if (message.channel.type == "DM" || message.channel.id === CHANNELS.ANTWOORDEN) return; const prefix = client.config.get(message.guild!.id)?.prefix || PREFIX; if (message.content.startsWith(prefix) || message.author.bot) return; @@ -18,6 +18,6 @@ export default async (client: Client, message: Message) => { const words = text.split(" "); const index = words.indexOf(match[match.length - 1].split(" ")[1]) + 1; const name = words.slice(index).join(" "); - message.inlineReply(`Hallo ${name}, ik ben compagnon :wave:`); + message.reply(`Hallo ${name}, ik ben compagnon :wave:`); } }; diff --git a/src/features/filter.ts b/src/features/filter.ts index 00f726b..efb4971 100644 --- a/src/features/filter.ts +++ b/src/features/filter.ts @@ -6,7 +6,7 @@ import { Swear } from "../entity/Swear"; const { PREFIX } = process.env; export default async (client: Client, message: Message) => { - if (message.channel.type == "dm") return; + if (message.channel.type == "DM") return; const prefix = client.config.get(message.guild!.id)?.prefix || PREFIX; if (message.content.startsWith(prefix) || message.author.bot) return; diff --git a/src/features/index.ts b/src/features/index.ts index deb17a5..f968252 100644 --- a/src/features/index.ts +++ b/src/features/index.ts @@ -5,3 +5,4 @@ export { default as polls } from "./polls"; export { default as xp } from "./xp"; export { default as dad } from "./dad"; export { default as quiz } from "./quiz"; +export { default as interaction } from "./interaction"; diff --git a/src/features/interaction.ts b/src/features/interaction.ts new file mode 100644 index 0000000..84b62e2 --- /dev/null +++ b/src/features/interaction.ts @@ -0,0 +1,8 @@ +import { Interaction } from "discord.js"; + +export default async (interaction: Interaction) => { + if (!interaction.isCommand()) return; + + const command = interaction.client.slashCommands.get(interaction.commandName); + return command?.execute(interaction); +}; diff --git a/src/features/music.ts b/src/features/music.ts index c0fa776..b134782 100644 --- a/src/features/music.ts +++ b/src/features/music.ts @@ -15,7 +15,7 @@ export default (music: DisTube) => { }, { name: "Requested by", - value: song.user, + value: song.user.username, }, { name: "Status", @@ -23,7 +23,7 @@ export default (music: DisTube) => { }, ], }); - message.channel.send(embed); + message.channel.send({ embeds: [embed] }); }) .on("addSong", (message, queue, song) => { const embed = new MessageEmbed({ @@ -36,7 +36,7 @@ export default (music: DisTube) => { }, { name: "Requested by", - value: song.user, + value: song.user.username, }, { name: "Status", @@ -44,7 +44,7 @@ export default (music: DisTube) => { }, ], }); - message.channel.send(embed); + message.channel.send({ embeds: [embed] }); }) .on("playList", (message, queue, playlist, song) => { const embed = new MessageEmbed({ @@ -57,7 +57,7 @@ export default (music: DisTube) => { }, { name: "Requested by", - value: song.user, + value: song.user.username, }, { name: "Now playing", @@ -70,7 +70,7 @@ export default (music: DisTube) => { ], }); - message.channel.send(embed); + message.channel.send({ embeds: [embed] }); }) .on("addList", (message, queue, playlist) => { const embed = new MessageEmbed({ @@ -83,7 +83,7 @@ export default (music: DisTube) => { }, { name: "Requested by", - value: playlist.user, + value: playlist.user.username, }, { @@ -93,7 +93,7 @@ export default (music: DisTube) => { ], }); - message.channel.send(embed); + message.channel.send({ embeds: [embed] }); }) .on("error", (message, e) => { @@ -105,10 +105,10 @@ export default (music: DisTube) => { fields: [ { name: "An error encountered", - value: e, + value: e.message, }, ], }); - message.channel.send(embed); + message.channel.send({ embeds: [embed] }); }); }; diff --git a/src/features/polls.ts b/src/features/polls.ts index ccccb5a..5d7d5ef 100644 --- a/src/features/polls.ts +++ b/src/features/polls.ts @@ -4,7 +4,7 @@ import { CHANNELS } from "../lib/contants"; const { PREFIX } = process.env; export default async (client: Client, message: Message) => { - if (message.channel.type == "dm") return; + if (message.channel.type == "DM") return; const prefix = client.config.get(message.guild!.id)?.prefix || PREFIX; if (message.channel.id == CHANNELS.POLLS) { diff --git a/src/features/quiz.ts b/src/features/quiz.ts index a679124..c7b9519 100644 --- a/src/features/quiz.ts +++ b/src/features/quiz.ts @@ -5,30 +5,34 @@ import { embed } from "@/lib/helpers"; const { PREFIX } = process.env; export default async (client: Client, message: Message) => { - if (message.channel.type == "dm") return; + if (message.channel.type == "DM") return; const prefix = client.config.get(message.guild!.id)?.prefix || PREFIX; if (message.content.startsWith(prefix) || message.channel.id != CHANNELS.ANTWOORDEN || message.author.bot) return; const member = await client.users.fetch(USERS.JESSE); - await member.send( - embed({ - description: message.content, - author: { - name: message.author.username, - iconURL: message.author.displayAvatarURL() ?? message.author.defaultAvatarURL, - }, - }) - ); + await member.send({ + embeds: [ + embed({ + description: message.content, + author: { + name: message.author.username, + iconURL: message.author.displayAvatarURL() ?? message.author.defaultAvatarURL, + }, + }), + ], + }); - await message.author.send( - embed({ - title: "Antwoord", - description: message.content, - }) - ); + await message.author.send({ + embeds: [ + embed({ + title: "Antwoord", + description: message.content, + }), + ], + }); await message.reply("Answer successfully submitted! ✅"); - await message.delete({ timeout: 500 }); + await message.delete(); }; diff --git a/src/features/xp.ts b/src/features/xp.ts index 385f8d9..df6797e 100644 --- a/src/features/xp.ts +++ b/src/features/xp.ts @@ -19,13 +19,15 @@ export default async (_: Client, message: Message) => { if (isChad) { if (sent.get(message.author.toString())) return; - await message.channel.send( - embed({ - title: "Congratulations", - description: `You have reached \`42069\` xp\nYou now have one of the biggest dicks in this server! 🍆 \nAs a reward you have been promoted to <@&${ROLES.CHAD}>`, - thumbnail: { url: "https://media.tenor.com/images/111a73396501d1621a54bd26e4db5ed8/tenor.gif" }, - }) - ); + await message.channel.send({ + embeds: [ + embed({ + title: "Congratulations", + description: `You have reached \`42069\` xp\nYou now have one of the biggest dicks in this server! 🍆 \nAs a reward you have been promoted to <@&${ROLES.CHAD}>`, + thumbnail: { url: "https://media.tenor.com/images/111a73396501d1621a54bd26e4db5ed8/tenor.gif" }, + }), + ], + }); giveRole(message.member!, ROLES.CHAD); diff --git a/src/index.ts b/src/index.ts index 37bd133..96c9e38 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,18 +1,19 @@ // Global import "dotenv/config"; import "module-alias/register"; -import "./modules/ExtendedMessage"; +// import "./modules/ExtendedMessage"; // Command and Event classes +import SlashCommand from "./modules/SlashCommand"; import Command from "./modules/Command"; import Event from "./modules/Event"; // Other import consola from "consola"; import DisTube from "distube"; -import { Client, Collection } from "discord.js"; +import { Client, Collection, Intents } from "discord.js"; import { Snipe } from "./typings"; -import { registerCommands, registerEvents } from "./lib/registry"; +import { registerCommands, registerEvents, registerSlashCommands } from "./lib/registry"; import { music } from "./features"; import { createConnection } from "typeorm"; import colors from "colors"; @@ -21,11 +22,21 @@ import { Config } from "./entity/Config"; // Environment variables const { TOKEN } = process.env; +// Register REST client + // Register new discord client -const client = new Client({ partials: ["MESSAGE", "CHANNEL", "REACTION"] }); +const client = new Client({ + intents: [ + Intents.FLAGS.DIRECT_MESSAGES, + Intents.FLAGS.GUILDS, + // Intents.FLAGS.GUILD_MEMBERS, + Intents.FLAGS.GUILD_MESSAGES, + ], +}); // Client properties for easy acces client.commands = new Collection(); +client.slashCommands = new Collection(); client.aliases = new Collection(); client.snipes = new Collection(); client.events = new Collection(); @@ -38,6 +49,7 @@ client.logger = consola; // Register commands and events await registerCommands(client, "../commands"); await registerEvents(client, "../events"); + await registerSlashCommands(client, "../_commands"); // Music handler music(client.music); @@ -52,3 +64,5 @@ client.logger = consola; client.logger.error(error); } })(); + +process.on("uncaughtException", (error) => client.logger.error(error)); diff --git a/src/lib/helpers.ts b/src/lib/helpers.ts index 989b848..5c44b16 100644 --- a/src/lib/helpers.ts +++ b/src/lib/helpers.ts @@ -9,6 +9,7 @@ import { GIFResponse, MemeResponse } from "../typings"; import Command from "../modules/Command"; import { Guild } from "../entity/Guild"; import { Config } from "../entity/Config"; +import { promisify } from "util"; const { API_KEY, REDIS_KEY_PREFIX } = process.env; @@ -189,7 +190,7 @@ export function random(arrOrMin: number | T[], countOrMax?: number, float?: t export async function createGuildConfig(guild: Server) { const newGuild = new Guild({ id: guild.id, - ownerId: guild.ownerID, + ownerId: guild.ownerId, }); await newGuild.save(); @@ -216,3 +217,5 @@ export function isAllowed(command: Command, guildId: string): boolean { return true; } } + +export const wait = promisify(setTimeout); diff --git a/src/lib/read.ts b/src/lib/read.ts index bad881b..a3af83d 100644 --- a/src/lib/read.ts +++ b/src/lib/read.ts @@ -29,6 +29,7 @@ export async function read(dir: string): Promise { // table.addRow(file, "✅"); commands.push(command); } catch (error) { + console.error(error); // table.addRow(file, `❌ - ${error}`); } } diff --git a/src/lib/registry.ts b/src/lib/registry.ts index 6a82fdf..9605429 100644 --- a/src/lib/registry.ts +++ b/src/lib/registry.ts @@ -1,8 +1,15 @@ +import SlashCommand from "@/modules/SlashCommand"; +import { REST } from "@discordjs/rest"; +import { Routes } from "discord-api-types/v9"; import { Client } from "discord.js"; import Command from "../modules/Command"; import Event from "../modules/Event"; import { read } from "./read"; +const { TOKEN, CLIENT_ID, GUILD_ID } = process.env; + +const rest = new REST({ version: "9" }).setToken(TOKEN); + export async function registerCommands(client: Client, dir = "") { const commands = await read(dir); @@ -18,12 +25,28 @@ export async function registerCommands(client: Client, dir = "") { } } +export async function registerSlashCommands(client: Client, dir = "../_commands") { + const slashCommands = await read(dir); + + for (const slashCommand of slashCommands) { + client.slashCommands.set(slashCommand.name, slashCommand); + } + + await rest.put(Routes.applicationGuildCommands(CLIENT_ID!, GUILD_ID!), { + body: slashCommands, + }); +} + export async function registerEvents(client: Client, dir = "") { const events = await read(dir); for (const event of events) { client.events.set(event.name, event); try { - client.on(event.name, event.run.bind(event, client)); + if (event.once) { + client.once(event.name, event.run.bind(event, client)); + } else { + client.on(event.name, event.run.bind(event, client)); + } } catch (error) { client.logger.error(error); } diff --git a/src/modules/Event.ts b/src/modules/Event.ts index 036a279..11c832a 100644 --- a/src/modules/Event.ts +++ b/src/modules/Event.ts @@ -2,6 +2,7 @@ import { Client, ClientEvents } from "discord.js"; export default class Event { public name: keyof ClientEvents; + public once: boolean; run: (client: Client, ...args: any) => Promise; constructor({ name, run }: { name: keyof ClientEvents; run: (client: Client, ...args: any) => Promise }) { diff --git a/src/modules/ExtendedMessage.ts b/src/modules/ExtendedMessage.ts index e3c1597..f8cfd77 100644 --- a/src/modules/ExtendedMessage.ts +++ b/src/modules/ExtendedMessage.ts @@ -1,41 +1,41 @@ -//@ts-ignore -import { APIMessageContentResolvable } from "discord.js"; -import { APIMessage, Structures } from "discord.js"; +// //@ts-ignore +// import { APIMessageContentResolvable } from "discord.js"; +// import { APIMessage, Structures } from "discord.js"; -class ExtAPIMessage extends APIMessage { - resolveData() { - if (this.data) return this; - super.resolveData(); - const allowedMentions = this.options.allowedMentions || this.target.client.options.allowedMentions || {}; - //@ts-ignore - if (allowedMentions.repliedUser !== undefined) { - //@ts-ignore - if (this.data.allowed_mentions === undefined) this.data.allowed_mentions = {}; - //@ts-ignore - Object.assign(this.data.allowed_mentions, { replied_user: allowedMentions.repliedUser }); - } - //@ts-ignore - if (this.options.replyTo !== undefined) { - //@ts-ignore - Object.assign(this.data, { message_reference: { message_id: this.options.replyTo.id } }); - } - return this; - } -} +// class ExtAPIMessage extends APIMessage { +// resolveData() { +// if (this.data) return this; +// super.resolveData(); +// const allowedMentions = this.options.allowedMentions || this.target.client.options.allowedMentions || {}; +// //@ts-ignore +// if (allowedMentions.repliedUser !== undefined) { +// //@ts-ignore +// if (this.data.allowed_mentions === undefined) this.data.allowed_mentions = {}; +// //@ts-ignore +// Object.assign(this.data.allowed_mentions, { replied_user: allowedMentions.repliedUser }); +// } +// //@ts-ignore +// if (this.options.replyTo !== undefined) { +// //@ts-ignore +// Object.assign(this.data, { message_reference: { message_id: this.options.replyTo.id } }); +// } +// return this; +// } +// } -class Message extends Structures.get("Message") { - //@ts-ignore - inlineReply(content: APIMessageContentResolvable, options) { - //@ts-ignore - return this.channel.send(ExtAPIMessage.create(this, content, options, { replyTo: this }).resolveData()); - } +// class Message extends Structures.get("Message") { +// //@ts-ignore +// inlineReply(content: APIMessageContentResolvable, options) { +// //@ts-ignore +// return this.channel.send(ExtAPIMessage.create(this, content, options, { replyTo: this }).resolveData()); +// } - //@ts-ignore - edit(content, options) { - //@ts-ignore - return super.edit(ExtAPIMessage.create(this, content, options).resolveData()); - } -} +// //@ts-ignore +// edit(content, options) { +// //@ts-ignore +// return super.edit(ExtAPIMessage.create(this, content, options).resolveData()); +// } +// } -//@ts-ignore -Structures.extend("Message", () => Message); +// //@ts-ignore +// Structures.extend("Message", () => Message); diff --git a/src/modules/SlashCommand.ts b/src/modules/SlashCommand.ts new file mode 100644 index 0000000..aecb66c --- /dev/null +++ b/src/modules/SlashCommand.ts @@ -0,0 +1,54 @@ +import { ToAPIApplicationCommandOptions } from "@discordjs/builders"; +import { ApplicationCommandOptionType, CommandInteraction } from "discord.js"; +import { ApplicationCommandOptionTypes } from "discord.js/typings/enums"; + +export enum CommandType { + SUB_COMMAND = 1, + SUB_COMMAND_GROUP = 2, + STRING = 3, + INTEGER = 4, + BOOLEAN = 5, + USER = 6, + CHANNEL = 7, + ROLE = 8, + MENTIONABLE = 9, + NUMBER = 10, +} + +interface Option { + type: CommandType; + name: string; + description: string; + required?: boolean; +} + +export default class SlashCommand { + public name: string; + public description: string; + public options: Option[]; + public execute: (interaction: CommandInteraction) => void; + constructor({ + name, + description, + execute, + options, + }: { + name: string; + description: string; + options?: Option[]; + execute: (interaction: CommandInteraction) => void; + }) { + this.name = name; + this.description = description; + this.options = options ?? []; + this.execute = execute; + } + + toJSON() { + return { + name: this.name, + description: this.description, + options: this.options ?? [], + }; + } +} diff --git a/src/typings/client.d.ts b/src/typings/client.d.ts index bcdda3b..3582266 100644 --- a/src/typings/client.d.ts +++ b/src/typings/client.d.ts @@ -1,17 +1,18 @@ +import SlashCommand from "@/modules/SlashCommand"; +import { SlashCommandBuilder } from "@discordjs/builders"; import { Consola } from "consola"; import "discord.js"; +import { Collection } from "discord.js"; import DisTube from "distube"; import { Config } from "../entity/Config"; import Command from "../modules/Command"; import Event from "../modules/Event"; import { Snipe } from "./"; -type Content = APIMessageContentResolvable | (MessageOptions & { split?: false }) | MessageAdditions; -type Options = (MessageOptions & { split?: false }) | MessageAdditions; - declare module "discord.js" { interface Client { commands: Collection; + slashCommands: Collection; aliases: Collection; snipes: Collection; events: Collection; @@ -20,8 +21,4 @@ declare module "discord.js" { music: DisTube; logger: Consola; } - interface Message { - inlineReply(content: Content, options?: Options): Promise; - edit(content: Content, options?: Options): Promise; - } } diff --git a/src/typings/env.d.ts b/src/typings/env.d.ts index b8ace23..1216ba3 100644 --- a/src/typings/env.d.ts +++ b/src/typings/env.d.ts @@ -1,6 +1,7 @@ declare namespace NodeJS { interface ProcessEnv { TOKEN: string; + CLIENT_ID: string; PREFIX: string; PORT: number; API_KEY: string; diff --git a/yarn.lock b/yarn.lock index fac7a5d..50f20aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -303,11 +303,38 @@ http-response-object "^3.0.1" parse-cache-control "^1.0.1" +"@discordjs/builders@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-0.4.0.tgz#bb41573ce4824aa9194a53b52c29c5219b610010" + integrity sha512-EiwLltKph6TSaPJIzJYdzNc1PnA2ZNaaE0t0ODg3ghnpVHqfgd0YX9/srsleYHW2cw1sfIq+kbM+h0etf7GWLA== + dependencies: + "@sindresorhus/is" "^4.0.1" + discord-api-types "^0.22.0" + ow "^0.27.0" + ts-mixer "^6.0.0" + tslib "^2.3.0" + +"@discordjs/builders@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-0.5.0.tgz#646cbea9cc67f68639e6fb70ed1278b26dacdb14" + integrity sha512-HP5y4Rqw68o61Qv4qM5tVmDbWi4mdTFftqIOGRo33SNPpLJ1Ga3KEIR2ibKofkmsoQhEpLmopD1AZDs3cKpHuw== + dependencies: + "@sindresorhus/is" "^4.0.1" + discord-api-types "^0.22.0" + ow "^0.27.0" + ts-mixer "^6.0.0" + tslib "^2.3.0" + "@discordjs/collection@^0.1.6": version "0.1.6" resolved "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz" integrity sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ== +"@discordjs/collection@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.2.1.tgz#ea4bc7b41b7b7b6daa82e439141222ec95c469b2" + integrity sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog== + "@discordjs/form-data@^3.0.1": version "3.0.1" resolved "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz" @@ -341,6 +368,20 @@ "@discordjs/node-pre-gyp" "^0.1.0" node-addon-api "^3.0.2" +"@discordjs/rest@^0.1.0-canary.0": + version "0.1.0-canary.0" + resolved "https://registry.yarnpkg.com/@discordjs/rest/-/rest-0.1.0-canary.0.tgz#666f9a1a0c1f2f5a09a3a79f77aeddaeafbcbcc1" + integrity sha512-d+s//ISYVV+e0w/926wMEeO7vju+Pn11x1JM4tcmVMCHSDgpi6pnFCNAXF1TEdnDcy7xf9tq5cf2pQkb/7ySTQ== + dependencies: + "@discordjs/collection" "^0.1.6" + "@sapphire/async-queue" "^1.1.4" + "@sapphire/snowflake" "^1.3.5" + abort-controller "^3.0.0" + discord-api-types "^0.18.1" + form-data "^4.0.0" + node-fetch "^2.6.1" + tslib "^2.3.0" + "@distube/youtube-dl@^1.0.2": version "1.0.2" resolved "https://registry.npmjs.org/@distube/youtube-dl/-/youtube-dl-1.0.2.tgz" @@ -717,11 +758,26 @@ dependencies: debug "^4.3.1" +"@sapphire/async-queue@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.1.4.tgz#ae431310917a8880961cebe8e59df6ffa40f2957" + integrity sha512-fFrlF/uWpGOX5djw5Mu2Hnnrunao75WGey0sP0J3jnhmrJ5TAPzHYOmytD5iN/+pMxS+f+u/gezqHa9tPhRHEA== + +"@sapphire/snowflake@^1.3.5": + version "1.3.6" + resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-1.3.6.tgz#166e8c5c08d01c861edd7e2edc80b5739741715f" + integrity sha512-QnzuLp+p9D7agynVub/zqlDVriDza9y3STArBhNiNBUgIX8+GL5FpQxstRfw1jDr5jkZUjcuKYAHxjIuXKdJAg== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== +"@sindresorhus/is@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5" + integrity sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g== + "@sinonjs/commons@^1.7.0": version "1.8.1" resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz" @@ -925,6 +981,13 @@ resolved "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz" integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== +"@types/ws@^7.4.7": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "20.2.0" resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz" @@ -1687,7 +1750,7 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" -callsites@^3.0.0: +callsites@^3.0.0, callsites@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== @@ -2357,6 +2420,16 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +discord-api-types@^0.18.1: + version "0.18.1" + resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.18.1.tgz#5d08ed1263236be9c21a22065d0e6b51f790f492" + integrity sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg== + +discord-api-types@^0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.22.0.tgz#34dc57fe8e016e5eaac5e393646cd42a7e1ccc2a" + integrity sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg== + discord-paginationembed@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/discord-paginationembed/-/discord-paginationembed-2.1.0.tgz" @@ -2404,6 +2477,20 @@ discord.js@^12.5.3: tweetnacl "^1.0.3" ws "^7.4.4" +discord.js@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.0.1.tgz#58f009706d1d7587fe9ff6c6c781e4540ae085f9" + integrity sha512-pEODCFfxypBnGEYpSgjkn1jt70raCS1um7Zp0AXEfW1DcR29wISzQ/WeWdnjP5KTXGi0LTtkRiUjOsMgSoukxA== + dependencies: + "@discordjs/builders" "^0.4.0" + "@discordjs/collection" "^0.2.1" + "@discordjs/form-data" "^3.0.1" + "@sapphire/async-queue" "^1.1.4" + "@types/ws" "^7.4.7" + discord-api-types "^0.22.0" + node-fetch "^2.6.1" + ws "^7.5.1" + distube@^2.8.8: version "2.8.8" resolved "https://registry.npmjs.org/distube/-/distube-2.8.8.tgz" @@ -2443,6 +2530,13 @@ dot-prop@^5.2.0: dependencies: is-obj "^2.0.0" +dot-prop@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" + integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== + dependencies: + is-obj "^2.0.0" + dotenv@^8.2.0: version "8.2.0" resolved "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz" @@ -3200,6 +3294,15 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" @@ -3280,6 +3383,14 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +gen-env-types@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/gen-env-types/-/gen-env-types-1.3.0.tgz#9605ece55cdb343eff93f67004fdda9a471e2c27" + integrity sha512-ZpS804j3N8tgTevROYzrmjokZKGIYneOJkHQqJ7GO+L3N8C8Ln/blKSNH46JWnVXXIZlMP7qTGKteAM99xTDWQ== + dependencies: + chalk "^4.0.0" + dotenv "^8.2.0" + gensync@^1.0.0-beta.1: version "1.0.0-beta.2" resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" @@ -4790,6 +4901,11 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + lodash.memoize@4.x: version "4.1.2" resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" @@ -5602,6 +5718,18 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +ow@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/ow/-/ow-0.27.0.tgz#d44da088e8184fa11de64b5813206f9f86ab68d0" + integrity sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ== + dependencies: + "@sindresorhus/is" "^4.0.1" + callsites "^3.1.0" + dot-prop "^6.0.1" + lodash.isequal "^4.5.0" + type-fest "^1.2.1" + vali-date "^1.0.0" + p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz" @@ -7527,6 +7655,11 @@ ts-jest@^26.4.4: semver "7.x" yargs-parser "20.x" +ts-mixer@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.0.tgz#4e631d3a36e3fa9521b973b132e8353bc7267f9f" + integrity sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ== + ts-node-dev@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-1.1.1.tgz" @@ -7590,6 +7723,11 @@ tslib@^2.0.1: resolved "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz" integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== +tslib@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" @@ -7663,6 +7801,11 @@ type-fest@^0.8.1: resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== + type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" @@ -7839,6 +7982,11 @@ v8-to-istanbul@^7.0.0: convert-source-map "^1.6.0" source-map "^0.7.3" +vali-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" + integrity sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY= + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" @@ -8024,6 +8172,11 @@ ws@^7.4.4: resolved "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz" integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g== +ws@^7.5.1: + version "7.5.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" + integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== + ws@~7.2.0: version "7.2.5" resolved "https://registry.npmjs.org/ws/-/ws-7.2.5.tgz" From 1c765e54b0c152bb8db4a4271b52c39fdec7459e Mon Sep 17 00:00:00 2001 From: Joehoel <31251240+Joehoel@users.noreply.github.com> Date: Thu, 12 Aug 2021 22:49:45 +0200 Subject: [PATCH 2/2] fix: :bug: Change JESSE to JOEL --- src/_commands/answer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_commands/answer.ts b/src/_commands/answer.ts index 01e4174..c0f54d2 100644 --- a/src/_commands/answer.ts +++ b/src/_commands/answer.ts @@ -23,7 +23,7 @@ export default new SlashCommand({ interaction.reply({ ephemeral: true, content: answer }); // TODO: Change to USERS.JESSE - const member = await interaction.client.users.fetch(USERS.JOEL); + const member = await interaction.client.users.fetch(USERS.JESSE); // Send answer to Jesse await member.send({