aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIRONM00N <64110067+IRONM00N@users.noreply.github.com>2021-06-14 22:51:48 -0400
committerIRONM00N <64110067+IRONM00N@users.noreply.github.com>2021-06-14 22:51:48 -0400
commitd055e0dbb86ef7fd4ee96a1531b51181e825fb4b (patch)
treee2ed9e956f2d8167e7f225383f9917e66d2a2803 /src
parent335f7c30994fc8c4e787f407dfd4c2de63b400e3 (diff)
downloadtanzanite-d055e0dbb86ef7fd4ee96a1531b51181e825fb4b.tar.gz
tanzanite-d055e0dbb86ef7fd4ee96a1531b51181e825fb4b.tar.bz2
tanzanite-d055e0dbb86ef7fd4ee96a1531b51181e825fb4b.zip
made a few changes
Diffstat (limited to 'src')
-rw-r--r--src/commands/dev/eval.ts213
-rw-r--r--src/commands/dev/reload.ts10
-rw-r--r--src/commands/dev/setLevel.ts13
-rw-r--r--src/commands/info/botInfo.ts13
-rw-r--r--src/commands/info/help.ts14
-rw-r--r--src/commands/info/ping.ts19
-rw-r--r--src/commands/info/pronouns.ts36
-rw-r--r--src/commands/moderation/ban.ts16
-rw-r--r--src/commands/moderation/kick.ts12
-rw-r--r--src/commands/moderation/modlog.ts79
-rw-r--r--src/commands/moderation/role.ts52
-rw-r--r--src/commands/moulberry-bush/capePerms.ts19
-rw-r--r--src/commands/moulberry-bush/giveawayPing.ts19
-rw-r--r--src/commands/moulberry-bush/level.ts10
-rw-r--r--src/commands/moulberry-bush/rule.ts26
-rw-r--r--src/commands/server-config/prefix.ts5
-rw-r--r--src/config/example-options.ts16
-rw-r--r--src/lib/extensions/BushClient.ts37
-rw-r--r--src/lib/extensions/BushCommand.ts1
-rw-r--r--src/lib/extensions/BushCommandHandler.ts15
-rw-r--r--src/lib/extensions/BushInteractionMessage.ts15
-rw-r--r--src/lib/extensions/BushListenerHandler.ts6
-rw-r--r--src/lib/extensions/BushMessage.ts11
-rw-r--r--src/lib/extensions/BushTaskHandler.ts12
-rw-r--r--src/lib/extensions/Util.ts256
-rw-r--r--src/lib/models/Ban.ts9
-rw-r--r--src/lib/utils/Console.ts188
-rw-r--r--src/lib/utils/Logger.ts4
-rw-r--r--src/listeners/commands/commandError.ts10
-rw-r--r--src/listeners/commands/slashCommandError.ts10
30 files changed, 757 insertions, 389 deletions
diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts
index bab5f8e..2f1d45d 100644
--- a/src/commands/dev/eval.ts
+++ b/src/commands/dev/eval.ts
@@ -1,15 +1,16 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
-import { BushCommand } from '../../lib/extensions/BushCommand';
-import { MessageEmbed, Message } from 'discord.js';
-import { inspect, promisify } from 'util';
import { exec } from 'child_process';
+import { Constants } from 'discord-akairo';
+import { Message, MessageEmbed, MessageEmbedOptions, Util } from 'discord.js';
+import { transpile } from 'typescript';
+import { inspect, promisify } from 'util';
+import { BushCommand } from '../../lib/extensions/BushCommand';
const clean = (text) => {
- if (typeof text === 'string')
- return text.replace(/`/g, '`' + String.fromCharCode(8203)).replace(/@/g, '@' + String.fromCharCode(8203));
- else return text;
+ if (typeof text === 'string') {
+ return (text = Util.cleanCodeBlockContent(text));
+ } else return text;
};
-
export default class EvalCommand extends BushCommand {
public constructor() {
super('eval', {
@@ -17,29 +18,54 @@ export default class EvalCommand extends BushCommand {
category: 'dev',
description: {
content: 'Use the command to eval stuff in the bot.',
- usage: 'eval <code> [--silent] [--depth #]',
+ usage: 'eval [--depth #] <code> [--sudo] [--silent] [--delete] [--proto] [--hidden] [--ts]',
examples: ['eval message.guild.name', 'eval this.client.ownerID']
},
args: [
{
- id: 'depth',
- match: 'option',
- type: 'number',
+ id: 'selDepth',
+ match: Constants.ArgumentMatches.OPTION,
+ type: Constants.ArgumentTypes.NUMBER,
flag: '--depth',
default: 0
},
{
+ id: 'sudo',
+ match: Constants.ArgumentMatches.FLAG,
+ flag: '--sudo'
+ },
+ {
+ id: 'deleteMSG',
+ match: Constants.ArgumentMatches.FLAG,
+ flag: '--delete'
+ },
+ {
id: 'silent',
- match: 'flag',
+ match: Constants.ArgumentMatches.FLAG,
flag: '--silent'
},
{
+ id: 'typescript',
+ match: Constants.ArgumentMatches.FLAG,
+ flag: '--ts'
+ },
+ {
+ id: 'hidden',
+ match: Constants.ArgumentMatches.FLAG,
+ flag: '--hidden'
+ },
+ {
+ id: 'showProto',
+ match: Constants.ArgumentMatches.FLAG,
+ flag: '--proto'
+ },
+ {
id: 'code',
- match: 'rest',
- type: 'string',
+ match: Constants.ArgumentMatches.REST,
+ type: Constants.ArgumentTypes.STRING,
prompt: {
start: 'What would you like to eval?',
- retry: 'Invalid code to eval. What would you like to eval?'
+ retry: '{error} Invalid code to eval.'
}
}
],
@@ -48,11 +74,62 @@ export default class EvalCommand extends BushCommand {
});
}
+ private redactCredentials(old: string) {
+ const mapping = {
+ ['token']: 'Token',
+ ['devToken']: 'Dev Token',
+ ['MongoDB']: 'MongoDB URI',
+ ['hypixelApiKey']: 'Hypixel Api Key',
+ ['webhookID']: 'Webhook ID',
+ ['webhookToken']: 'Webhook Token'
+ };
+ return mapping[old] || old;
+ }
+
public async exec(
message: Message,
- { depth, code, silent }: { depth: number; code: string; silent: boolean }
- ): Promise<void> {
+ {
+ selDepth,
+ code: codeArg,
+ sudo,
+ silent,
+ deleteMSG,
+ typescript,
+ hidden,
+ showProto
+ }: {
+ selDepth: number;
+ code: string;
+ sudo: boolean;
+ silent: boolean;
+ deleteMSG: boolean;
+ typescript: boolean;
+ hidden: boolean;
+ showProto: boolean;
+ }
+ ): Promise<unknown> {
+ if (!this.client.config.owners.includes(message.author.id))
+ return await message.channel.send(`${this.client.util.emojis.error} Only my developers can run this command.`);
+ const code: { js?: string | null; ts?: string | null; lang?: 'js' | 'ts' } = {};
+ codeArg = codeArg.replace(/[β€œβ€]/g, '"');
+ codeArg = codeArg.replace(/```/g, '');
+ if (typescript) {
+ code.ts = codeArg;
+ code.js = transpile(codeArg);
+ code.lang = 'ts';
+ } else {
+ code.ts = null;
+ code.js = codeArg;
+ code.lang = 'js';
+ }
+
const embed: MessageEmbed = new MessageEmbed();
+ const bad_phrases: string[] = ['delete', 'destroy'];
+ if (bad_phrases.some((p) => code[code.lang].includes(p)) && !sudo) {
+ return await message.util.send(`${this.client.util.emojis.error} This eval was blocked by smooth brain protectionβ„’.`);
+ }
+ const embeds: (MessageEmbed | MessageEmbedOptions)[] = [new MessageEmbed()];
+ embeds.some((embed) => embed);
try {
let output;
@@ -62,59 +139,85 @@ export default class EvalCommand extends BushCommand {
guild = message.guild,
channel = message.channel,
config = this.client.config,
+ members = message.guild.members,
+ roles = message.guild.roles,
sh = promisify(exec),
models = this.client.db.models,
got = require('got'); // eslint-disable-line @typescript-eslint/no-var-requires
- output = eval(code);
- output = await output;
- if (typeof output !== 'string') output = inspect(output, { depth });
- output = output.replace(new RegExp(this.client.token, 'g'), '[token omitted]');
+ if (code[code.lang].replace(/ /g, '').includes('9+10' || '10+9')) {
+ output = 21;
+ } else {
+ output = eval(code.js);
+ output = await output;
+ }
+ let proto, outputProto;
+ if (showProto) {
+ proto = Object.getPrototypeOf(output);
+ outputProto = clean(inspect(proto, { depth: 1, getters: true, showHidden: true }));
+ }
+ if (typeof output !== 'string')
+ output = inspect(output, { depth: selDepth, showHidden: hidden, getters: true, showProxy: true });
+ for (const credentialName in this.client.config.credentials) {
+ const credential = this.client.config.credentials[credentialName];
+ const newCredential = this.redactCredentials(credentialName);
+ output = output.replace(
+ new RegExp(credential.toString().replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
+ `[${newCredential} Omitted]`
+ );
+ output = output.replace(
+ new RegExp([...credential.toString().replace(/[.*+?^${}()|[\]\\]/g, '\\$&')].reverse().join(''), 'g'),
+ `[${newCredential} Omitted]`
+ );
+ }
+
output = clean(output);
+ const inputJS = clean(code.js);
+
embed
- .setTitle('βœ… Evaled code successfully')
- .addField(
- 'πŸ“₯ Input',
- code.length > 1012
- ? 'Too large to display. Hastebin: ' + (await this.client.util.haste(code))
- : '```js\n' + code + '```'
- )
- .addField(
- 'πŸ“€ Output',
- output.length > 1012
- ? 'Too large to display. Hastebin: ' + (await this.client.util.haste(output))
- : '```js\n' + output + '```'
- )
- .setColor('#66FF00')
- .setFooter(message.author.username, message.author.displayAvatarURL({ dynamic: true }))
+ .setTitle(`${this.client.util.emojis.successFull} Evaled code successfully`)
+ .setColor(this.client.util.colors.success)
+ .setFooter(message.author.tag, message.author.displayAvatarURL({ dynamic: true }))
.setTimestamp();
+ if (code.lang === 'ts') {
+ const inputTS = clean(code.ts);
+ embed
+ .addField('πŸ“₯ Input (typescript)', await this.client.util.codeblock(inputTS, 1024, 'ts'))
+ .addField('πŸ“₯ Input (transpiled javascript)', await this.client.util.codeblock(inputJS, 1024, 'js'));
+ } else {
+ embed.addField('πŸ“₯ Input', await this.client.util.codeblock(inputJS, 1024, 'js'));
+ }
+ embed.addField('πŸ“€ Output', await this.client.util.codeblock(output, 1024, 'js'));
+ if (showProto) embed.addField('βš™οΈ Proto', await this.client.util.codeblock(outputProto, 1024, 'js'));
} catch (e) {
+ const inputJS = clean(code.js);
embed
- .setTitle('❌ Code was not able to be evaled')
- .addField(
- 'πŸ“₯ Input',
- code.length > 1012
- ? 'Too large to display. Hastebin: ' + (await this.client.util.haste(code))
- : '```js\n' + code + '```'
- )
- .addField(
- 'πŸ“€ Output',
- e.length > 1012
- ? 'Too large to display. Hastebin: ' + (await this.client.util.haste(e))
- : '```js\n' + e + '```Full stack:' + (await this.client.util.haste(e.stack))
- )
- .setColor('#FF0000')
- .setFooter(message.author.username, message.author.displayAvatarURL({ dynamic: true }))
+ .setTitle(`${this.client.util.emojis.errorFull} Code was not able to be evaled.`)
+ .setColor(this.client.util.colors.error)
+ .setFooter(message.author.tag, message.author.displayAvatarURL({ dynamic: true }))
.setTimestamp();
+ if (code.lang === 'ts') {
+ const inputTS = clean(code.ts);
+ embed
+ .addField('πŸ“₯ Input (typescript)', await this.client.util.codeblock(inputTS, 1024, 'ts'))
+ .addField('πŸ“₯ Input (transpiled javascript)', await this.client.util.codeblock(inputJS, 1024, 'js'));
+ } else {
+ embed.addField('πŸ“₯ Input', await this.client.util.codeblock(inputJS, 1024, 'js'));
+ }
+ embed.addField('πŸ“€ Output', await this.client.util.codeblock(e?.stack, 1024, 'js'));
}
if (!silent) {
- await message.util.send(embed);
+ await message.util.reply({ embeds: [embed] });
} else {
try {
- await message.author.send(embed);
- await message.react('<a:Check_Mark:790373952760971294>');
+ await message.author.send({ embeds: [embed] });
+ if (!deleteMSG) await message.react(this.client.util.emojis.successFull);
} catch (e) {
- await message.react('❌');
+ if (!deleteMSG) await message.react(this.client.util.emojis.errorFull);
}
}
+
+ if (deleteMSG && message.deletable) {
+ await message.delete();
+ }
}
}
diff --git a/src/commands/dev/reload.ts b/src/commands/dev/reload.ts
index 0cf32ce..3194ce2 100644
--- a/src/commands/dev/reload.ts
+++ b/src/commands/dev/reload.ts
@@ -1,9 +1,9 @@
-import { BushCommand } from '../../lib/extensions/BushCommand';
import { stripIndent } from 'common-tags';
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { Message } from 'discord.js';
-import { CommandInteraction } from 'discord.js';
+import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
import { SlashCommandOption } from '../../lib/extensions/Util';
-import { ApplicationCommandOptionType } from 'discord-api-types';
export default class ReloadCommand extends BushCommand {
constructor() {
@@ -55,7 +55,7 @@ export default class ReloadCommand extends BushCommand {
await message.util.send(await this.getResponse(fast));
}
- public async execSlash(message: CommandInteraction, { fast }: { fast: SlashCommandOption<boolean> }): Promise<void> {
- await message.reply(await this.getResponse(fast?.value));
+ public async execSlash(message: BushInteractionMessage, { fast }: { fast: SlashCommandOption<boolean> }): Promise<void> {
+ await message.interaction.reply(await this.getResponse(fast?.value));
}
}
diff --git a/src/commands/dev/setLevel.ts b/src/commands/dev/setLevel.ts
index e57e2f8..7401699 100644
--- a/src/commands/dev/setLevel.ts
+++ b/src/commands/dev/setLevel.ts
@@ -1,8 +1,7 @@
import { ApplicationCommandOptionType } from 'discord-api-types';
-import { CommandInteraction } from 'discord.js';
-import { User } from 'discord.js';
-import { Message } from 'discord.js';
+import { Message, User } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
import { SlashCommandOption } from '../../lib/extensions/Util';
import { Level } from '../../lib/models';
import AllowedMentions from '../../lib/utils/AllowedMentions';
@@ -68,16 +67,18 @@ export default class SetLevelCommand extends BushCommand {
}
async exec(message: Message, { user, level }: { user: User; level: number }): Promise<void> {
- await message.util.send(await this.setLevel(user, level), {
+ await message.util.send({
+ content: await this.setLevel(user, level),
allowedMentions: AllowedMentions.none()
});
}
async execSlash(
- message: CommandInteraction,
+ message: BushInteractionMessage,
{ user, level }: { user: SlashCommandOption<void>; level: SlashCommandOption<number> }
): Promise<void> {
- await message.reply(await this.setLevel(user.user, level.value), {
+ await message.interaction.reply({
+ content: await this.setLevel(user.user, level.value),
allowedMentions: AllowedMentions.none()
});
}
diff --git a/src/commands/info/botInfo.ts b/src/commands/info/botInfo.ts
index ebbd0c9..66bf5af 100644
--- a/src/commands/info/botInfo.ts
+++ b/src/commands/info/botInfo.ts
@@ -1,6 +1,7 @@
-import { MessageEmbed, Message, CommandInteraction } from 'discord.js';
-import { BushCommand } from '../../lib/extensions/BushCommand';
+import { Message, MessageEmbed } from 'discord.js';
import { duration } from 'moment';
+import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
export default class BotInfoCommand extends BushCommand {
constructor() {
@@ -33,7 +34,7 @@ export default class BotInfoCommand extends BushCommand {
},
{
name: 'User count',
- value: this.client.users.cache.size,
+ value: this.client.users.cache.size.toString(),
inline: true
},
{
@@ -46,10 +47,10 @@ export default class BotInfoCommand extends BushCommand {
}
public async exec(message: Message): Promise<void> {
- await message.util.send(await this.generateEmbed());
+ await message.util.send({ embeds: [await this.generateEmbed()] });
}
- public async execSlash(message: CommandInteraction): Promise<void> {
- await message.reply(await this.generateEmbed());
+ public async execSlash(message: BushInteractionMessage): Promise<void> {
+ await message.interaction.reply({ embeds: [await this.generateEmbed()] });
}
}
diff --git a/src/commands/info/help.ts b/src/commands/info/help.ts
index 0629bf1..317091e 100644
--- a/src/commands/info/help.ts
+++ b/src/commands/info/help.ts
@@ -1,8 +1,8 @@
-import { Message, MessageEmbed } from 'discord.js';
-import { BushCommand } from '../../lib/extensions/BushCommand';
import { stripIndent } from 'common-tags';
import { ApplicationCommandOptionType } from 'discord-api-types';
-import { CommandInteraction } from 'discord.js';
+import { Message, MessageEmbed } from 'discord.js';
+import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
import { SlashCommandOption } from '../../lib/extensions/Util';
export default class HelpCommand extends BushCommand {
@@ -72,14 +72,14 @@ export default class HelpCommand extends BushCommand {
}
public async exec(message: Message, { command }: { command: BushCommand }): Promise<void> {
- await message.util.send(this.generateEmbed(command));
+ await message.util.send({ embeds: [this.generateEmbed(command)] });
}
- public async execSlash(message: CommandInteraction, { command }: { command: SlashCommandOption<string> }): Promise<void> {
+ public async execSlash(message: BushInteractionMessage, { command }: { command: SlashCommandOption<string> }): Promise<void> {
if (command) {
- await message.reply(this.generateEmbed(this.handler.findCommand(command.value) as BushCommand));
+ await message.interaction.reply({ embeds: [this.generateEmbed(this.handler.findCommand(command.value) as BushCommand)] });
} else {
- await message.reply(this.generateEmbed());
+ await message.interaction.reply({ embeds: [this.generateEmbed()] });
}
}
}
diff --git a/src/commands/info/ping.ts b/src/commands/info/ping.ts
index b130e6d..feb48ad 100644
--- a/src/commands/info/ping.ts
+++ b/src/commands/info/ping.ts
@@ -1,7 +1,6 @@
-import { CommandInteraction } from 'discord.js';
-import { Message } from 'discord.js';
-import { MessageEmbed } from 'discord.js';
+import { Message, MessageEmbed } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
export default class PingCommand extends BushCommand {
constructor() {
@@ -29,23 +28,23 @@ export default class PingCommand extends BushCommand {
.setTimestamp();
await sentMessage.edit({
content: null,
- embed
+ embeds: [embed]
});
}
- public async execSlash(message: CommandInteraction): Promise<void> {
- const timestamp1 = message.createdTimestamp;
- await message.reply('Pong!');
- const timestamp2 = await message.fetchReply().then((m) => (m as Message).createdTimestamp);
+ public async execSlash(message: BushInteractionMessage): Promise<void> {
+ const timestamp1 = message.interaction.createdTimestamp;
+ await message.interaction.reply('Pong!');
+ const timestamp2 = await message.interaction.fetchReply().then((m) => (m as Message).createdTimestamp);
const botLatency = `\`\`\`\n ${Math.floor(timestamp2 - timestamp1)}ms \`\`\``;
const apiLatency = `\`\`\`\n ${Math.round(this.client.ws.ping)}ms \`\`\``;
const embed = new MessageEmbed()
.setTitle('Pong! πŸ“')
.addField('Bot Latency', botLatency, true)
.addField('API Latency', apiLatency, true)
- .setFooter(message.user.username, message.user.displayAvatarURL({ dynamic: true }))
+ .setFooter(message.interaction.user.username, message.interaction.user.displayAvatarURL({ dynamic: true }))
.setTimestamp();
- await message.editReply({
+ await message.interaction.editReply({
content: null,
embeds: [embed]
});
diff --git a/src/commands/info/pronouns.ts b/src/commands/info/pronouns.ts
index 740eb68..faf3aa2 100644
--- a/src/commands/info/pronouns.ts
+++ b/src/commands/info/pronouns.ts
@@ -1,8 +1,8 @@
-import { BushCommand } from '../../lib/extensions/BushCommand';
-import { User, Message, MessageEmbed } from 'discord.js';
-import got, { HTTPError } from 'got';
-import { CommandInteraction } from 'discord.js';
import { ApplicationCommandOptionType } from 'discord-api-types';
+import { CommandInteraction, Message, MessageEmbed, User } from 'discord.js';
+import got, { HTTPError } from 'got';
+import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
import { SlashCommandOption } from '../../lib/extensions/Util';
export const pronounMapping = {
@@ -56,7 +56,7 @@ export default class PronounsCommand extends BushCommand {
required: false
}
],
- slashEmphemeral: true // I'll add dynamic checking to this later
+ slashEphemeral: true // I'll add dynamic checking to this later
});
}
async sendResponse(message: Message | CommandInteraction, user: User, author: boolean): Promise<void> {
@@ -65,15 +65,17 @@ export default class PronounsCommand extends BushCommand {
.get(`https://pronoundb.org/api/v1/lookup?platform=discord&id=${user.id}`)
.json();
if (message instanceof Message) {
- message.reply(
- new MessageEmbed({
- title: `${author ? 'Your' : `${user.tag}'s`} pronouns:`,
- description: pronounMapping[apiRes.pronouns],
- footer: {
- text: 'Data provided by https://pronoundb.org/'
- }
- })
- );
+ message.reply({
+ embeds: [
+ new MessageEmbed({
+ title: `${author ? 'Your' : `${user.tag}'s`} pronouns:`,
+ description: pronounMapping[apiRes.pronouns],
+ footer: {
+ text: 'Data provided by https://pronoundb.org/'
+ }
+ })
+ ]
+ });
} else {
message.reply({
embeds: [
@@ -105,8 +107,8 @@ export default class PronounsCommand extends BushCommand {
const u = user || message.author;
await this.sendResponse(message, u, u.id === message.author.id);
}
- async execSlash(message: CommandInteraction, { user }: { user?: SlashCommandOption<void> }): Promise<void> {
- const u = user?.user || message.user;
- await this.sendResponse(message, u, u.id === message.user.id);
+ async execSlash(message: BushInteractionMessage, { user }: { user?: SlashCommandOption<void> }): Promise<void> {
+ const u = user?.user || message.author;
+ await this.sendResponse(message.interaction, u, u.id === message.author.id);
}
}
diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts
index 0d57203..f843ac4 100644
--- a/src/commands/moderation/ban.ts
+++ b/src/commands/moderation/ban.ts
@@ -1,12 +1,10 @@
-import { User } from 'discord.js';
-import { Guild } from '../../lib/models';
-import { BushCommand } from '../../lib/extensions/BushCommand';
-import { Ban, Modlog, ModlogType } from '../../lib/models';
+import { ApplicationCommandOptionType } from 'discord-api-types';
+import { CommandInteraction, Message, User } from 'discord.js';
import moment from 'moment';
-import { Message } from 'discord.js';
-import { CommandInteraction } from 'discord.js';
+import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
import { SlashCommandOption } from '../../lib/extensions/Util';
-import { ApplicationCommandOptionType } from 'discord-api-types';
+import { Ban, Guild, Modlog, ModlogType } from '../../lib/models';
const durationAliases: Record<string, string[]> = {
weeks: ['w', 'weeks', 'week', 'wk', 'wks'],
@@ -170,7 +168,7 @@ export default class BanCommand extends BushCommand {
}
async execSlash(
- message: CommandInteraction,
+ message: BushInteractionMessage,
{
user,
reason,
@@ -181,7 +179,7 @@ export default class BanCommand extends BushCommand {
time: SlashCommandOption<string>;
}
): Promise<void> {
- for await (const response of this.genResponses(message, user.user, reason?.value, time?.value)) {
+ for await (const response of this.genResponses(message.interaction, user.user, reason?.value, time?.value)) {
await message.reply(response);
}
}
diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts
index c5581f6..eed0122 100644
--- a/src/commands/moderation/kick.ts
+++ b/src/commands/moderation/kick.ts
@@ -1,8 +1,8 @@
+import { ApplicationCommandOptionType } from 'discord-api-types';
+import { CommandInteraction, GuildMember, Message } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
import { Guild, Modlog, ModlogType } from '../../lib/models';
-import { GuildMember, Message } from 'discord.js';
-import { ApplicationCommandOptionType } from 'discord-api-types';
-import { CommandInteraction } from 'discord.js';
export default class KickCommand extends BushCommand {
constructor() {
@@ -100,9 +100,9 @@ export default class KickCommand extends BushCommand {
}
}
- async execSlash(message: CommandInteraction, { user, reason }: { user: GuildMember; reason?: string }): Promise<void> {
- for await (const response of this.genResponses(message, user, reason)) {
- await message.reply(response);
+ async execSlash(message: BushInteractionMessage, { user, reason }: { user: GuildMember; reason?: string }): Promise<void> {
+ for await (const response of this.genResponses(message.interaction, user, reason)) {
+ await message.interaction.reply(response);
}
}
}
diff --git a/src/commands/moderation/modlog.ts b/src/commands/moderation/modlog.ts
index 806c00a..862a26d 100644
--- a/src/commands/moderation/modlog.ts
+++ b/src/commands/moderation/modlog.ts
@@ -1,10 +1,9 @@
-import { BushCommand } from '../../lib/extensions/BushCommand';
-import { Message } from 'discord.js';
-import { Modlog } from '../../lib/models';
-import { MessageEmbed } from 'discord.js';
-import moment from 'moment';
import { stripIndent } from 'common-tags';
import { Argument } from 'discord-akairo';
+import { Message, MessageEmbed } from 'discord.js';
+import moment from 'moment';
+import { BushCommand } from '../../lib/extensions/BushCommand';
+import { Modlog } from '../../lib/models';
export default class ModlogCommand extends BushCommand {
constructor() {
@@ -87,10 +86,10 @@ export default class ModlogCommand extends BushCommand {
})
);
if (page) {
- await message.util.send(embedPages[page - 1]);
+ await message.util.send({ embeds: [embedPages[page - 1]] });
return;
} else {
- await message.util.send(embedPages[0]);
+ await message.util.send({ embeds: [embedPages[0]] });
return;
}
} else if (search) {
@@ -99,38 +98,40 @@ export default class ModlogCommand extends BushCommand {
await message.util.send('That modlog does not exist.');
return;
}
- await message.util.send(
- new MessageEmbed({
- title: `Modlog ${entry.id}`,
- fields: [
- {
- name: 'Type',
- value: entry.type.toLowerCase(),
- inline: true
- },
- {
- name: 'Duration',
- value: `${entry.duration ? moment.duration(entry.duration, 'milliseconds').humanize() : 'N/A'}`,
- inline: true
- },
- {
- name: 'Reason',
- value: `${entry.reason || 'None given'}`,
- inline: true
- },
- {
- name: 'Moderator',
- value: `<@!${entry.moderator}> (${entry.moderator})`,
- inline: true
- },
- {
- name: 'User',
- value: `<@!${entry.user}> (${entry.user})`,
- inline: true
- }
- ]
- })
- );
+ await message.util.send({
+ embeds: [
+ new MessageEmbed({
+ title: `Modlog ${entry.id}`,
+ fields: [
+ {
+ name: 'Type',
+ value: entry.type.toLowerCase(),
+ inline: true
+ },
+ {
+ name: 'Duration',
+ value: `${entry.duration ? moment.duration(entry.duration, 'milliseconds').humanize() : 'N/A'}`,
+ inline: true
+ },
+ {
+ name: 'Reason',
+ value: `${entry.reason || 'None given'}`,
+ inline: true
+ },
+ {
+ name: 'Moderator',
+ value: `<@!${entry.moderator}> (${entry.moderator})`,
+ inline: true
+ },
+ {
+ name: 'User',
+ value: `<@!${entry.user}> (${entry.user})`,
+ inline: true
+ }
+ ]
+ })
+ ]
+ });
}
}
}
diff --git a/src/commands/moderation/role.ts b/src/commands/moderation/role.ts
index b01d578..8951560 100644
--- a/src/commands/moderation/role.ts
+++ b/src/commands/moderation/role.ts
@@ -1,8 +1,8 @@
/* eslint-disable @typescript-eslint/no-empty-function */
+import { ApplicationCommandOptionType } from 'discord-api-types';
+import { GuildMember, Message, Role } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
import AllowedMentions from '../../lib/utils/AllowedMentions';
-import { Message, Role, GuildMember } from 'discord.js';
-import { ApplicationCommandOptionType } from 'discord-api-types';
export default class RoleCommand extends BushCommand {
private roleWhitelist: Record<string, string[]> = {
@@ -77,43 +77,39 @@ export default class RoleCommand extends BushCommand {
if (!message.member.permissions.has('MANAGE_ROLES') && !this.client.ownerID.includes(message.author.id)) {
const mappedRole = this.client.util.moulberryBushRoleMap.find((m) => m.id === role.id);
if (!mappedRole || !this.roleWhitelist[mappedRole.name]) {
- return message.util.reply(
- `<:error:837123021016924261> <@&${role.id}> is not whitelisted, and you do not have manage roles permission.`,
- {
- allowedMentions: AllowedMentions.none()
- }
- );
+ return message.util.reply({
+ content: `<:error:837123021016924261> <@&${role.id}> is not whitelisted, and you do not have manage roles permission.`,
+ allowedMentions: AllowedMentions.none()
+ });
}
const allowedRoles = this.roleWhitelist[mappedRole.name].map((r) => {
return this.client.util.moulberryBushRoleMap.find((m) => m.name === r).id;
});
if (!message.member.roles.cache.some((role) => allowedRoles.includes(role.id))) {
- return message.util.reply(
- `<:error:837123021016924261> <@&${role.id}> is whitelisted, but you do not have any of the roles required to manage it.`,
- {
- allowedMentions: AllowedMentions.none()
- }
- );
+ return message.util.reply({
+ content: `<:error:837123021016924261> <@&${role.id}> is whitelisted, but you do not have any of the roles required to manage it.`,
+ allowedMentions: AllowedMentions.none()
+ });
}
}
if (!this.client.ownerID.includes(message.author.id)) {
if (role.comparePositionTo(message.member.roles.highest) >= 0) {
- return message.util.reply(`<:error:837123021016924261> <@&${role.id}> is higher or equal to your highest role.`, {
+ return message.util.reply({
+ content: `<:error:837123021016924261> <@&${role.id}> is higher or equal to your highest role.`,
allowedMentions: AllowedMentions.none()
});
}
if (role.comparePositionTo(message.guild.me.roles.highest) >= 0) {
- return message.util.reply(`<:error:837123021016924261> <@&${role.id}> is higher or equal to my highest role.`, {
+ return message.util.reply({
+ content: `<:error:837123021016924261> <@&${role.id}> is higher or equal to my highest role.`,
allowedMentions: AllowedMentions.none()
});
}
if (role.managed) {
- await message.util.reply(
- `<:error:837123021016924261> <@&${role.id}> is managed by an integration and cannot be managed.`,
- {
- allowedMentions: AllowedMentions.none()
- }
- );
+ await message.util.reply({
+ content: `<:error:837123021016924261> <@&${role.id}> is managed by an integration and cannot be managed.`,
+ allowedMentions: AllowedMentions.none()
+ });
}
}
// No checks if the user has MANAGE_ROLES
@@ -121,22 +117,26 @@ export default class RoleCommand extends BushCommand {
try {
await user.roles.remove(role.id);
} catch {
- return message.util.reply(`<:error:837123021016924261> Could not remove <@&${role.id}> from <@${user.id}>.`, {
+ return message.util.reply({
+ content: `<:error:837123021016924261> Could not remove <@&${role.id}> from <@${user.id}>.`,
allowedMentions: AllowedMentions.none()
});
}
- return message.util.reply(`<:checkmark:837109864101707807> Successfully removed <@&${role.id}> from <@${user.id}>!`, {
+ return message.util.reply({
+ content: `<:checkmark:837109864101707807> Successfully removed <@&${role.id}> from <@${user.id}>!`,
allowedMentions: AllowedMentions.none()
});
} else {
try {
await user.roles.add(role.id);
} catch {
- return message.util.reply(`<:error:837123021016924261> Could not add <@&${role.id}> to <@${user.id}>.`, {
+ return message.util.reply({
+ content: `<:error:837123021016924261> Could not add <@&${role.id}> to <@${user.id}>.`,
allowedMentions: AllowedMentions.none()
});
}
- return message.util.reply(`<:checkmark:837109864101707807> Successfully added <@&${role.id}> to <@${user.id}>!`, {
+ return message.util.reply({
+ content: `<:checkmark:837109864101707807> Successfully added <@&${role.id}> to <@${user.id}>!`,
allowedMentions: AllowedMentions.none()
});
}
diff --git a/src/commands/moulberry-bush/capePerms.ts b/src/commands/moulberry-bush/capePerms.ts
index a0edf8c..7eb90c5 100644
--- a/src/commands/moulberry-bush/capePerms.ts
+++ b/src/commands/moulberry-bush/capePerms.ts
@@ -1,9 +1,8 @@
import { ApplicationCommandOptionType } from 'discord-api-types';
-import { MessageEmbed } from 'discord.js';
-import { CommandInteraction } from 'discord.js';
-import { Message } from 'discord.js';
+import { Message, MessageEmbed } from 'discord.js';
import got from 'got';
import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
import { SlashCommandOption } from '../../lib/extensions/Util';
interface Capeperms {
@@ -75,12 +74,12 @@ export default class CapePermissionsCommand extends BushCommand {
]
});
}
- private async getResponse(user: string): Promise<string | MessageEmbed> {
+ private async getResponse(user: string): Promise<{ content?: string; embeds?: MessageEmbed[] }> {
let capeperms: Capeperms, uuid: string;
try {
uuid = await this.client.util.mcUUID(user);
} catch (e) {
- return `<:error:837123021016924261> \`${user}\` doesn't appear to be a valid username.`;
+ return { content: `<:error:837123021016924261> \`${user}\` doesn't appear to be a valid username.` };
}
try {
@@ -89,19 +88,19 @@ export default class CapePermissionsCommand extends BushCommand {
capeperms = null;
}
if (capeperms == null) {
- return `<:error:837123021016924261> There was an error finding cape perms for \`${user}\`.`;
+ return { content: `<:error:837123021016924261> There was an error finding cape perms for \`${user}\`.` };
} else {
if (capeperms?.perms) {
const foundUser = capeperms.perms.find((u) => u._id === uuid);
- if (foundUser == null) return `<:error:837123021016924261> \`${user}\` does not appear to have any capes.`;
+ if (foundUser == null) return { content: `<:error:837123021016924261> \`${user}\` does not appear to have any capes.` };
const userPerm: string[] = foundUser.perms;
const embed = this.client.util
.createEmbed(this.client.util.colors.default)
.setTitle(`${user}'s Capes`)
.setDescription(userPerm.join('\n'));
- return embed;
+ return { embeds: [embed] };
} else {
- return `<:error:837123021016924261> There was an error finding cape perms for ${user}.`;
+ return { content: `<:error:837123021016924261> There was an error finding cape perms for ${user}.` };
}
}
}
@@ -109,7 +108,7 @@ export default class CapePermissionsCommand extends BushCommand {
await message.reply(await this.getResponse(user));
}
- public async execSlash(message: CommandInteraction, { user }: { user: SlashCommandOption<string> }): Promise<void> {
+ public async execSlash(message: BushInteractionMessage, { user }: { user: SlashCommandOption<string> }): Promise<void> {
await message.reply(await this.getResponse(user.value));
}
}
diff --git a/src/commands/moulberry-bush/giveawayPing.ts b/src/commands/moulberry-bush/giveawayPing.ts
index 34de257..9a03140 100644
--- a/src/commands/moulberry-bush/giveawayPing.ts
+++ b/src/commands/moulberry-bush/giveawayPing.ts
@@ -1,8 +1,6 @@
+import { Message, NewsChannel, TextChannel, WebhookClient } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
import AllowedMentions from '../../lib/utils/AllowedMentions';
-import { Message, WebhookClient } from 'discord.js';
-import { TextChannel } from 'discord.js';
-import { NewsChannel } from 'discord.js';
export default class GiveawayPingCommand extends BushCommand {
constructor() {
@@ -39,13 +37,12 @@ export default class GiveawayPingCommand extends BushCommand {
const webhook = webhooks.first();
webhookClient = new WebhookClient(webhook.id, webhook.token);
}
- return webhookClient.send(
- 'πŸŽ‰ <@&767782793261875210> Giveaway.\n\n<:mad:783046135392239626> Spamming, line breaking, gibberish etc. disqualifies you from winning. We can and will ban you from giveaways. Winners will all be checked and rerolled if needed.',
- {
- username: `${message.member.nickname || message.author.username}`,
- avatarURL: message.author.avatarURL({ dynamic: true }),
- allowedMentions: AllowedMentions.roles()
- }
- );
+ return webhookClient.send({
+ content:
+ 'πŸŽ‰ <@&767782793261875210> Giveaway.\n\n<:mad:783046135392239626> Spamming, line breaking, gibberish etc. disqualifies you from winning. We can and will ban you from giveaways. Winners will all be checked and rerolled if needed.',
+ username: `${message.member.nickname || message.author.username}`,
+ avatarURL: message.author.avatarURL({ dynamic: true }),
+ allowedMentions: AllowedMentions.roles()
+ });
}
}
diff --git a/src/commands/moulberry-bush/level.ts b/src/commands/moulberry-bush/level.ts
index 0375fd8..f53aa64 100644
--- a/src/commands/moulberry-bush/level.ts
+++ b/src/commands/moulberry-bush/level.ts
@@ -1,9 +1,7 @@
import { ApplicationCommandOptionType } from 'discord-api-types';
-import { Message } from 'discord.js';
-import { CommandInteractionOption } from 'discord.js';
-import { CommandInteraction } from 'discord.js';
-import { User } from 'discord.js';
+import { CommandInteractionOption, Message, User } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
import { Level } from '../../lib/models';
/*
import canvas from 'canvas';
@@ -150,13 +148,13 @@ export default class LevelCommand extends BushCommand {
// );
await message.reply(await this.getResponse(user || message.author));
}
- async execSlash(message: CommandInteraction, { user }: { user?: CommandInteractionOption }): Promise<void> {
+ async execSlash(message: BushInteractionMessage, { user }: { user?: CommandInteractionOption }): Promise<void> {
// await message.reply(
// new MessageAttachment(
// await this.getImage(user?.user || message.user),
// 'lel.png'
// )
// );
- await message.reply(await this.getResponse(user?.user || message.user));
+ await message.reply(await this.getResponse(user?.user || message.author));
}
}
diff --git a/src/commands/moulberry-bush/rule.ts b/src/commands/moulberry-bush/rule.ts
index ba4f9e6..b71b42f 100644
--- a/src/commands/moulberry-bush/rule.ts
+++ b/src/commands/moulberry-bush/rule.ts
@@ -1,8 +1,8 @@
import { Argument } from 'discord-akairo';
-import { Message, MessageEmbed, User } from 'discord.js';
-import { BushCommand } from '../../lib/extensions/BushCommand';
import { ApplicationCommandOptionType } from 'discord-api-types';
-import { CommandInteraction } from 'discord.js';
+import { CommandInteraction, Message, MessageEmbed, User } from 'discord.js';
+import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
import { SlashCommandOption } from '../../lib/extensions/Util';
export default class RuleCommand extends BushCommand {
@@ -118,12 +118,12 @@ export default class RuleCommand extends BushCommand {
message: Message | CommandInteraction,
rule?: number,
user?: User
- ): string | MessageEmbed | [string, MessageEmbed] {
+ ): { content?: string; embeds?: MessageEmbed[] } | [string, MessageEmbed] {
if (
message.guild.id !== '516977525906341928' &&
!this.client.ownerID.includes(message instanceof Message ? message.author.id : message.user.id)
) {
- return "<:no:787549684196704257> This command can only be run in Moulberry's Bush.";
+ return { content: "<:no:787549684196704257> This command can only be run in Moulberry's Bush." };
}
let rulesEmbed = new MessageEmbed().setColor('ef3929');
if (message instanceof Message) {
@@ -138,7 +138,7 @@ export default class RuleCommand extends BushCommand {
}
}
if (!user) {
- return rulesEmbed;
+ return { embeds: [rulesEmbed] };
} else {
return [`<@!${user.id}>`, rulesEmbed];
}
@@ -146,8 +146,9 @@ export default class RuleCommand extends BushCommand {
public async exec(message: Message, { rule, user }: { rule?: number; user?: User }): Promise<void> {
const response = this.getResponse(message, rule, user);
if (Array.isArray(response)) {
- await message.util.send(response[0], {
- embed: response[1]
+ await message.util.send({
+ content: response[0],
+ embeds: [response[1]]
});
} else {
await message.util.send(response);
@@ -156,16 +157,17 @@ export default class RuleCommand extends BushCommand {
}
public async execSlash(
- message: CommandInteraction,
+ message: BushInteractionMessage,
{ rule, user }: { rule?: SlashCommandOption<number>; user?: SlashCommandOption<void> }
): Promise<void> {
- const response = this.getResponse(message, rule?.value, user?.user);
+ const response = this.getResponse(message.interaction, rule?.value, user?.user);
if (Array.isArray(response)) {
- await message.reply(response[0], {
+ await message.interaction.reply({
+ content: response[0],
embeds: [response[1]]
});
} else {
- await message.reply(response);
+ await message.interaction.reply(response);
}
}
}
diff --git a/src/commands/server-config/prefix.ts b/src/commands/server-config/prefix.ts
index c60f8fb..9cdc331 100644
--- a/src/commands/server-config/prefix.ts
+++ b/src/commands/server-config/prefix.ts
@@ -1,6 +1,7 @@
import { ApplicationCommandOptionType } from 'discord-api-types';
-import { CommandInteraction, Message, Guild as DiscordGuild } from 'discord.js';
+import { Guild as DiscordGuild, Message } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushInteractionMessage } from '../../lib/extensions/BushInteractionMessage';
import { SlashCommandOption } from '../../lib/extensions/Util';
import { Guild } from '../../lib/models';
@@ -57,7 +58,7 @@ export default class PrefixCommand extends BushCommand {
}
}
- async execSlash(message: CommandInteraction, { prefix }: { prefix?: SlashCommandOption<string> }): Promise<void> {
+ async execSlash(message: BushInteractionMessage, { prefix }: { prefix?: SlashCommandOption<string> }): Promise<void> {
await this.changePrefix(message.guild, prefix?.value);
if (prefix) {
await message.reply(`Sucessfully set prefix to \`${prefix.value}\``);
diff --git a/src/config/example-options.ts b/src/config/example-options.ts
index ebd8c21..a00ba42 100644
--- a/src/config/example-options.ts
+++ b/src/config/example-options.ts
@@ -1,22 +1,24 @@
+import { Snowflake } from 'discord.js';
+
// Credentials
export const credentials = {
botToken: 'token here'
};
// Options
-export const owners = [
+export const owners: Snowflake[] = [
'322862723090219008', //IRONM00N
'464970779944157204', //TrashCan
'487443883127472129' //Tyman
];
export const prefix = '-' as string;
export const dev = true as boolean;
-export const devGuild = '695310188764332072' as string;
-export const channels = {
- log: 'id here',
- error: 'id here',
- dm: 'id here',
- command: 'id here'
+export const devGuild = '1000000000000000' as Snowflake;
+export const channels: { log: Snowflake; error: Snowflake; dm: Snowflake; command: Snowflake } = {
+ log: '1000000000000000',
+ error: '1000000000000000',
+ dm: '1000000000000000',
+ command: '1000000000000000'
};
// Database specific
diff --git a/src/lib/extensions/BushClient.ts b/src/lib/extensions/BushClient.ts
index 8a0fc8c..e2e889b 100644
--- a/src/lib/extensions/BushClient.ts
+++ b/src/lib/extensions/BushClient.ts
@@ -1,14 +1,15 @@
-import { AkairoClient, CommandHandler, InhibitorHandler, ListenerHandler, TaskHandler } from 'discord-akairo';
-import { Guild } from 'discord.js';
+import chalk from 'chalk';
+import { AkairoClient, InhibitorHandler, ListenerHandler, TaskHandler } from 'discord-akairo';
+import { Guild, Intents, Snowflake } from 'discord.js';
import * as path from 'path';
-import { Sequelize } from 'sequelize';
-import * as Models from '../models';
-import { Util } from './Util';
import { exit } from 'process';
-import { Intents } from 'discord.js';
+import { Sequelize } from 'sequelize';
import * as config from '../../config/options';
-import { Logger } from '../utils/Logger';
-import chalk from 'chalk';
+import * as Models from '../models';
+import AllowedMentions from '../utils/AllowedMentions';
+import { BushLogger } from '../utils/Logger';
+import { BushCommandHandler } from './BushCommandHandler';
+import { BushUtil } from './Util';
export type BotConfig = typeof config;
@@ -16,21 +17,21 @@ export class BushClient extends AkairoClient {
public config: BotConfig;
public listenerHandler: ListenerHandler;
public inhibitorHandler: InhibitorHandler;
- public commandHandler: CommandHandler;
+ public commandHandler: BushCommandHandler;
public taskHandler: TaskHandler;
- public util: Util;
- public ownerID: string[];
+ public util: BushUtil;
+ public ownerID: Snowflake[];
public db: Sequelize;
- public logger: Logger;
+ public logger: BushLogger;
constructor(config: BotConfig) {
super(
{
ownerID: config.owners,
- intents: Intents.NON_PRIVILEGED
+ intents: Intents.ALL
},
{
- allowedMentions: { parse: ['users'] }, // No everyone or role mentions by default
- intents: Intents.NON_PRIVILEGED
+ allowedMentions: AllowedMentions.users(), // No everyone or role mentions by default
+ intents: Intents.ALL
}
);
@@ -58,7 +59,7 @@ export class BushClient extends AkairoClient {
});
// Create command handler
- this.commandHandler = new CommandHandler(this, {
+ this.commandHandler = new BushCommandHandler(this, {
directory: path.join(__dirname, '..', '..', 'commands'),
prefix: async ({ guild }: { guild: Guild }) => {
const row = await Models.Guild.findByPk(guild.id);
@@ -82,14 +83,14 @@ export class BushClient extends AkairoClient {
automateCategories: true
});
- this.util = new Util(this);
+ this.util = new BushUtil(this);
this.db = new Sequelize(this.config.dev ? 'bushbot-dev' : 'bushbot', this.config.db.username, this.config.db.password, {
dialect: 'postgres',
host: this.config.db.host,
port: this.config.db.port,
logging: false
});
- this.logger = new Logger(this);
+ this.logger = new BushLogger(this);
}
// Initialize everything
diff --git a/src/lib/extensions/BushCommand.ts b/src/lib/extensions/BushCommand.ts
index 4f9dc6e..2b34c69 100644
--- a/src/lib/extensions/BushCommand.ts
+++ b/src/lib/extensions/BushCommand.ts
@@ -13,6 +13,7 @@ export interface BushCommandOptions extends CommandOptions {
export class BushCommand extends Command {
public client: BushClient;
+ options: BushCommandOptions;
constructor(id: string, options?: BushCommandOptions) {
super(id, options);
this.options = options;
diff --git a/src/lib/extensions/BushCommandHandler.ts b/src/lib/extensions/BushCommandHandler.ts
new file mode 100644
index 0000000..6ef44d7
--- /dev/null
+++ b/src/lib/extensions/BushCommandHandler.ts
@@ -0,0 +1,15 @@
+import { CommandHandler, CommandHandlerOptions } from 'discord-akairo';
+import { Collection } from 'discord.js';
+import { BushClient } from './BushClient';
+import { BushCommand } from './BushCommand';
+
+export interface BushCommandHandlerOptions extends CommandHandlerOptions {}
+
+export class BushCommandHandler extends CommandHandler {
+ public constructor(client: BushClient, options: BushCommandHandlerOptions) {
+ super(client, options);
+ this.client = client;
+ }
+
+ declare modules: Collection<string, BushCommand>;
+}
diff --git a/src/lib/extensions/BushInteractionMessage.ts b/src/lib/extensions/BushInteractionMessage.ts
new file mode 100644
index 0000000..9bdc291
--- /dev/null
+++ b/src/lib/extensions/BushInteractionMessage.ts
@@ -0,0 +1,15 @@
+import { AkairoMessage } from 'discord-akairo';
+import { CommandInteraction } from 'discord.js';
+import { BushClient } from './BushClient';
+
+export class BushInteractionMessage extends AkairoMessage {
+ public constructor(
+ client: BushClient,
+ interaction: CommandInteraction,
+ { slash, replied }: { slash?: boolean; replied?: boolean }
+ ) {
+ super(client, interaction, { slash, replied });
+ this.client = client;
+ this.interaction = interaction;
+ }
+}
diff --git a/src/lib/extensions/BushListenerHandler.ts b/src/lib/extensions/BushListenerHandler.ts
new file mode 100644
index 0000000..28615fc
--- /dev/null
+++ b/src/lib/extensions/BushListenerHandler.ts
@@ -0,0 +1,6 @@
+import { ListenerHandler } from 'discord-akairo';
+import { BushClient } from './BushClient';
+
+export class BushListenerHandler extends ListenerHandler {
+ declare client: BushClient;
+}
diff --git a/src/lib/extensions/BushMessage.ts b/src/lib/extensions/BushMessage.ts
new file mode 100644
index 0000000..e7146f6
--- /dev/null
+++ b/src/lib/extensions/BushMessage.ts
@@ -0,0 +1,11 @@
+import { DMChannel, Message, NewsChannel, TextChannel } from 'discord.js';
+import { BushClient } from './BushClient';
+
+export class BushMessage extends Message {
+ declare client: BushClient;
+ constructor(client: BushClient, data: unknown, channel: TextChannel | DMChannel | NewsChannel) {
+ super(client, data, channel);
+ this.client = client;
+ this.channel = channel;
+ }
+}
diff --git a/src/lib/extensions/BushTaskHandler.ts b/src/lib/extensions/BushTaskHandler.ts
new file mode 100644
index 0000000..f783eb3
--- /dev/null
+++ b/src/lib/extensions/BushTaskHandler.ts
@@ -0,0 +1,12 @@
+import { AkairoHandlerOptions, TaskHandler } from 'discord-akairo';
+import { BushClient } from './BushClient';
+
+export interface BushTaskHandlerOptions extends AkairoHandlerOptions {}
+
+export class BushTaskHandler extends TaskHandler {
+ public constructor(client: BushClient, options: BushTaskHandlerOptions) {
+ super(client, options);
+ this.client;
+ }
+ declare client: BushClient;
+}
diff --git a/src/lib/extensions/Util.ts b/src/lib/extensions/Util.ts
index 78fba12..3913437 100644
--- a/src/lib/extensions/Util.ts
+++ b/src/lib/extensions/Util.ts
@@ -1,20 +1,33 @@
-import { ClientUtil } from 'discord-akairo';
-import { BushClient } from './BushClient';
-import { promisify } from 'util';
+import chalk from 'chalk';
import { exec } from 'child_process';
-import got from 'got';
-import { MessageEmbed, GuildMember, User } from 'discord.js';
-import { CommandInteractionOption } from 'discord.js';
+import { ClientUtil, Command } from 'discord-akairo';
import {
- ApplicationCommandOptionType,
- APIInteractionDataResolvedGuildMember,
APIInteractionDataResolvedChannel,
- APIRole
+ APIInteractionDataResolvedGuildMember,
+ APIRole,
+ ApplicationCommandOptionType
} from 'discord-api-types';
-import { GuildChannel } from 'discord.js';
-import { Role } from 'discord.js';
-import chalk from 'chalk';
-import { Guild } from 'discord.js';
+import {
+ ButtonInteraction,
+ CommandInteractionOption,
+ Constants,
+ Guild,
+ GuildChannel,
+ GuildMember,
+ MessageActionRow,
+ MessageButton,
+ MessageComponentInteraction,
+ MessageEmbed,
+ MessageOptions,
+ Role,
+ Snowflake,
+ User,
+ Util
+} from 'discord.js';
+import got from 'got';
+import { promisify } from 'util';
+import { BushClient } from './BushClient';
+import { BushMessage } from './BushMessage';
interface hastebinRes {
key: string;
@@ -23,11 +36,7 @@ interface hastebinRes {
export interface uuidRes {
uuid: string;
username: string;
- username_history?:
- | {
- username: string;
- }[]
- | null;
+ username_history?: { username: string }[] | null;
textures: {
custom: boolean;
slim: boolean;
@@ -54,7 +63,7 @@ export interface SlashCommandOption<T> {
role?: Role | APIRole;
}
-export class Util extends ClientUtil {
+export class BushUtil extends ClientUtil {
/**
* The client of this ClientUtil
* @type {BushClient}
@@ -92,7 +101,7 @@ export class Util extends ClientUtil {
* @param ids The list of IDs to map
* @returns The list of users mapped
*/
- public async mapIDs(ids: string[]): Promise<User[]> {
+ public async mapIDs(ids: Snowflake[]): Promise<User[]> {
return await Promise.all(ids.map((id) => this.client.users.fetch(id)));
}
@@ -144,7 +153,7 @@ export class Util extends ClientUtil {
const idMatch = text.match(idReg);
if (idMatch) {
try {
- const user = await this.client.users.fetch(text);
+ const user = await this.client.users.fetch(text as Snowflake);
return user;
} catch {
// pass
@@ -154,7 +163,7 @@ export class Util extends ClientUtil {
const mentionMatch = text.match(mentionReg);
if (mentionMatch) {
try {
- const user = await this.client.users.fetch(mentionMatch.groups.id);
+ const user = await this.client.users.fetch(mentionMatch.groups.id as Snowflake);
return user;
} catch {
// pass
@@ -195,24 +204,37 @@ export class Util extends ClientUtil {
*/
public colors = {
default: '#1FD8F1',
- error: '#ff0000',
- success: '#00ff02',
+ error: '#EF4947',
+ warn: '#FEBA12',
+ success: '#3BB681',
red: '#ff0000',
- blue: '#0055ff',
+ orange: '#E86100',
+ gold: '#b59400',
+ yellow: '#ffff00',
+ green: '#00ff1e',
+ darkGreen: '#008f11',
aqua: '#00bbff',
- purple: '#8400ff',
+ blue: '#0055ff',
blurple: '#5440cd',
+ purple: '#8400ff',
pink: '#ff00e6',
- green: '#00ff1e',
- darkgreen: '#008f11',
- gold: '#b59400',
- yellow: '#ffff00',
white: '#ffffff',
gray: '#a6a6a6',
- lightgray: '#cfcfcf',
- darkgray: '#7a7a7a',
- black: '#000000',
- orange: '#E86100'
+ lightGray: '#cfcfcf',
+ darkGray: '#7a7a7a',
+ black: '#000000'
+ };
+
+ public emojis = {
+ success: '<:checkmark:837109864101707807>',
+ warn: '<:warn:848726900876247050> ',
+ error: '<:error:837123021016924261>',
+ successFull: '<:checkmark_full:850118767576088646>',
+ warnFull: '<:warn_full:850118767391539312>',
+ errorFull: '<:error_full:850118767295201350>',
+ mad: '<:mad:783046135392239626>',
+ join: '<:join:850198029809614858>',
+ leave: '<:leave:850198048205307919>'
};
/**
@@ -238,7 +260,7 @@ export class Util extends ClientUtil {
return apiRes.uuid.replace(/-/g, '');
}
- public async syncSlashCommands(force = false, guild?: string): Promise<void> {
+ public async syncSlashCommands(force = false, guild?: Snowflake): Promise<void> {
let fetchedGuild: Guild;
if (guild) fetchedGuild = this.client.guilds.cache.get(guild);
try {
@@ -260,7 +282,7 @@ export class Util extends ClientUtil {
for (const [, botCommand] of this.client.commandHandler.modules) {
if (botCommand.execSlash) {
const found = registered.find((i) => i.name == botCommand.id);
-
+ Command;
const slashdata = {
name: botCommand.id,
description: botCommand.description.content,
@@ -332,6 +354,168 @@ export class Util extends ClientUtil {
{ name: 'No Giveaways', id: '808265422334984203' },
{ name: 'No Support', id: '790247359824396319' }
];
+
+ private paginateEmojis = {
+ begging: '853667381335162910',
+ back: '853667410203770881',
+ stop: '853667471110570034',
+ forward: '853667492680564747',
+ end: '853667514915225640'
+ };
+
+ public async buttonPaginate(
+ message: BushMessage,
+ embeds: MessageEmbed[],
+ text: string | null = null,
+ deleteOnExit?: boolean
+ ): Promise<void> {
+ if (deleteOnExit === undefined) deleteOnExit = true;
+ embeds.forEach((_e, i) => {
+ embeds[i] = embeds[i].setFooter(`Page ${i + 1}/${embeds.length}`);
+ });
+
+ const style = Constants.MessageButtonStyles.PRIMARY;
+ let curPage = 0;
+ if (typeof embeds !== 'object') throw 'embeds must be an object';
+ const msg = await message.util.reply({ content: text, embeds: [embeds[curPage]], components: [getPaginationRow()] });
+ const filter = (interaction: ButtonInteraction) =>
+ interaction.customID.startsWith('paginate_') && interaction.message == msg;
+ const collector = msg.createMessageComponentInteractionCollector(filter, { time: 300000 });
+ collector.on('collect', async (interaction: MessageComponentInteraction) => {
+ if (interaction.user.id == message.author.id || message.client.config.owners.includes(interaction.user.id)) {
+ switch (interaction.customID) {
+ case 'paginate_beginning': {
+ curPage = 0;
+ await edit(interaction);
+ break;
+ }
+ case 'paginate_back': {
+ curPage--;
+ await edit(interaction);
+ break;
+ }
+ case 'paginate_stop': {
+ if (deleteOnExit) {
+ await interaction.deferUpdate();
+ await msg.delete();
+ } else {
+ await interaction?.update({
+ content: `${text ? text + '\n' : ''}Command closed by user.`,
+ embeds: [],
+ components: []
+ });
+ }
+ return;
+ }
+ case 'paginate_next': {
+ curPage++;
+ await edit(interaction);
+ break;
+ }
+ case 'paginate_end': {
+ curPage = embeds.length - 1;
+ await edit(interaction);
+ break;
+ }
+ }
+ } else {
+ return await interaction?.deferUpdate();
+ }
+ });
+
+ collector.on('end', async () => {
+ await msg.edit({ content: text, embeds: [embeds[curPage]], components: [getPaginationRow(true)] }).catch(() => {});
+ });
+
+ async function edit(interaction: MessageComponentInteraction): Promise<void> {
+ return await interaction?.update({ content: text, embeds: [embeds[curPage]], components: [getPaginationRow()] });
+ }
+ function getPaginationRow(disableAll = false): MessageActionRow {
+ return new MessageActionRow().addComponents(
+ new MessageButton({
+ style,
+ customID: 'paginate_beginning',
+ emoji: this.paginateEmojis.begging,
+ disabled: disableAll || curPage == 0
+ }),
+ new MessageButton({
+ style,
+ customID: 'paginate_back',
+ emoji: this.paginateEmojis.back,
+ disabled: disableAll || curPage == 0
+ }),
+ new MessageButton({ style, customID: 'paginate_stop', emoji: this.paginateEmojis.stop, disabled: disableAll }),
+ new MessageButton({
+ style,
+ customID: 'paginate_next',
+ emoji: this.paginateEmojis.forward,
+ disabled: disableAll || curPage == embeds.length - 1
+ }),
+ new MessageButton({
+ style,
+ customID: 'paginate_end',
+ emoji: this.paginateEmojis.end,
+ disabled: disableAll || curPage == embeds.length - 1
+ })
+ );
+ }
+ }
+
+ public async sendWithDeleteButton(message: BushMessage, options: MessageOptions): Promise<void> {
+ updateOptions();
+ const msg = await message.util.reply(options as MessageOptions & { split?: false });
+ const filter = (interaction: ButtonInteraction) => interaction.customID == 'paginate__stop' && interaction.message == msg;
+ const collector = msg.createMessageComponentInteractionCollector(filter, { time: 300000 });
+ collector.on('collect', async (interaction: MessageComponentInteraction) => {
+ if (interaction.user.id == message.author.id || message.client.config.owners.includes(interaction.user.id)) {
+ await interaction.deferUpdate();
+ await msg.delete();
+ return;
+ } else {
+ return await interaction?.deferUpdate();
+ }
+ });
+
+ collector.on('end', async () => {
+ updateOptions(true, true);
+ await msg.edit(options);
+ });
+
+ function updateOptions(edit?: boolean, disable?: boolean) {
+ if (edit == undefined) edit = false;
+ if (disable == undefined) disable = false;
+ options.components = [
+ new MessageActionRow().addComponents(
+ new MessageButton({
+ style: Constants.MessageButtonStyles.PRIMARY,
+ customID: 'paginate__stop',
+ emoji: this.paginateEmojis.stop,
+ disabled: disable
+ })
+ )
+ ];
+ if (edit) {
+ options.reply = undefined;
+ }
+ }
+ }
+ /**
+ * Surrounds text in a code block with the specified language and puts it in a haste bin if it too long.
+ *
+ * * Embed Description Limit = 2048 characters
+ * * Embed Field Limit = 1024 characters
+ */
+ public async codeblock(code: string, length: number, language: 'ts' | 'js' | 'sh' | 'json' | '' = ''): Promise<string> {
+ let hasteOut = '';
+ const tildes = '```';
+ const formattingLength = 2 * tildes.length + language.length + 2 * '\n'.length;
+ if (code.length + formattingLength > length) hasteOut = 'Too large to display. Hastebin: ' + (await this.haste(code));
+
+ const code2 = code.length > length ? code.substring(0, length - (hasteOut.length + '\n'.length + formattingLength)) : code;
+ return (
+ tildes + language + '\n' + Util.cleanCodeBlockContent(code2) + '\n' + tildes + (hasteOut.length ? '\n' + hasteOut : '')
+ );
+ }
}
// I just copy pasted this code from stackoverflow don't yell at me if there is issues for it
diff --git a/src/lib/models/Ban.ts b/src/lib/models/Ban.ts
index 66c1be9..8ba55ec 100644
--- a/src/lib/models/Ban.ts
+++ b/src/lib/models/Ban.ts
@@ -1,7 +1,8 @@
+import { Snowflake } from 'discord.js';
import { DataTypes, Sequelize } from 'sequelize';
-import { BaseModel } from './BaseModel';
-import * as Models from './';
import { v4 as uuidv4 } from 'uuid';
+import * as Models from './';
+import { BaseModel } from './BaseModel';
export interface BanModel {
id: string;
@@ -28,11 +29,11 @@ export class Ban extends BaseModel<BanModel, BanModelCreationAttributes> impleme
/**
* The user who is banned
*/
- user: string;
+ user: Snowflake;
/**
* The guild they are banned from
*/
- guild: string;
+ guild: Snowflake;
/**
* The reason they are banned (optional)
*/
diff --git a/src/lib/utils/Console.ts b/src/lib/utils/Console.ts
index b74ea07..a3bf326 100644
--- a/src/lib/utils/Console.ts
+++ b/src/lib/utils/Console.ts
@@ -1,93 +1,115 @@
-// import chalk from 'chalk';
-// import { BushClient } from '../extensions/BushClient';
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
+import chalk from 'chalk';
+import { BushClient } from '../extensions/BushClient';
-// export class CustomConsole {
-// private client: BushClient;
-// public constructor(client: BushClient) {
-// this.client = client;
-// }
+export class Log {
+ client: BushClient;
-// private parseColors(content: any, color: 'blueBright' | 'blackBright' | 'redBright' | 'yellowBright' | 'greenBright'): string | any {
-// if (typeof content === 'string') {
-// const newContent: Array<string> = content.split(/<<|>>/);
-// const tempParsedArray: Array<string> = [];
-// newContent.forEach((value, index) => {
-// if (index % 2 !== 0) {
-// tempParsedArray.push(chalk[color](value));
-// } else {
-// tempParsedArray.push(value);
-// }
-// });
-// return tempParsedArray.join('');
-// } else {
-// return content;
-// }
-// }
+ public constructor(client: BushClient) {
+ this.client = client;
+ }
-// private timeStamp(): string {
-// const now = new Date();
-// const hours = now.getHours();
-// const minute = now.getMinutes();
-// let hour = hours;
-// let amOrPm: 'AM' | 'PM' = 'AM';
-// if (hour > 12) {
-// amOrPm = 'PM';
-// hour = hour - 12;
-// }
+ private parseColors(
+ content: any,
+ color: 'blueBright' | 'blackBright' | 'redBright' | 'yellowBright' | 'greenBright'
+ ): string | any {
+ if (typeof content === 'string') {
+ const newContent: Array<string> = content.split(/<<|>>/);
+ const tempParsedArray: Array<string> = [];
+ newContent.forEach((value, index) => {
+ if (index % 2 !== 0) {
+ tempParsedArray.push(chalk[color](value));
+ } else {
+ tempParsedArray.push(value);
+ }
+ });
+ return tempParsedArray.join('');
+ } else {
+ return content;
+ }
+ }
-// return `${hour >= 10 ? hour : `0${hour}`}:${minute >= 10 ? minute : `0${minute}`} ${amOrPm}`;
-// }
+ private timeStamp(): string {
+ const now = new Date();
+ const hours = now.getHours();
+ const minute = now.getMinutes();
+ let hour = hours;
+ let amOrPm: 'AM' | 'PM' = 'AM';
+ if (hour > 12) {
+ amOrPm = 'PM';
+ hour = hour - 12;
+ }
-// /**
-// * Logs debug information.
-// * @param content - The content to log.
-// */
-// public debug(content: any): void {
-// console.log(`${chalk.bgGrey(this.timeStamp())} ${chalk.grey('[Debug]')}`, content);
-// }
+ return `${hour >= 10 ? hour : `0${hour}`}:${minute >= 10 ? minute : `0${minute}`} ${amOrPm}`;
+ }
-// /**
-// * Logs verbose information. Highlight information by surrounding it in `<<>>`.
-// * @param header - The header displayed before the content, displayed in grey.
-// * @param content - The content to log, highlights displayed in bright black.
-// */
-// public verbose(header: string, content: string): void {
-// return console.info(`${chalk.bgGrey(this.timeStamp())} ${chalk.grey(`[${header}]`)} ` + this.parseColors(content, 'blackBright'));
-// }
+ /**
+ * Logs debug information. Only works in dev is enabled in the config.
+ * @param content - The content to log.
+ */
+ public debug(...content: any): void {
+ if (this.client.config.dev) {
+ console.log(`${chalk.bgGrey(this.timeStamp())} ${chalk.grey('[Debug]')}`, ...content);
+ }
+ }
-// /**
-// * Logs information. Highlight information by surrounding it in `<<>>`.
-// * @param header - The header displayed before the content, displayed in cyan.
-// * @param content - The content to log, highlights displayed in bright blue.
-// */
-// public info(header: string, content: string): void {
-// return console.info(`${chalk.bgCyan(this.timeStamp())} ${chalk.cyan(`[${header}]`)} ` + this.parseColors(content, 'blueBright'));
-// }
+ /**
+ * Logs verbose information. Highlight information by surrounding it in `<<>>`.
+ * @param header - The header displayed before the content, displayed in grey.
+ * @param content - The content to log, highlights displayed in bright black.
+ */
+ public verbose(header: string, content: any): void {
+ if (this.client.config.logging.verbose) {
+ return console.info(
+ `${chalk.bgGrey(this.timeStamp())} ${chalk.grey(`[${header}]`)} ` + this.parseColors(content, 'blackBright')
+ );
+ }
+ }
-// /**
-// * Logs warnings. Highlight information by surrounding it in `<<>>`.
-// * @param header - The header displayed before the content, displayed in yellow.
-// * @param content - The content to log, highlights displayed in bright yellow.
-// */
-// public warn(header: string, content: string): void {
-// return console.warn(`${chalk.bgYellow(this.timeStamp())} ${chalk.yellow(`[${header}]`)} ` + this.parseColors(content, 'yellowBright'));
-// }
+ /**
+ * Logs information. Highlight information by surrounding it in `<<>>`.
+ * @param header - The header displayed before the content, displayed in cyan.
+ * @param content - The content to log, highlights displayed in bright blue.
+ */
+ public info(header: string, content: any): void {
+ if (this.client.config.logging.info) {
+ return console.info(
+ `${chalk.bgCyan(this.timeStamp())} ${chalk.cyan(`[${header}]`)} ` + this.parseColors(content, 'blueBright')
+ );
+ }
+ }
-// /**
-// * Logs errors. Highlight information by surrounding it in `<<>>`.
-// * @param header - The header displayed before the content, displayed in bright red.
-// * @param content - The content to log, highlights displayed in bright red.
-// */
-// public error(header: string, content: string): void {
-// return console.error(`${chalk.bgRedBright(this.timeStamp())} ${chalk.redBright(`[${header}]`)} ` + this.parseColors(content, 'redBright'));
-// }
+ /**
+ * Logs warnings. Highlight information by surrounding it in `<<>>`.
+ * @param header - The header displayed before the content, displayed in yellow.
+ * @param content - The content to log, highlights displayed in bright yellow.
+ */
+ public warn(header: string, content: any): void {
+ return console.warn(
+ `${chalk.bgYellow(this.timeStamp())} ${chalk.yellow(`[${header}]`)} ` + this.parseColors(content, 'yellowBright')
+ );
+ }
-// /**
-// * Logs successes. Highlight information by surrounding it in `<<>>`.
-// * @param header - The header displayed before the content, displayed in green.
-// * @param content - The content to log, highlights displayed in bright green.
-// */
-// public success(header: string, content: string): void {
-// return console.log(`${chalk.bgGreen(this.timeStamp())} ${chalk.greenBright(`[${header}]`)} ` + this.parseColors(content, 'greenBright'));
-// }
-// }
+ /**
+ * Logs errors. Highlight information by surrounding it in `<<>>`.
+ * @param header - The header displayed before the content, displayed in bright red.
+ * @param content - The content to log, highlights displayed in bright red.
+ */
+ public error(header: string, content: any): void {
+ return console.error(
+ `${chalk.bgRedBright(this.timeStamp())} ${chalk.redBright(`[${header}]`)} ` + this.parseColors(content, 'redBright')
+ );
+ }
+
+ /**
+ * Logs successes. Highlight information by surrounding it in `<<>>`.
+ * @param header - The header displayed before the content, displayed in green.
+ * @param content - The content to log, highlights displayed in bright green.
+ */
+ public success(header: string, content: any): void {
+ return console.log(
+ `${chalk.bgGreen(this.timeStamp())} ${chalk.greenBright(`[${header}]`)} ` + this.parseColors(content, 'greenBright')
+ );
+ }
+}
diff --git a/src/lib/utils/Logger.ts b/src/lib/utils/Logger.ts
index 96837b6..0675e3d 100644
--- a/src/lib/utils/Logger.ts
+++ b/src/lib/utils/Logger.ts
@@ -1,8 +1,8 @@
+import chalk from 'chalk';
import { TextChannel } from 'discord.js';
import { BushClient } from '../extensions/BushClient';
-import chalk from 'chalk';
-export class Logger {
+export class BushLogger {
private client: BushClient;
public constructor(client: BushClient) {
this.client = client;
diff --git a/src/listeners/commands/commandError.ts b/src/listeners/commands/commandError.ts
index 0e52140..06aa55f 100644
--- a/src/listeners/commands/commandError.ts
+++ b/src/listeners/commands/commandError.ts
@@ -1,9 +1,7 @@
+import { stripIndents } from 'common-tags';
+import { Message, MessageEmbed, TextChannel } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
import { BushListener } from '../../lib/extensions/BushListener';
-import { stripIndents } from 'common-tags';
-import { Message } from 'discord.js';
-import { MessageEmbed } from 'discord.js';
-import { TextChannel } from 'discord.js';
export default class CommandErrorListener extends BushListener {
constructor() {
@@ -36,7 +34,7 @@ export default class CommandErrorListener extends BushListener {
);
}
const channel = (await this.client.channels.fetch(this.client.config.channels.log)) as TextChannel;
- await channel.send(errorDevEmbed);
- if (errorUserEmbed) await message.reply(errorUserEmbed);
+ await channel.send({ embeds: [errorDevEmbed] });
+ if (errorUserEmbed) await message.reply({ embeds: [errorUserEmbed] });
}
}
diff --git a/src/listeners/commands/slashCommandError.ts b/src/listeners/commands/slashCommandError.ts
index e4c3bb0..b8d9b6b 100644
--- a/src/listeners/commands/slashCommandError.ts
+++ b/src/listeners/commands/slashCommandError.ts
@@ -1,9 +1,7 @@
+import { stripIndents } from 'common-tags';
+import { CommandInteraction, MessageEmbed, TextChannel } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
import { BushListener } from '../../lib/extensions/BushListener';
-import { stripIndents } from 'common-tags';
-import { MessageEmbed } from 'discord.js';
-import { TextChannel } from 'discord.js';
-import { CommandInteraction } from 'discord.js';
export default class SlashCommandErrorListener extends BushListener {
constructor() {
@@ -36,7 +34,7 @@ export default class SlashCommandErrorListener extends BushListener {
);
}
const channel = (await this.client.channels.fetch(this.client.config.channels.log)) as TextChannel;
- await channel.send(errorDevEmbed);
- if (errorUserEmbed) await message.reply(errorUserEmbed);
+ await channel.send({ embeds: [errorDevEmbed] });
+ if (errorUserEmbed) await message.reply({ embeds: [errorUserEmbed] });
}
}