Compare commits

..

No commits in common. "132e3cc62b742c2a66ec3c1d34447efa54686fdf" and "2207d996a1b586b64cff629a084e30f12015e8cc" have entirely different histories.

89 changed files with 1978 additions and 2151 deletions

View File

@ -34,12 +34,12 @@
"pnpm": ">=9"
},
"dependencies": {
"@prisma/client": "^6.2.1",
"@prisma/client": "^5.22.0",
"@sapphire/discord.js-utilities": "^7.3.2",
"@sapphire/framework": "^5.3.2",
"@sapphire/plugin-logger": "^4.0.2",
"@sapphire/plugin-scheduled-tasks": "^10.0.2",
"@sapphire/plugin-subcommands": "^7.0.1",
"@sapphire/plugin-subcommands": "^6.0.3",
"@sapphire/stopwatch": "^1.5.4",
"@sapphire/time-utilities": "^1.7.14",
"@sapphire/ts-config": "^5.0.1",
@ -51,13 +51,13 @@
"typescript": "~5.4.5"
},
"devDependencies": {
"@types/node": "^22.10.7",
"@typescript-eslint/eslint-plugin": "^8.20.0",
"@typescript-eslint/parser": "^8.20.0",
"eslint": "9.18.0",
"eslint-config-prettier": "^10.0.1",
"prettier": "3.4.2",
"prisma": "^6.2.1"
"@types/node": "^20.17.13",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"eslint": "8.56.0",
"eslint-config-prettier": "^9.1.0",
"prettier": "3.2.4",
"prisma": "^5.22.0"
},
"packageManager": "pnpm@9.12.2+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228"
}

732
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -18,10 +18,8 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { MessageFlagsBitField } from 'discord.js';
import { ChannelType } from 'discord.js';
import IDs from '#utils/ids';
import { isRole, isUser } from '#utils/typeChecking';
import { isTextChannel } from '@sapphire/discord.js-utilities';
export class AccessCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -81,7 +79,7 @@ export class AccessCommand extends Command {
if (!interaction.inCachedGuild()) {
await interaction.reply({
content: 'This command can only be run in a server!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -93,29 +91,32 @@ export class AccessCommand extends Command {
const role = interaction.options.getRole('role');
// Checks if all the variables are of the right type
if (!isUser(user) && !isRole(role)) {
if (user === null && role === null) {
await interaction.reply({
content: 'Error fetching slash command data!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
// If user and role is provided, the return an error
if (isUser(user) && isRole(role)) {
if (user !== null && role !== null) {
await interaction.reply({
content:
'You have entered a user and a role at the same time! Please only enter one at a time.',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
// Checks that the channel is a GuildText or GuildVoice, otherwise, return error
if (!isTextChannel(channel) && !channel.isVoiceBased()) {
if (
channel.type !== ChannelType.GuildText &&
channel.type !== ChannelType.GuildVoice
) {
await interaction.reply({
content: 'Please only select a text or voice channel!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -128,7 +129,7 @@ export class AccessCommand extends Command {
) {
await interaction.reply({
content: 'Channel is not in ModMail/Private/Restricted category!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -142,13 +143,13 @@ export class AccessCommand extends Command {
} else {
await interaction.reply({
content: 'Could not find the role to edit permissions!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
// Set permissions of voice channel
if (channel.isVoiceBased()) {
if (channel.type === ChannelType.GuildVoice) {
switch (permission) {
case 'add':
await channel.permissionOverwrites.create(permId, {
@ -184,7 +185,7 @@ export class AccessCommand extends Command {
default:
await interaction.reply({
content: 'Incorrect permission option!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -219,7 +220,7 @@ export class AccessCommand extends Command {
default:
await interaction.reply({
content: 'Incorrect permission option!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}

View File

@ -20,7 +20,6 @@
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Message, MessageFlagsBitField } from 'discord.js';
import { ChannelType, TextChannel } from 'discord.js';
import { isTextChannel } from '@sapphire/discord.js-utilities';
export class AnonymousCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -75,7 +74,7 @@ export class AnonymousCommand extends Command {
}
if (channel === null) {
if (!isTextChannel(interaction.channel)) {
if (interaction.channel === null) {
await interaction.reply({
content: 'Error getting the channel!',
flags: MessageFlagsBitField.Flags.Ephemeral,

View File

@ -18,8 +18,7 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Message, MessageFlagsBitField } from 'discord.js';
import { isGuildBasedChannel } from '@sapphire/discord.js-utilities';
import type { Message } from 'discord.js';
export class ClearCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -58,11 +57,11 @@ export class ClearCommand extends Command {
const messages = interaction.options.getInteger('messages', true);
const { channel } = interaction;
if (!isGuildBasedChannel(channel)) {
if (channel === null || channel.isDMBased()) {
await interaction.reply({
content: 'Could not fetch channel!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -71,8 +70,8 @@ export class ClearCommand extends Command {
await interaction.reply({
content: `Successfully deleted ${messages} messages!`,
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
}
@ -93,7 +92,7 @@ export class ClearCommand extends Command {
const { channel } = message;
if (!isGuildBasedChannel(channel)) {
if (!channel.isTextBased() || channel.isDMBased()) {
await message.react('❌');
await message.reply('Unsupported channel type!');
return;

View File

@ -19,8 +19,9 @@
import { RegisterBehavior } from '@sapphire/framework';
import { Subcommand } from '@sapphire/plugin-subcommands';
import { TextChannel, Snowflake, MessageFlagsBitField } from 'discord.js';
import type { Guild, TextChannel, Snowflake } from 'discord.js';
import {
CategoryChannel,
ChannelType,
EmbedBuilder,
GuildMember,
@ -28,19 +29,6 @@ import {
time,
} from 'discord.js';
import IDs from '#utils/ids';
import {
isCategoryChannel,
isGuildBasedChannel,
isGuildMember,
isTextChannel,
isVoiceChannel,
} from '@sapphire/discord.js-utilities';
import {
getCategoryChannel,
getGuildMember,
getVoiceChannel,
} from '#utils/fetcher';
import { isUser } from '#utils/typeChecking';
export class PrivateCommand extends Subcommand {
public constructor(
@ -105,9 +93,7 @@ export class PrivateCommand extends Subcommand {
const modUser = interaction.user;
const { guild } = interaction;
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
// Checks if all the variables are of the right type
if (guild === null) {
@ -117,11 +103,11 @@ export class PrivateCommand extends Subcommand {
return;
}
const member = await getGuildMember(user.id, guild);
const mod = await getGuildMember(modUser.id, guild);
const member = guild.members.cache.get(user.id);
const mod = guild.members.cache.get(modUser.id);
// Checks if guildMember is null
if (!isGuildMember(member) || !isGuildMember(mod)) {
if (member === undefined || mod === undefined) {
await interaction.editReply({
content: 'Error fetching users!',
});
@ -130,7 +116,7 @@ export class PrivateCommand extends Subcommand {
const [name, coordinator] = this.getCoordinator(mod);
if (await this.checkPrivate(member.id, coordinator)) {
if (this.checkPrivate(member.id, coordinator, guild)) {
await interaction.editReply({
content: 'A private channel already exists!',
});
@ -249,22 +235,20 @@ export class PrivateCommand extends Subcommand {
const modUser = interaction.user;
const { guild, channel } = interaction;
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
// Checks if all the variables are of the right type
if (guild === null || !isGuildBasedChannel(channel)) {
if (guild === null || channel === null) {
await interaction.editReply({
content: 'Error fetching user!',
});
return;
}
const mod = await getGuildMember(modUser.id, guild);
const mod = guild.members.cache.get(modUser.id);
// Checks if guildMember is null
if (!isGuildMember(mod)) {
if (mod === undefined) {
await interaction.editReply({
content: 'Error fetching users!',
});
@ -275,8 +259,8 @@ export class PrivateCommand extends Subcommand {
const coordinator = coordinatorInfo[1];
let topic: string[];
if (!isUser(user)) {
if (!isTextChannel(channel)) {
if (user === null) {
if (channel.type !== ChannelType.GuildText) {
await interaction.editReply({
content:
'Please make sure you ran this command in the original private text channel!',
@ -303,10 +287,10 @@ export class PrivateCommand extends Subcommand {
await channel.delete();
const vcId = topic[topic.indexOf(coordinator) + 1];
const voiceChannel = await getVoiceChannel(vcId);
const voiceChannel = guild.channels.cache.get(vcId);
if (
isVoiceChannel(voiceChannel) &&
voiceChannel !== undefined &&
voiceChannel.parentId === IDs.categories.private
) {
await voiceChannel.delete();
@ -314,7 +298,9 @@ export class PrivateCommand extends Subcommand {
return;
}
const category = await getCategoryChannel(IDs.categories.private);
const category = guild.channels.cache.get(IDs.categories.private) as
| CategoryChannel
| undefined;
if (category === undefined) {
await interaction.editReply({
@ -323,32 +309,26 @@ export class PrivateCommand extends Subcommand {
return;
}
const textChannels = category.children.cache.filter((channel) =>
isTextChannel(channel),
const textChannels = category.children.cache.filter(
(c) => c.type === ChannelType.GuildText,
);
for (const c of textChannels) {
const channel = c[1];
if (!isTextChannel(channel)) {
continue;
}
textChannels.forEach((c) => {
const textChannel = c as TextChannel;
// Checks if the channel topic has the user's snowflake
if (channel.topic !== null && channel.topic.includes(user.id)) {
topic = channel.topic.split(' ');
if (textChannel.topic?.includes(user?.id)) {
topic = textChannel.topic.split(' ');
const vcId = topic[topic.indexOf(coordinator) + 1];
const voiceChannel = await getVoiceChannel(vcId);
const voiceChannel = guild.channels.cache.get(vcId);
if (
isVoiceChannel(voiceChannel) &&
voiceChannel !== undefined &&
voiceChannel.parentId === IDs.categories.private
) {
await voiceChannel.delete();
voiceChannel.delete();
}
await channel.delete();
textChannel.delete();
}
}
});
await interaction.editReply({
content: `Successfully deleted the channel for ${user}`,
@ -389,35 +369,29 @@ export class PrivateCommand extends Subcommand {
return [name, id];
}
private async checkPrivate(user: Snowflake, coordinator: string) {
const category = await getCategoryChannel(IDs.categories.private);
private checkPrivate(user: Snowflake, coordinator: string, guild: Guild) {
const category = guild.channels.cache.get(IDs.categories.private) as
| CategoryChannel
| undefined;
if (!isCategoryChannel(category)) {
if (category === undefined) {
return true;
}
const textChannels = category.children.cache.filter(
(c) => c.type === ChannelType.GuildText,
);
let exists = false;
for (const c of textChannels) {
const channel = c[1];
if (!isTextChannel(channel)) {
continue;
}
textChannels.forEach((c) => {
const textChannel = c as TextChannel;
// Checks if the channel topic has the user's snowflake
if (
channel.topic !== null &&
channel.topic.includes(user) &&
channel.topic.includes(coordinator)
textChannel.topic?.includes(user) &&
textChannel.topic?.includes(coordinator)
) {
exists = true;
}
}
});
return exists;
}
}

View File

@ -18,12 +18,10 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { User, Guild, Message, MessageFlagsBitField } from 'discord.js';
import type { User, Guild, Message } from 'discord.js';
import { updateUser } from '#utils/database/dbExistingUser';
import { getBalance } from '#utils/database/fun/economy';
import { EmbedBuilder } from 'discord.js';
import { getGuildMember } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class BalanceCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -52,7 +50,7 @@ export class BalanceCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Could not find the guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -68,9 +66,15 @@ export class BalanceCommand extends Command {
}
public async messageRun(message: Message) {
const user = message.author;
const user = message.member?.user;
const { guild } = message;
if (user === undefined) {
await message.react('❌');
await message.reply('Could not find your user!');
return;
}
if (guild === null) {
await message.react('❌');
await message.reply('Could not find the guild!');
@ -95,9 +99,9 @@ export class BalanceCommand extends Command {
success: false,
};
const member = await getGuildMember(user.id, guild);
const member = guild.members.cache.get(user.id);
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Could not find your guild member!';
return info;
}

View File

@ -19,19 +19,11 @@
import { Command, RegisterBehavior } from '@sapphire/framework';
import { Time } from '@sapphire/time-utilities';
import {
User,
Guild,
GuildMember,
Message,
MessageFlagsBitField,
} from 'discord.js';
import type { User, Guild, GuildMember, Message } from 'discord.js';
import { updateUser } from '#utils/database/dbExistingUser';
import { daily, getLastDaily } from '#utils/database/fun/economy';
import { EmbedBuilder } from 'discord.js';
import IDs from '#utils/ids';
import { getGuildMember } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class DailyCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -59,7 +51,7 @@ export class DailyCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Could not find the guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -75,9 +67,15 @@ export class DailyCommand extends Command {
}
public async messageRun(message: Message) {
const user = message.author;
const user = message.member?.user;
const { guild } = message;
if (user === undefined) {
await message.react('❌');
await message.reply('Could not find your user!');
return;
}
if (guild === null) {
await message.react('❌');
await message.reply('Could not find the guild!');
@ -116,9 +114,9 @@ export class DailyCommand extends Command {
return info;
}
const member = await getGuildMember(user.id, guild);
const member = guild.members.cache.get(user.id);
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Could not find your guild member!';
return info;
}

View File

@ -18,13 +18,11 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { User, Guild, Message, MessageFlagsBitField } from 'discord.js';
import type { User, Guild, Message } from 'discord.js';
import { updateUser } from '#utils/database/dbExistingUser';
import { getBalance, transfer } from '#utils/database/fun/economy';
import { EmbedBuilder } from 'discord.js';
import { EmbedBuilder, TextChannel } from 'discord.js';
import IDs from '#utils/ids';
import { getGuildMember, getTextBasedChannel } from '#utils/fetcher';
import { isGuildMember, isTextChannel } from '@sapphire/discord.js-utilities';
export class BalanceCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -77,7 +75,7 @@ export class BalanceCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Could not find the guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -119,9 +117,15 @@ export class BalanceCommand extends Command {
return;
}
const user = message.author;
const user = message.member?.user;
const { guild } = message;
if (user === undefined) {
await message.react('❌');
await message.reply('Could not find your user!');
return;
}
if (guild === null) {
await message.react('❌');
await message.reply('Could not find the guild!');
@ -160,15 +164,15 @@ export class BalanceCommand extends Command {
return info;
}
const member = await getGuildMember(user.id, guild);
const recipientMember = await getGuildMember(recipient.id, guild);
const member = guild.members.cache.get(user.id);
const recipientMember = guild.members.cache.get(recipient.id);
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Could not find your guild member!';
return info;
}
if (!isGuildMember(recipientMember)) {
if (recipientMember === undefined) {
info.message = 'Could not find the user!';
return info;
}
@ -202,16 +206,18 @@ export class BalanceCommand extends Command {
info.embeds.push(embed);
// Log the payment in the server
const logChannel = await getTextBasedChannel(IDs.channels.logs.economy);
let logChannel = guild.channels.cache.get(IDs.channels.logs.economy) as
| TextChannel
| undefined;
if (!isTextChannel(logChannel)) {
this.container.logger.error('Pay: Could not fetch log channel');
return info;
} else if (!logChannel.isSendable()) {
this.container.logger.error(
'Pay: the bot does not have permission to send in the log channel',
);
return info;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(IDs.channels.logs.economy)) as
| TextChannel
| undefined;
if (logChannel === undefined) {
this.container.logger.error('Pay Error: Could not fetch log channel');
return info;
}
}
const logEmbed = new EmbedBuilder(embed.data);

View File

@ -18,10 +18,9 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { N1984 } from '#utils/gifs';
import { addFunLog, countTotal } from '#utils/database/fun/fun';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class N1984Command extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -49,10 +48,10 @@ export class N1984Command extends Command {
const { member } = interaction;
// Type checks
if (!isGuildMember(member)) {
if (!(member instanceof GuildMember)) {
await interaction.reply({
ephemeral: true,
content: 'Failed to fetch your user on the bot!',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
}
@ -80,6 +79,6 @@ export class N1984Command extends Command {
.setFooter({ text: embedFooter });
// Send the embed
await interaction.reply({ embeds: [n1984Embed], withResponse: true });
await interaction.reply({ embeds: [n1984Embed], fetchReply: true });
}
}

View File

@ -18,10 +18,9 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Cringe } from '#utils/gifs';
import { addFunLog, countTotal } from '#utils/database/fun/fun';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class CringeCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -48,10 +47,10 @@ export class CringeCommand extends Command {
const { member } = interaction;
// Type check
if (!isGuildMember(member)) {
if (!(member instanceof GuildMember)) {
await interaction.reply({
ephemeral: true,
content: 'Failed to fetch your user on the bot!',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
}
@ -75,6 +74,6 @@ export class CringeCommand extends Command {
.setFooter({ text: embedFooter });
// Send the embed
await interaction.reply({ embeds: [cringeEmbed], withResponse: true });
await interaction.reply({ embeds: [cringeEmbed], fetchReply: true });
}
}

View File

@ -18,9 +18,8 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Happy } from '#utils/gifs';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class HappyCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -47,10 +46,10 @@ export class HappyCommand extends Command {
const { member } = interaction;
// Type checks
if (!isGuildMember(member)) {
if (!(member instanceof GuildMember)) {
await interaction.reply({
ephemeral: true,
content: 'Failed to fetch your user on the bot!',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
}
@ -63,6 +62,6 @@ export class HappyCommand extends Command {
.setImage(randomHappy);
// Send the embed
await interaction.reply({ embeds: [happyEmbed], withResponse: true });
await interaction.reply({ embeds: [happyEmbed], fetchReply: true });
}
}

View File

@ -18,10 +18,9 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Hugs } from '#utils/gifs';
import { addFunLog, countTotal } from '#utils/database/fun/fun';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class HugCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -59,10 +58,10 @@ export class HugCommand extends Command {
// Type Checks
if (!isGuildMember(hugger)) {
if (!(hugger instanceof GuildMember)) {
await interaction.reply({
ephemeral: true,
content: 'Failed to fetch your user on the bot!',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
}
@ -97,7 +96,7 @@ export class HugCommand extends Command {
await interaction.reply({
content: `${user}`,
embeds: [hugEmbed],
withResponse: true,
fetchReply: true,
});
}
}

View File

@ -18,10 +18,9 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Kill } from '#utils/gifs';
import { addFunLog, countTotal } from '#utils/database/fun/fun';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class KillCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -58,10 +57,10 @@ export class KillCommand extends Command {
const sender = interaction.member;
// Type checks
if (!isGuildMember(sender)) {
if (!(sender instanceof GuildMember)) {
await interaction.reply({
ephemeral: true,
content: 'Failed to fetch your user on the bot!',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
}
@ -93,7 +92,7 @@ export class KillCommand extends Command {
await interaction.reply({
content: `${user}`,
embeds: [killEmbed],
withResponse: true,
fetchReply: true,
});
}
}

View File

@ -18,10 +18,9 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Poke } from '#utils/gifs';
import { addFunLog, countTotal } from '#utils/database/fun/fun';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class PokeCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -58,10 +57,10 @@ export class PokeCommand extends Command {
const sender = interaction.member;
// Type checks
if (!isGuildMember(sender)) {
if (!(sender instanceof GuildMember)) {
await interaction.reply({
ephemeral: true,
content: 'Failed to fetch your user on the bot!',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
}
@ -96,7 +95,7 @@ export class PokeCommand extends Command {
await interaction.reply({
content: `${user}`,
embeds: [pokeEmbed],
withResponse: true,
fetchReply: true,
});
}
}

View File

@ -18,9 +18,8 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Sad } from '#utils/gifs';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class SadCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -47,10 +46,10 @@ export class SadCommand extends Command {
const { member } = interaction;
// Type checks
if (!isGuildMember(member)) {
if (!(member instanceof GuildMember)) {
await interaction.reply({
ephemeral: true,
content: 'Failed to fetch your user on the bot!',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
}
@ -63,6 +62,6 @@ export class SadCommand extends Command {
.setImage(randomSad);
// Send the embed
await interaction.reply({ embeds: [sadEmbed], withResponse: true });
await interaction.reply({ embeds: [sadEmbed], fetchReply: true });
}
}

View File

@ -18,9 +18,8 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import { EmbedBuilder, GuildMember } from 'discord.js';
import { Shrug } from '#utils/gifs';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class ShrugCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -47,10 +46,10 @@ export class ShrugCommand extends Command {
const { member } = interaction;
// Type checks
if (!isGuildMember(member)) {
if (!(member instanceof GuildMember)) {
await interaction.reply({
ephemeral: true,
content: 'Failed to fetch your user on the bot!',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
}
@ -63,6 +62,6 @@ export class ShrugCommand extends Command {
.setImage(randomShrug);
// Send the embed
await interaction.reply({ embeds: [shrugEmbed], withResponse: true });
await interaction.reply({ embeds: [shrugEmbed], fetchReply: true });
}
}

View File

@ -18,13 +18,7 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import {
User,
Message,
Snowflake,
Guild,
MessageFlagsBitField,
} from 'discord.js';
import type { User, Message, Snowflake, TextChannel, Guild } from 'discord.js';
import { EmbedBuilder } from 'discord.js';
import IDs from '#utils/ids';
import { addBan, checkBan } from '#utils/database/moderation/ban';
@ -33,12 +27,6 @@ import {
checkTempBan,
removeTempBan,
} from '#utils/database/moderation/tempBan';
import { getGuildMember, getTextBasedChannel, getUser } from '#utils/fetcher';
import { isUser } from '#utils/typeChecking';
import {
isGuildMember,
isTextBasedChannel,
} from '@sapphire/discord.js-utilities';
export class BanCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -87,15 +75,13 @@ export class BanCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const ban = await this.ban(user.id, mod.id, reason, guild);
@ -156,19 +142,17 @@ export class BanCommand extends Command {
success: false,
};
const user = await getUser(userId);
let user = guild.client.users.cache.get(userId);
if (!isUser(user)) {
info.message =
'The user does not exist! (The user provided is probably wrong, or their account has been deleted.)';
return info;
if (user === undefined) {
user = (await guild.client.users.fetch(userId)) as User;
}
// Gets mod's GuildMember
const mod = await getGuildMember(modId, guild);
const mod = guild.members.cache.get(modId);
// Checks if guildMember is null
if (!isGuildMember(mod)) {
if (mod === undefined) {
info.message = 'Error fetching mod!';
return info;
}
@ -182,9 +166,13 @@ export class BanCommand extends Command {
await updateUser(mod);
// Gets guildMember
const member = await getGuildMember(userId, guild);
let member = guild.members.cache.get(userId);
if (isGuildMember(member)) {
if (member === undefined) {
member = await guild.members.fetch(userId).catch(() => undefined);
}
if (member !== undefined) {
// Checks if the user is not restricted
if (member.roles.cache.has(IDs.roles.vegan.vegan)) {
info.message = 'You need to restrict the user first!';
@ -218,20 +206,19 @@ export class BanCommand extends Command {
info.success = true;
// Log the ban
const logChannel = await getTextBasedChannel(IDs.channels.logs.restricted);
let logChannel = guild.channels.cache.get(IDs.channels.logs.restricted) as
| TextChannel
| undefined;
if (!isTextBasedChannel(logChannel)) {
this.container.logger.error('Ban: Could not fetch log channel');
info.message = `${user} has been banned. This hasn't been logged in a text channel as log channel could not be found`;
return info;
} else if (!logChannel.isSendable()) {
this.container.logger.error(
'Ban: The bot does not have permission to send in the logs channel!',
);
info.message = `${user} has been banned. This hasn't been logged in a text channel as the bot does not have permission to send logs!`;
return info;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(
IDs.channels.logs.restricted,
)) as TextChannel | undefined;
if (logChannel === undefined) {
this.container.logger.error('Ban Error: Could not fetch log channel');
info.message = `${user} has been banned. This hasn't been logged in a text channel as log channel could not be found`;
return info;
}
}
const log = new EmbedBuilder()

View File

@ -19,17 +19,11 @@
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Duration, DurationFormatter } from '@sapphire/time-utilities';
import { User, Snowflake, Guild, MessageFlagsBitField } from 'discord.js';
import type { User, Snowflake, TextChannel, Guild } from 'discord.js';
import { EmbedBuilder, Message } from 'discord.js';
import IDs from '#utils/ids';
import { addTempBan, checkTempBan } from '#utils/database/moderation/tempBan';
import { addEmptyUser, updateUser } from '#utils/database/dbExistingUser';
import { getGuildMember, getTextBasedChannel, getUser } from '#utils/fetcher';
import { isUser } from '#utils/typeChecking';
import {
isGuildMember,
isTextBasedChannel,
} from '@sapphire/discord.js-utilities';
export class TempBanCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -85,8 +79,8 @@ export class TempBanCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -100,9 +94,7 @@ export class TempBanCommand extends Command {
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const ban = await this.ban(user.id, mod.id, time, reason, guild);
@ -209,19 +201,17 @@ export class TempBanCommand extends Command {
const banLength = new DurationFormatter().format(time.offset);
const user = await getUser(userId);
let user = guild.client.users.cache.get(userId);
if (!isUser(user)) {
info.message =
'The user does not exist! (The user provided is probably wrong, or their account has been deleted.)';
return info;
if (user === undefined) {
user = (await guild.client.users.fetch(userId)) as User;
}
// Gets mod's GuildMember
const mod = await getGuildMember(modId, guild);
const mod = guild.members.cache.get(modId);
// Checks if guildMember is null
if (!isGuildMember(mod)) {
if (mod === undefined) {
info.message = 'Error fetching mod!';
return info;
}
@ -235,9 +225,13 @@ export class TempBanCommand extends Command {
await updateUser(mod);
// Gets guildMember
const member = await getGuildMember(userId, guild);
let member = guild.members.cache.get(userId);
if (isGuildMember(member)) {
if (member === undefined) {
member = await guild.members.fetch(userId).catch(() => undefined);
}
if (member !== undefined) {
// Checks if the user is not restricted
if (member.roles.cache.has(IDs.roles.vegan.vegan)) {
info.message = 'You need to restrict the user first!';
@ -279,25 +273,23 @@ export class TempBanCommand extends Command {
info.success = true;
// Log the ban
const logChannel = await getTextBasedChannel(IDs.channels.logs.restricted);
let logChannel = guild.channels.cache.get(IDs.channels.logs.restricted) as
| TextChannel
| undefined;
if (!isTextBasedChannel(logChannel)) {
this.container.logger.error('Temp Ban: Could not fetch log channel');
info.message =
`${user} has been temporarily banned for ${banLength}. ` +
"This hasn't been logged in a text channel as log channel could not be found";
return info;
} else if (!logChannel.isSendable()) {
this.container.logger.error(
'Temp Ban: The bot does not have permission to send in the logs channel!',
);
info.message =
`${user} has been temporarily banned for ${banLength}. ` +
"This hasn't been logged in a text channel as the bot does not have permission to send logs!";
return info;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(
IDs.channels.logs.restricted,
)) as TextChannel | undefined;
if (logChannel === undefined) {
this.container.logger.error(
'Temp Ban Error: Could not fetch log channel',
);
info.message =
`${user} has been temporarily banned for ${banLength}. ` +
"This hasn't been logged in a text channel as log channel could not be found";
return info;
}
}
const log = new EmbedBuilder()

View File

@ -18,13 +18,13 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import {
import type {
User,
Message,
Snowflake,
TextChannel,
Guild,
GuildBan,
MessageFlagsBitField,
} from 'discord.js';
import { EmbedBuilder } from 'discord.js';
import IDs from '#utils/ids';
@ -34,12 +34,6 @@ import {
removeTempBan,
} from '#utils/database/moderation/tempBan';
import { addEmptyUser, addExistingUser } from '#utils/database/dbExistingUser';
import { getGuildMember, getTextBasedChannel, getUser } from '#utils/fetcher';
import {
isGuildMember,
isTextBasedChannel,
} from '@sapphire/discord.js-utilities';
import { isNullish } from '@sapphire/utilities';
export class UnbanCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -81,8 +75,8 @@ export class UnbanCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -129,10 +123,10 @@ export class UnbanCommand extends Command {
};
// Gets mod's GuildMember
const mod = await getGuildMember(modId, guild);
const mod = guild.members.cache.get(modId);
// Checks if guildMember is null
if (!isGuildMember(mod)) {
if (mod === undefined) {
info.message = 'Error fetching mod!';
return info;
}
@ -140,11 +134,14 @@ export class UnbanCommand extends Command {
// Check if mod is in database
await addExistingUser(mod);
const user = await getUser(userId);
let user = guild.client.users.cache.get(userId);
if (user === undefined) {
info.message = 'Could not fetch the user!';
return info;
user = await guild.client.users.fetch(userId);
if (user === undefined) {
info.message = 'Could not fetch the user!';
return info;
}
}
let dbBan = await checkBan(userId);
@ -164,7 +161,7 @@ export class UnbanCommand extends Command {
}
let { reason } = ban;
if (isNullish(reason)) {
if (reason === null || reason === undefined) {
reason = '';
}
@ -194,21 +191,19 @@ export class UnbanCommand extends Command {
info.success = true;
// Log unban
let logChannel = await getTextBasedChannel(IDs.channels.logs.restricted);
let logChannel = guild.channels.cache.get(IDs.channels.logs.restricted) as
| TextChannel
| undefined;
if (!isTextBasedChannel(logChannel)) {
this.container.logger.error('Unban Error: Could not fetch log channel');
info.message = `${user} has been unbanned. This hasn't been logged in a text channel as log channel could not be found`;
return info;
}
if (!logChannel.isSendable()) {
this.container.logger.error(
'Unban: The bot does not have permission to send in the logs channel!',
);
info.message = `${user} has been unbanned. This hasn't been logged in a text channel as the bot does not have permission to send logs!`;
return info;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(
IDs.channels.logs.restricted,
)) as TextChannel | undefined;
if (logChannel === undefined) {
this.container.logger.error('Ban Error: Could not fetch log channel');
info.message = `${user} has been banned. This hasn't been logged in a text channel as log channel could not be found`;
return info;
}
}
const log = new EmbedBuilder()

View File

@ -22,20 +22,13 @@
import { Args, container, RegisterBehavior } from '@sapphire/framework';
import { Subcommand } from '@sapphire/plugin-subcommands';
import {
ChannelType,
GuildMember,
Message,
MessageFlagsBitField,
PermissionsBitField,
} from 'discord.js';
import type { Snowflake } from 'discord.js';
import type { TextChannel, Snowflake } from 'discord.js';
import IDs from '#utils/ids';
import { getGuildMember, getRole, getTextBasedChannel } from '#utils/fetcher';
import {
isGuildMember,
isTextChannel,
isThreadChannel,
} from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class DiversityCommand extends Subcommand {
public constructor(
@ -96,25 +89,47 @@ export class DiversityCommand extends Subcommand {
// Command run
public async toggleOpen(interaction: Subcommand.ChatInputCommandInteraction) {
// Get the channel
const channel = await getTextBasedChannel(interaction.channelId);
// Check if channel is text
if (!isTextChannel(channel)) {
// Check if guild is not null
if (interaction.guild === null) {
await interaction.reply({
content: 'Channel is not a text channel!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
content: 'Guild not found!',
ephemeral: true,
fetchReply: true,
});
return;
}
// Get the channel
const channel = interaction.guild.channels.cache.get(interaction.channelId);
// Check if channel is not undefined
if (channel === undefined) {
await interaction.reply({
content: 'Channel not found!',
ephemeral: true,
fetchReply: true,
});
return;
}
// Check if channel is text
if (channel.type !== ChannelType.GuildText) {
await interaction.reply({
content: 'Channel is not a text channel!',
ephemeral: true,
fetchReply: true,
});
return;
}
// Converts GuildBasedChannel to TextChannel
const channelText = channel as TextChannel;
// Check if the command was run in the diversity section
if (channel.parentId !== IDs.categories.diversity) {
await interaction.reply({
content: 'Command was not run in the Diversity section!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -125,13 +140,13 @@ export class DiversityCommand extends Subcommand {
.has([PermissionsBitField.Flags.SendMessages]);
// Toggle send message in channel
await channel.permissionOverwrites.edit(IDs.roles.vegan.vegan, {
await channelText.permissionOverwrites.edit(IDs.roles.vegan.vegan, {
SendMessages: !open,
});
await interaction.reply({
content: `${!open ? 'Opened' : 'Closed'} this channel.`,
withResponse: true,
fetchReply: true,
});
}
@ -140,69 +155,51 @@ export class DiversityCommand extends Subcommand {
) {
// TODO add database updates
// Get the arguments
const user = interaction.options.getUser('user', true);
const user = interaction.options.getUser('user');
const mod = interaction.member;
const { guild } = interaction;
// Checks if all the variables are of the right type
if (guild === null) {
if (user === null || guild === null || mod === null) {
await interaction.reply({
content: 'Error fetching the guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
content: 'Error fetching user!',
ephemeral: true,
fetchReply: true,
});
return;
}
if (!isGuildMember(mod)) {
await interaction.reply({
content: 'Error fetching your user!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
});
return;
}
// Gets guildMember whilst removing the ability of each other variables being null
const guildMember = guild.members.cache.get(user.id);
const diversity = guild.roles.cache.get(IDs.roles.staff.diversity);
const member = await getGuildMember(user.id, guild);
const diversity = await getRole(IDs.roles.staff.diversity, guild);
// Checks if the member was found
if (!isGuildMember(member)) {
// Checks if guildMember is null
if (guildMember === undefined || diversity === undefined) {
await interaction.reply({
content: 'Error fetching the user!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
});
return;
}
// Checks if the role was found
if (!isRole(diversity)) {
await interaction.reply({
content: 'Error fetching the diversity role!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
content: 'Error fetching user!',
ephemeral: true,
fetchReply: true,
});
return;
}
// Checks if the user has Diversity and to give them or remove them based on if they have it
if (member.roles.cache.has(IDs.roles.staff.diversity)) {
if (guildMember.roles.cache.has(IDs.roles.staff.diversity)) {
// Remove the Diversity role from the user
await member.roles.remove(diversity);
await this.threadManager(member.id, false);
await guildMember.roles.remove(diversity);
await this.threadManager(guildMember.id, false);
await interaction.reply({
content: `Removed the ${diversity.name} role from ${user}`,
withResponse: true,
fetchReply: true,
});
return;
}
// Add Diversity Team role to the user
await member.roles.add(diversity);
await this.threadManager(member.id, true);
await guildMember.roles.add(diversity);
await this.threadManager(guildMember.id, true);
await interaction.reply({
content: `Gave ${user} the ${diversity.name} role!`,
withResponse: true,
fetchReply: true,
});
await user
.send(`You have been given the ${diversity.name} role by ${mod}!`)
@ -222,7 +219,7 @@ export class DiversityCommand extends Subcommand {
const mod = message.member;
if (!isGuildMember(mod)) {
if (mod === null) {
await message.react('❌');
await message.reply(
'Diversity coordinator not found! Try again or contact a developer!',
@ -238,9 +235,9 @@ export class DiversityCommand extends Subcommand {
return;
}
const diversity = await getRole(IDs.roles.staff.diversity, guild);
const diversity = guild.roles.cache.get(IDs.roles.staff.diversity);
if (!isRole(diversity)) {
if (diversity === undefined) {
await message.react('❌');
await message.reply('Role not found! Try again or contact a developer!');
return;
@ -273,8 +270,11 @@ export class DiversityCommand extends Subcommand {
const thread = await container.client.channels.fetch(
IDs.channels.diversity.diversity,
);
if (thread === null) {
return;
}
if (!isThreadChannel(thread)) {
if (!thread.isThread()) {
return;
}

View File

@ -21,13 +21,8 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Message, MessageFlagsBitField } from 'discord.js';
import type { Message } from 'discord.js';
import { ChannelType } from 'discord.js';
import {
isGuildMember,
isVoiceBasedChannel,
} from '@sapphire/discord.js-utilities';
import { getVoiceBasedChannel } from '#utils/fetcher';
export class MoveAllCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -66,9 +61,7 @@ export class MoveAllCommand extends Command {
const { member } = interaction;
const { guild } = interaction;
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
if (
channel.type !== ChannelType.GuildVoice &&
@ -88,31 +81,40 @@ export class MoveAllCommand extends Command {
return;
}
if (!isGuildMember(member)) {
if (member === null) {
await interaction.editReply({
content: 'Error fetching your user',
});
return;
}
if (member.voice.channelId === null) {
const mod = guild.members.cache.get(member.user.id);
if (mod === undefined) {
await interaction.editReply({
content: 'Error fetching user from guild',
});
return;
}
if (mod.voice.channelId === null) {
await interaction.editReply({
content: 'You need to be in a voice channel to run this command!',
});
return;
}
const voice = await getVoiceBasedChannel(member.voice.channelId);
const voice = guild.channels.cache.get(mod.voice.channelId);
if (!isVoiceBasedChannel(voice)) {
if (voice === undefined || !voice.isVoiceBased()) {
await interaction.editReply({
content: 'Error fetching your current voice channel!',
});
return;
}
voice.members.forEach((vcMember) => {
vcMember.voice.setChannel(channel.id);
voice.members.forEach((memberVC) => {
memberVC.voice.setChannel(channel.id);
});
await interaction.editReply({
@ -133,7 +135,7 @@ export class MoveAllCommand extends Command {
const mod = message.member;
const { guild } = message;
if (!isGuildMember(mod)) {
if (mod === null) {
await message.react('❌');
await message.reply('Could not find your user!');
return;
@ -153,9 +155,9 @@ export class MoveAllCommand extends Command {
return;
}
const voice = await getVoiceBasedChannel(mod.voice.channelId);
const voice = guild.channels.cache.get(mod.voice.channelId);
if (!isVoiceBasedChannel(voice)) {
if (voice === undefined || !voice.isVoiceBased()) {
await message.react('❌');
await message.reply('Could not fetch current voice channel!');
return;

View File

@ -18,9 +18,7 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { GuildMember, Message, MessageFlagsBitField } from 'discord.js';
import { getGuildMember } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import type { GuildMember, Message } from 'discord.js';
export class RenameUserCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -70,21 +68,21 @@ export class RenameUserCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
// Gets guildMember whilst removing the ability of each other variables being null
const member = await getGuildMember(user.id, guild);
const member = guild.members.cache.get(user.id);
// Checks if guildMember is null
if (!isGuildMember(member)) {
if (member === undefined) {
await interaction.reply({
content: 'Error fetching user!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -95,15 +93,15 @@ export class RenameUserCommand extends Command {
} catch {
await interaction.reply({
content: "Bot doesn't have permission to change the user's name!",
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.reply({
content: `Changed ${user}'s nickname`,
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
fetchReply: true,
ephemeral: true,
});
}

View File

@ -26,7 +26,6 @@ import {
import {
ChannelType,
EmbedBuilder,
MessageFlagsBitField,
PermissionsBitField,
time,
} from 'discord.js';
@ -40,11 +39,6 @@ import {
import { restrict, checkActive } from '#utils/database/moderation/restriction';
import { randint } from '#utils/maths';
import { blockedRolesAfterRestricted } from '#utils/blockedRoles';
import { getGuildMember, getTextBasedChannel, getUser } from '#utils/fetcher';
import {
isGuildMember,
isTextBasedChannel,
} from '@sapphire/discord.js-utilities';
export async function restrictRun(
userId: Snowflake,
@ -58,18 +52,21 @@ export async function restrictRun(
success: false,
};
const user = await getUser(userId);
let user = guild.client.users.cache.get(userId);
if (user === undefined) {
info.message = 'Error fetching user';
return info;
user = await guild.client.users.fetch(userId);
if (user === undefined) {
info.message = 'Error fetching user';
return info;
}
}
// Gets mod's GuildMember
const mod = await getGuildMember(modId, guild);
const mod = guild.members.cache.get(modId);
// Checks if guildMember is null
if (!isGuildMember(mod)) {
if (mod === undefined) {
info.message = 'Error fetching mod';
return info;
}
@ -83,13 +80,17 @@ export async function restrictRun(
}
// Gets guildMember
const member = await getGuildMember(userId, guild);
let member = guild.members.cache.get(userId);
if (member === undefined) {
member = await guild.members.fetch(userId).catch(() => undefined);
}
const restrictRoles = IDs.roles.restrictions.restricted;
let section = tolerance ? randint(3, 4) : randint(1, 2);
if (isGuildMember(member)) {
if (member !== undefined) {
// Checks if the user is not restricted
if (member.roles.cache.hasAny(...restrictRoles)) {
info.message = `${member} is already restricted!`;
@ -217,7 +218,7 @@ export async function restrictRun(
}
}
if (isGuildMember(member) && member.voice.channelId !== null) {
if (member !== undefined && member.voice.channelId !== null) {
await member.voice.disconnect();
}
@ -241,20 +242,19 @@ export async function restrictRun(
await user.send({ embeds: [dmEmbed] }).catch(() => {});
// Log the ban
const logChannel = await getTextBasedChannel(IDs.channels.logs.restricted);
let logChannel = guild.channels.cache.get(IDs.channels.logs.restricted) as
| TextChannel
| undefined;
if (!isTextBasedChannel(logChannel)) {
container.logger.error('Restrict: Could not fetch log channel');
info.message = `Restricted ${user} but could not find the log channel. This has been logged to the database.`;
return info;
} else if (!logChannel.isSendable()) {
container.logger.error(
'Restrict: The bot does not have permission to send in the logs channel!',
);
info.message = `${user} has been restricted. This hasn't been logged in a text channel as the bot does not have permission to send logs!`;
return info;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(IDs.channels.logs.restricted)) as
| TextChannel
| undefined;
if (logChannel === undefined) {
container.logger.error('Restrict Error: Could not fetch log channel');
info.message = `Restricted ${user} but could not find the log channel. This has been logged to the database.`;
return info;
}
}
const message = new EmbedBuilder()
@ -324,17 +324,15 @@ export class RestrictCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await restrictRun(user.id, mod.id, reason, guild);
const info = await restrictRun(user?.id, mod.id, reason, guild);
await interaction.editReply({
content: info.message,
@ -369,7 +367,7 @@ export class RestrictCommand extends Command {
return;
}
const info = await restrictRun(user.id, mod.id, reason, guild);
const info = await restrictRun(user?.id, mod.id, reason, guild);
await message.reply(info.message);
await message.react(info.success ? '✅' : '❌');

View File

@ -18,14 +18,11 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import type { Message, Guild, Snowflake } from 'discord.js';
import { ChannelType, EmbedBuilder } from 'discord.js';
import type { Message, TextChannel, Guild, Snowflake } from 'discord.js';
import IDs from '#utils/ids';
import { getRestrictions } from '#utils/database/moderation/restriction';
import { checkStaff } from '#utils/checker';
import { isUser } from '#utils/typeChecking';
import { isGuildMember, isTextChannel } from '@sapphire/discord.js-utilities';
import { getGuildMember, getUser } from '#utils/fetcher';
export class RestrictLogsCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -59,48 +56,47 @@ export class RestrictLogsCommand extends Command {
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
// Get the arguments
const user = interaction.options.getUser('user');
const { channel } = interaction;
let { channel } = interaction;
const { guild } = interaction;
// Checks if all the variables are of the right type
if (guild === null || channel === null) {
await interaction.reply({
content: 'Error fetching guild or channel!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
let userId: Snowflake | null = null;
if (isUser(user)) {
if (user !== undefined && user !== null) {
userId = user.id;
}
const staffChannel = checkStaff(channel);
if (staffChannel) {
// Checking Channel topic for Snowflake
channel = channel as TextChannel;
if (userId === null) {
let topic: string[];
if (
isTextChannel(channel) &&
channel.parentId === IDs.categories.modMail &&
channel.topic !== null
) {
if (channel.parentId === IDs.categories.modMail) {
// Checks if the channel topic has the user's snowflake
topic = channel.topic.split(' ');
userId = topic[2];
if (channel.topic !== null) {
topic = channel.topic.split(' ');
// eslint-disable-next-line prefer-destructuring
userId = topic[2];
}
}
}
// If no Snowflake was provided/found
if (userId === null) {
await interaction.reply({
content: 'User could not be found or was not provided!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -110,8 +106,8 @@ export class RestrictLogsCommand extends Command {
await interaction.reply({
embeds: info.embeds,
content: info.message,
withResponse: true,
flags: staffChannel ? undefined : MessageFlagsBitField.Flags.Ephemeral,
fetchReply: true,
ephemeral: !staffChannel,
});
}
}
@ -135,11 +131,10 @@ export class RestrictLogsCommand extends Command {
return;
}
// Attempting to get the user's Snowflake from the channel topic.
if (userId === null) {
const { channel } = message;
if (!isTextChannel(channel)) {
if (channel.type !== ChannelType.GuildText) {
await message.react('❌');
await message.reply('User was not provided!');
return;
@ -147,13 +142,13 @@ export class RestrictLogsCommand extends Command {
let topic: string[];
// Checks if the channel topic has the user's snowflake
if (
channel.parentId === IDs.categories.modMail &&
channel.topic !== null
) {
topic = channel.topic.split(' ');
userId = topic[2];
if (channel.parentId === IDs.categories.modMail) {
// Checks if the channel topic has the user's snowflake
if (channel.topic !== null) {
topic = channel.topic.split(' ');
// eslint-disable-next-line prefer-destructuring
userId = topic[2];
}
}
}
@ -178,12 +173,14 @@ export class RestrictLogsCommand extends Command {
success: false,
};
const user = await getUser(userId);
let user = guild.client.users.cache.get(userId);
if (!isUser(user)) {
info.message =
'Error fetching user. (You probably provided an incorrect user.)';
return info;
if (user === undefined) {
user = await guild.client.users.fetch(userId);
if (user === undefined) {
info.message = 'Error fetching user';
return info;
}
}
const restrictions = await getRestrictions(userId);
@ -208,15 +205,14 @@ export class RestrictLogsCommand extends Command {
) {
// Get mod names
let restMod = restrictions[i].modId;
const restModMember = await getGuildMember(restMod, guild);
if (isGuildMember(restModMember)) {
const restModMember = guild.members.cache.get(restMod);
if (restModMember !== undefined) {
restMod = restModMember.displayName;
}
let endRestMod = restrictions[i].endModId;
if (endRestMod !== null) {
const endRestModMember = await getGuildMember(endRestMod, guild);
if (isGuildMember(endRestModMember)) {
const endRestModMember = guild.members.cache.get(endRestMod);
if (endRestModMember !== undefined) {
endRestMod = endRestModMember.displayName;
}
}

View File

@ -18,7 +18,7 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { User, Message, MessageFlagsBitField } from 'discord.js';
import type { User, Message } from 'discord.js';
import { restrictRun } from './restrict';
export class RestrictToleranceCommand extends Command {
@ -69,17 +69,15 @@ export class RestrictToleranceCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await restrictRun(user.id, mod.id, reason, guild, true);
const info = await restrictRun(user?.id, mod.id, reason, guild, true);
await interaction.editReply({
content: info.message,
@ -114,7 +112,7 @@ export class RestrictToleranceCommand extends Command {
return;
}
const info = await restrictRun(user.id, mod.id, reason, guild, true);
const info = await restrictRun(user?.id, mod.id, reason, guild, true);
await message.reply(info.message);
await message.react(info.success ? '✅' : '❌');

View File

@ -19,15 +19,9 @@
import { RegisterBehavior } from '@sapphire/framework';
import { Subcommand } from '@sapphire/plugin-subcommands';
import { MessageFlagsBitField } from 'discord.js';
import type { TextChannel } from 'discord.js';
import { CategoryChannel, ChannelType } from 'discord.js';
import IDs from '#utils/ids';
import { isUser } from '#utils/typeChecking';
import {
isCategoryChannel,
isTextChannel,
isVoiceChannel,
} from '@sapphire/discord.js-utilities';
import { getCategoryChannel, getVoiceChannel } from '#utils/fetcher';
export class RestrictToolsCommand extends Subcommand {
public constructor(
@ -84,9 +78,7 @@ export class RestrictToolsCommand extends Subcommand {
const user = interaction.options.getUser('user');
const { guild, channel } = interaction;
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
// Checks if all the variables are of the right type
if (guild === null || channel === null) {
@ -98,8 +90,8 @@ export class RestrictToolsCommand extends Subcommand {
let topic: string[];
if (!isUser(user)) {
if (!isTextChannel(channel)) {
if (user === null) {
if (channel.type !== ChannelType.GuildText) {
await interaction.editReply({
content:
'Please make sure you ran this command in the original restricted text channel!',
@ -138,10 +130,10 @@ export class RestrictToolsCommand extends Subcommand {
await channel.delete();
const vcId = topic[3];
const voiceChannel = await getVoiceChannel(vcId);
const voiceChannel = guild.channels.cache.get(vcId);
if (
isVoiceChannel(voiceChannel) &&
voiceChannel !== undefined &&
voiceChannel.parentId === IDs.categories.restricted
) {
await voiceChannel.delete();
@ -150,47 +142,37 @@ export class RestrictToolsCommand extends Subcommand {
return;
}
const category = await getCategoryChannel(IDs.categories.restricted);
const category = guild.channels.cache.get(IDs.categories.restricted) as
| CategoryChannel
| undefined;
if (!isCategoryChannel(category)) {
if (category === undefined) {
await interaction.editReply({
content: 'Could not find category!',
});
return;
}
const textChannels = category.children.cache.filter((channel) =>
isTextChannel(channel),
const textChannels = category.children.cache.filter(
(c) => c.type === ChannelType.GuildText,
);
for (const c of textChannels) {
const channel = c[1];
// Checks that the channel is a text channel
if (!isTextChannel(channel)) {
continue;
}
// Checks that the channel has a topic
if (channel.topic === null) {
continue;
}
textChannels.forEach((c) => {
const textChannel = c as TextChannel;
// Checks if the channel topic has the user's snowflake
if (channel.topic.includes(user.id)) {
topic = channel.topic.split(' ');
const vcId = topic[topic.indexOf(user.id) + 1];
const voiceChannel = await getVoiceChannel(vcId);
if (textChannel.topic?.includes(user?.id)) {
topic = textChannel.topic.split(' ');
const vcId = topic[topic.indexOf(user?.id) + 1];
const voiceChannel = guild.channels.cache.get(vcId);
if (
isVoiceChannel(voiceChannel) &&
voiceChannel !== undefined &&
voiceChannel.parentId === IDs.categories.restricted
) {
await voiceChannel.delete();
voiceChannel.delete();
}
await channel.delete();
textChannel.delete();
}
}
});
await interaction.editReply({
content: `Successfully deleted the channel for ${user}`,

View File

@ -18,30 +18,15 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import type { Guild, Message, Snowflake, User } from 'discord.js';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import { CategoryChannel, ChannelType, EmbedBuilder } from 'discord.js';
import type { User, Message, TextChannel, Guild, Snowflake } from 'discord.js';
import IDs from '#utils/ids';
import { addExistingUser, fetchRoles } from '#utils/database/dbExistingUser';
import { fetchRoles, addExistingUser } from '#utils/database/dbExistingUser';
import {
checkActive,
unRestrict,
checkActive,
unRestrictLegacy,
} from '#utils/database/moderation/restriction';
import {
getCategoryChannel,
getGuildMember,
getTextBasedChannel,
getUser,
getVoiceChannel,
} from '#utils/fetcher';
import { isUser } from '#utils/typeChecking';
import {
isCategoryChannel,
isGuildMember,
isTextBasedChannel,
isTextChannel,
isVoiceChannel,
} from '@sapphire/discord.js-utilities';
export class UnRestrictCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -84,14 +69,14 @@ export class UnRestrictCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
await interaction.deferReply();
const info = await this.unRestrictRun(user.id, mod.id, guild);
const info = await this.unRestrictRun(user?.id, mod.id, guild);
await interaction.editReply({
content: info.message,
@ -123,7 +108,7 @@ export class UnRestrictCommand extends Command {
const channelRun = message.channel;
const info = await this.unRestrictRun(
user.id,
user?.id,
mod.id,
guild,
channelRun.id,
@ -147,18 +132,21 @@ export class UnRestrictCommand extends Command {
runInVeganRestrict: false,
};
const user = await getUser(userId);
let user = guild.client.users.cache.get(userId);
if (!isUser(user)) {
info.message = 'Error fetching user';
return info;
if (user === undefined) {
user = await guild.client.users.fetch(userId);
if (user === undefined) {
info.message = 'Error fetching user';
return info;
}
}
// Gets mod's GuildMember
const mod = await getGuildMember(modId, guild);
const mod = guild.members.cache.get(modId);
// Checks if guildMember is null
if (!isGuildMember(mod)) {
if (mod === undefined) {
info.message = 'Error fetching mod';
return info;
}
@ -167,9 +155,13 @@ export class UnRestrictCommand extends Command {
await addExistingUser(mod);
// Gets guildMember
const member = await getGuildMember(userId, guild);
let member = guild.members.cache.get(userId);
if (!isGuildMember(member)) {
if (member === undefined) {
member = await guild.members.fetch(userId).catch(() => undefined);
}
if (member === undefined) {
info.message = "Can't unrestrict the user as they are not on this server";
return info;
}
@ -188,20 +180,16 @@ export class UnRestrictCommand extends Command {
if (await checkActive(userId)) {
const roles = await fetchRoles(userId);
await member.roles.add(roles);
// Unrestricts the user on the database
await unRestrict(userId, modId);
} else {
let section = 1;
for (let i = 0; i < restrictRoles.length; i += 1) {
if (member.roles.cache.has(restrictRoles[i])) {
section = i + 1;
}
}
await member.roles.add(IDs.roles.nonvegan.nonvegan);
// Unrestricts the user on the database but for restricts done on the old bot
await unRestrictLegacy(userId, modId, section);
}
@ -210,73 +198,57 @@ export class UnRestrictCommand extends Command {
// Remove vegan restrict channels
if (member.roles.cache.has(IDs.roles.vegan.vegan)) {
const category = await getCategoryChannel(IDs.categories.restricted);
if (!isCategoryChannel(category)) {
info.message =
'Could not find the restricted category! The channels will have to be deleted manually.';
return info;
}
const category = guild.channels.cache.get(IDs.categories.restricted) as
| CategoryChannel
| undefined;
let topic: string[];
const textChannels = category.children.cache.filter((channel) =>
isTextChannel(channel),
);
if (category !== undefined) {
const textChannels = category.children.cache.filter(
(c) => c.type === ChannelType.GuildText,
);
textChannels.forEach((c) => {
const textChannel = c as TextChannel;
// Checks if the channel topic has the user's snowflake
if (textChannel.topic?.includes(userId)) {
if (textChannel.id === channelRun) {
info.runInVeganRestrict = true;
}
topic = textChannel.topic.split(' ');
const vcId = topic[topic.indexOf(userId) + 1];
const voiceChannel = guild.channels.cache.get(vcId);
for (const c of textChannels) {
const channel = c[1];
// Checks that the channel is a text channel
if (!isTextChannel(channel)) {
continue;
}
// Checks that the channel has a topic
if (channel.topic === null) {
continue;
}
// Checks if the channel topic has the user's snowflake
if (channel.topic.includes(userId)) {
if (channel.id === channelRun) {
info.runInVeganRestrict = true;
if (
voiceChannel !== undefined &&
voiceChannel.parentId === IDs.categories.restricted
) {
voiceChannel.delete();
}
textChannel.delete();
}
topic = channel.topic.split(' ');
const vcId = topic[topic.indexOf(user.id) + 1];
const voiceChannel = await getVoiceChannel(vcId);
if (
isVoiceChannel(voiceChannel) &&
// Used for sanitising the channel topic, so another voice channel does not get deleted
voiceChannel.parentId === IDs.categories.restricted
) {
await voiceChannel.delete();
}
await channel.delete();
}
});
}
}
info.success = true;
// Log the ban
const logChannel = await getTextBasedChannel(IDs.channels.logs.restricted);
let logChannel = guild.channels.cache.get(IDs.channels.logs.restricted) as
| TextChannel
| undefined;
if (!isTextBasedChannel(logChannel)) {
this.container.logger.error('Unrestrict: Could not fetch log channel');
info.message = `Unrestricted ${user} but could not find the log channel. This has been logged to the database.`;
return info;
} else if (!logChannel.isSendable()) {
this.container.logger.error(
'Unrestrict: The bot does not have permission to send in the logs channel!',
);
info.message = `Unrestricted ${user} but could not find the log channel. This hasn't been logged in a text channel as the bot does not have permission to send logs!`;
return info;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(
IDs.channels.logs.restricted,
)) as TextChannel | undefined;
if (logChannel === undefined) {
this.container.logger.error(
'Restrict Error: Could not fetch log channel',
);
info.message = `Unrestricted ${user} but could not find the log channel. This has been logged to the database.`;
return info;
}
}
const message = new EmbedBuilder()

View File

@ -18,13 +18,10 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Message, MessageFlagsBitField, TextBasedChannel } from 'discord.js';
import type { Message, TextBasedChannel } from 'discord.js';
import { ChannelType } from 'discord.js';
import { Duration, DurationFormatter } from '@sapphire/time-utilities';
import { isNumber } from '#utils/maths';
import {
isTextBasedChannel,
isTextChannel,
} from '@sapphire/discord.js-utilities';
export class SlowmodeCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -61,11 +58,11 @@ export class SlowmodeCommand extends Command {
const duration = interaction.options.getString('duration', true);
const { channel } = interaction;
if (!isTextBasedChannel(channel)) {
if (channel === null) {
await interaction.reply({
content: 'Could not fetch channel!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -97,7 +94,7 @@ export class SlowmodeCommand extends Command {
message: '',
success: false,
};
if (!isTextChannel(channel)) {
if (channel.type !== ChannelType.GuildText) {
info.message = 'Channel is not a text channel!';
return info;
}

View File

@ -18,10 +18,8 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { GuildMember, Message, MessageFlagsBitField } from 'discord.js';
import type { GuildMember, Message } from 'discord.js';
import IDs from '#utils/ids';
import { getGuildMember } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class SoftMuteCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -66,39 +64,39 @@ export class SoftMuteCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching the guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
// Gets GuildMember whilst removing the ability of each other variables being null
const member = await getGuildMember(user.id, guild);
// Gets guildMember whilst removing the ability of each other variables being null
const guildMember = guild.members.cache.get(user.id);
// Checks if guildMember is null
if (!isGuildMember(member)) {
if (guildMember === undefined) {
await interaction.reply({
content: 'Error fetching user!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
if (member.roles.cache.has(IDs.roles.restrictions.softMute)) {
await member.roles.remove(IDs.roles.restrictions.softMute);
if (guildMember.roles.cache.has(IDs.roles.restrictions.softMute)) {
await guildMember.roles.remove(IDs.roles.restrictions.softMute);
await interaction.reply({
content: `Removed soft muted for ${user}`,
withResponse: true,
fetchReply: true,
});
return;
}
await member.roles.add(IDs.roles.restrictions.softMute);
await guildMember.roles.add(IDs.roles.restrictions.softMute);
await interaction.reply({
content: `Soft muted ${user}`,
withResponse: true,
fetchReply: true,
});
}

View File

@ -27,6 +27,8 @@ import {
ButtonStyle,
User,
Guild,
TextChannel,
GuildMember,
Snowflake,
MessageFlagsBitField,
} from 'discord.js';
@ -41,13 +43,6 @@ import {
import { checkStaff } from '#utils/checker';
import IDs from '#utils/ids';
import { createSusLogEmbed } from '#utils/embeds';
import { getGuildMember, getTextBasedChannel, getUser } from '#utils/fetcher';
import { isUser } from '#utils/typeChecking';
import {
isGuildMember,
isTextBasedChannel,
isTextChannel,
} from '@sapphire/discord.js-utilities';
// TODO add a check when they join the server to give the user the sus role again
@ -234,20 +229,19 @@ export class SusCommand extends Subcommand {
info.success = true;
// Log the sus note
const logChannel = await getTextBasedChannel(IDs.channels.logs.sus);
let logChannel = guild.channels.cache.get(IDs.channels.logs.sus) as
| TextChannel
| undefined;
if (!isTextBasedChannel(logChannel)) {
this.container.logger.error('Sus: Could not fetch log channel.');
info.message = `Added a sus note for ${user} but could not find the log channel. This has been logged to the database.`;
return info;
} else if (!logChannel.isSendable()) {
this.container.logger.error(
'Sus: Does not have permission to message in the log channel.',
);
info.message = `Added a sus note for ${user} but could not send in the logs channel. This has been logged to the database.`;
return info;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(IDs.channels.logs.sus)) as
| TextChannel
| undefined;
if (logChannel === undefined) {
this.container.logger.error('Sus Error: Could not fetch log channel');
info.message = `Added a sus note for ${user} but could not find the log channel. This has been logged to the database.`;
return info;
}
}
const message = new EmbedBuilder()
@ -271,9 +265,15 @@ export class SusCommand extends Subcommand {
private async addSusRole(user: User, guild: Guild) {
// Get GuildMember for user to add a sus note for
const member = await getGuildMember(user.id, guild);
let member = guild.members.cache.get(user.id);
if (!isGuildMember(member)) {
// Checks if Member was not found in cache
if (member === undefined) {
// Fetches Member from API call to Discord
member = await guild.members.fetch(user.id).catch(() => undefined);
}
if (member === undefined) {
return;
}
@ -289,7 +289,7 @@ export class SusCommand extends Subcommand {
const { guild } = interaction;
// Checks if all the variables are of the right type
if (guild === null) {
if (guild == null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
@ -330,7 +330,7 @@ export class SusCommand extends Subcommand {
const { guild, channel } = interaction;
// Checks if all the variables are of the right type
if (guild === null || !isTextBasedChannel(channel)) {
if (guild === null || channel === null) {
await interaction.reply({
content: 'Error fetching guild or channel!',
flags: MessageFlagsBitField.Flags.Ephemeral,
@ -356,8 +356,11 @@ export class SusCommand extends Subcommand {
const modId = note.modId;
// Get user GuildMembers for user and mod and person who ran command
const user = await getUser(userId);
if (!isUser(user)) {
let user = guild.client.users.cache.get(userId);
if (!(user instanceof User)) {
user = await guild.client.users.fetch(userId).catch(() => undefined);
}
if (user === undefined) {
await interaction.reply({
content: 'Error fetching user!',
flags: MessageFlagsBitField.Flags.Ephemeral,
@ -366,11 +369,15 @@ export class SusCommand extends Subcommand {
return;
}
const modCreator = await getUser(modId);
let modCreator = guild.client.users.cache.get(modId);
if (!(modCreator instanceof User)) {
modCreator = await guild.client.users.fetch(modId).catch(() => undefined);
}
const modCreatorDisplay = isUser(modCreator)
? modCreator.displayName
: modId;
let modCreatorDisplay = modId;
if (modCreator instanceof User) {
modCreatorDisplay = modCreator.displayName;
}
// Create an embed for the note
const noteEmbed = new EmbedBuilder()
@ -436,15 +443,18 @@ export class SusCommand extends Subcommand {
// Checks if there are no notes on the user and if there's none, remove the sus role
if (notes.length === 0) {
const member = guild.members.cache.get(userId);
let member = guild.members.cache.get(userId);
if (!(member instanceof GuildMember)) {
member = await guild.members.fetch(userId).catch(() => undefined);
}
if (isGuildMember(member)) {
if (member instanceof GuildMember) {
await member.roles.remove(IDs.roles.restrictions.sus);
}
}
// Logs the removal of the sus note
await this.deleteNoteLogger(userId, mod, noteId);
await this.deleteNoteLogger(userId, mod, noteId, guild);
}
});
@ -457,22 +467,32 @@ export class SusCommand extends Subcommand {
}
// Logs removal of 1 sus note
private async deleteNoteLogger(userId: Snowflake, mod: User, noteId: number) {
private async deleteNoteLogger(
userId: Snowflake,
mod: User,
noteId: number,
guild: Guild,
) {
// Find user
const user = await getUser(userId);
if (!isUser(user)) return;
let user = guild.client.users.cache.get(userId);
if (user === undefined) {
user = await guild.client.users.fetch(userId).catch(() => undefined);
}
if (user === undefined) return;
// Log the sus note
const logChannel = await getTextBasedChannel(IDs.channels.logs.sus);
let logChannel = guild.channels.cache.get(IDs.channels.logs.sus) as
| TextChannel
| undefined;
if (!isTextBasedChannel(logChannel)) {
this.container.logger.error('Sus: Could not fetch log channel.');
return;
} else if (!logChannel.isSendable()) {
this.container.logger.error(
'Sus: The bot does not have permission to send in the log channel',
);
return;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(IDs.channels.logs.sus)) as
| TextChannel
| undefined;
if (logChannel === undefined) {
this.container.logger.error('Sus Error: Could not fetch log channel');
return;
}
}
const embed = new EmbedBuilder()
@ -501,7 +521,7 @@ export class SusCommand extends Subcommand {
const { guild, channel } = interaction;
// Checks if all the variables are of the right type
if (guild === null || !isTextBasedChannel(channel)) {
if (guild === null || channel === null) {
await interaction.reply({
content: 'Error fetching guild or channel!',
flags: MessageFlagsBitField.Flags.Ephemeral,
@ -510,10 +530,10 @@ export class SusCommand extends Subcommand {
return;
}
const member = await getGuildMember(user.id, guild);
const member = guild.members.cache.get(user.id);
// Checks if managed to find GuildMember for the user
if (!isGuildMember(member)) {
if (member === undefined) {
await interaction.reply({
content: 'Error fetching user!',
flags: MessageFlagsBitField.Flags.Ephemeral,
@ -550,11 +570,10 @@ export class SusCommand extends Subcommand {
) {
// Get mod name
let mod = notes[i].modId;
const modGuildMember = await getGuildMember(mod, guild);
if (isGuildMember(modGuildMember)) {
const modGuildMember = guild.members.cache.get(mod);
if (modGuildMember !== undefined) {
mod = modGuildMember.displayName;
}
// Add sus note to embed
noteEmbed.addFields({
name: `Sus ID: ${
@ -614,7 +633,7 @@ export class SusCommand extends Subcommand {
});
}
await this.deleteAllNotesLogger(user, mod);
await this.deleteAllNotesLogger(user, mod, guild);
});
// Remove the buttons after they have been clicked
@ -629,18 +648,20 @@ export class SusCommand extends Subcommand {
}
// Logs removal of 1 sus note
private async deleteAllNotesLogger(user: User, mod: User) {
private async deleteAllNotesLogger(user: User, mod: User, guild: Guild) {
// Log the sus note
const logChannel = await getTextBasedChannel(IDs.channels.logs.sus);
let logChannel = guild.channels.cache.get(IDs.channels.logs.sus) as
| TextChannel
| undefined;
if (!isTextChannel(logChannel)) {
this.container.logger.error('Sus: Could not fetch log channel.');
return;
} else if (!logChannel.isSendable()) {
this.container.logger.error(
'Sus: Could not not send in the log channel.',
);
return;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(IDs.channels.logs.sus)) as
| TextChannel
| undefined;
if (logChannel === undefined) {
this.container.logger.error('Sus Error: Could not fetch log channel');
return;
}
}
const embed = new EmbedBuilder()

View File

@ -18,15 +18,13 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { GuildMember, Message, MessageFlagsBitField } from 'discord.js';
import type { GuildMember, Message } from 'discord.js';
import {
addMute,
removeMute,
checkActive,
} from '#utils/database/moderation/vcMute';
import { addExistingUser } from '#utils/database/dbExistingUser';
import { getGuildMember } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class VCMuteCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -68,38 +66,29 @@ export class VCMuteCommand extends Command {
// Get the arguments
const user = interaction.options.getUser('user', true);
const reason = interaction.options.getString('reason');
const mod = interaction.member;
const modUser = interaction.user;
const { guild } = interaction;
// Checks if all the variables are of the right type
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
// Gets guildMember whilst removing the ability of each other variables being null
const member = await getGuildMember(user.id, guild);
const member = guild.members.cache.get(user.id);
const mod = guild.members.cache.get(modUser.id);
// Checks if `member` was found
if (!isGuildMember(member)) {
// Checks if guildMember is null
if (member === undefined || mod === undefined) {
await interaction.reply({
content: 'Error fetching user!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
});
return;
}
// Checks if `mod` was found
if (!isGuildMember(mod)) {
await interaction.reply({
content: 'Error fetching your user!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -113,8 +102,8 @@ export class VCMuteCommand extends Command {
await interaction.reply({
content: `Removed server mute from ${user}`,
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
fetchReply: true,
ephemeral: true,
});
return;
}
@ -129,8 +118,8 @@ export class VCMuteCommand extends Command {
await addMute(member.id, mod.id, reason);
await interaction.reply({
content: `Server muted ${user}`,
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
fetchReply: true,
ephemeral: true,
});
}
@ -148,7 +137,7 @@ export class VCMuteCommand extends Command {
const reason = args.finished ? null : await args.rest('string');
const mod = message.member;
if (!isGuildMember(mod)) {
if (mod === null) {
await message.react('❌');
await message.reply(
'Moderator not found! Try again or contact a developer!',

View File

@ -18,17 +18,14 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import type { Message, User } from 'discord.js';
import { EmbedBuilder, TextChannel } from 'discord.js';
import type { Message, Guild, User } from 'discord.js';
import IDs from '#utils/ids';
import {
deleteWarning,
fetchWarning,
} from '#utils/database/moderation/warnings';
import { checkStaff } from '#utils/checker';
import { getTextBasedChannel, getUser } from '#utils/fetcher';
import { isUser } from '#utils/typeChecking';
import { isTextChannel } from '@sapphire/discord.js-utilities';
export class DeleteWarningCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -65,14 +62,23 @@ export class DeleteWarningCommand extends Command {
// Get the arguments
const warningId = interaction.options.getInteger('id', true);
const mod = interaction.user;
const { guild } = interaction;
// Checks if all the variables are of the right type
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
ephemeral: true,
fetchReply: true,
});
return;
}
const staffChannel = checkStaff(interaction.channel);
await interaction.deferReply({
flags: staffChannel ? undefined : MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: !staffChannel });
const info = await this.deleteWarning(warningId, mod);
const info = await this.deleteWarning(warningId, mod, guild);
await interaction.editReply({
content: info.message,
@ -102,7 +108,7 @@ export class DeleteWarningCommand extends Command {
return;
}
const info = await this.deleteWarning(warningId, mod);
const info = await this.deleteWarning(warningId, mod, guild);
await message.reply({ content: info.message, embeds: info.embeds });
if (!info.success) {
@ -110,7 +116,7 @@ export class DeleteWarningCommand extends Command {
}
}
private async deleteWarning(warningId: number, mod: User) {
private async deleteWarning(warningId: number, mod: User, guild: Guild) {
const info = {
message: '',
embeds: [] as EmbedBuilder[],
@ -128,34 +134,34 @@ export class DeleteWarningCommand extends Command {
info.success = true;
const userId = warning.userId;
const user = await getUser(userId);
let user = guild.client.users.cache.get(userId);
if (!isUser(user)) {
info.message = `Deleted warning ID \`${warningId}\`, but the user could not be found!`;
return info;
if (user === undefined) {
user = await guild.client.users.fetch(userId);
if (user === undefined) {
info.message = `Deleted warning ID \`${warningId}\`, but the user could not be found!`;
return info;
}
}
// Log the warnings deletion
const logChannel = await getTextBasedChannel(IDs.channels.logs.sus);
let logChannel = guild.channels.cache.get(IDs.channels.logs.sus) as
| TextChannel
| undefined;
if (!isTextChannel(logChannel)) {
this.container.logger.error(
'Delete Warning: Could not fetch log channel',
);
info.message =
`Deleted warning for ${user} (Warning ID: ${warningId} but ` +
'could not find the log channel.';
return info;
} else if (!logChannel.isSendable()) {
this.container.logger.error(
'Delete Warning: The bot does not have permission to send in the logs channel!',
);
info.message =
`Deleted warning for ${user} (Warning ID: ${warningId} but ` +
"But this hasn't been logged in a text channel as the bot does not have permission to send logs!";
return info;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(IDs.channels.logs.sus)) as
| TextChannel
| undefined;
if (logChannel === undefined) {
this.container.logger.error(
'Delete Warning Error: Could not fetch log channel',
);
info.message =
`Deleted warning for ${user} (Warning ID: ${warningId} but ` +
'could not find the log channel.';
return info;
}
}
const message = new EmbedBuilder()

View File

@ -17,21 +17,17 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import {
EmbedBuilder,
Guild,
Message,
MessageFlagsBitField,
Snowflake,
User,
} from 'discord.js';
Args,
Command,
container,
RegisterBehavior,
} from '@sapphire/framework';
import type { User, Message, Snowflake, Guild, TextChannel } from 'discord.js';
import { updateUser } from '#utils/database/dbExistingUser';
import { addWarn } from '#utils/database/moderation/warnings';
import { EmbedBuilder } from 'discord.js';
import IDs from '#utils/ids';
import { getGuildMember, getTextBasedChannel, getUser } from '#utils/fetcher';
import { isGuildMember, isTextChannel } from '@sapphire/discord.js-utilities';
import { isUser } from '#utils/typeChecking';
export class WarnCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -80,8 +76,8 @@ export class WarnCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -107,7 +103,7 @@ export class WarnCommand extends Command {
return;
}
const reason = args.finished ? null : await args.rest('string');
const mod = message.author;
const mod = message.member;
if (reason === null) {
await message.react('❌');
@ -115,6 +111,14 @@ export class WarnCommand extends Command {
return;
}
if (mod === null) {
await message.react('❌');
await message.reply(
'Moderator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -145,10 +149,10 @@ export class WarnCommand extends Command {
};
// Gets mod's GuildMember
const mod = await getGuildMember(modId, guild);
const mod = guild.members.cache.get(modId);
// Checks if guildMember is null
if (!isGuildMember(mod)) {
if (mod === undefined) {
info.message = 'Error fetching mod!';
return info;
}
@ -157,11 +161,14 @@ export class WarnCommand extends Command {
await updateUser(mod);
// Gets User for person being restricted
const user = await getUser(userId);
let user = guild.client.users.cache.get(userId);
if (!isUser(user)) {
info.message = 'Error fetching user';
return info;
if (user === undefined) {
user = await guild.client.users.fetch(userId);
if (user === undefined) {
info.message = 'Error fetching user';
return info;
}
}
await addWarn(userId, modId, reason);
@ -183,20 +190,19 @@ export class WarnCommand extends Command {
await user.send({ embeds: [dmEmbed] }).catch(() => {});
// Log the ban
const logChannel = await getTextBasedChannel(IDs.channels.logs.sus);
let logChannel = guild.channels.cache.get(IDs.channels.logs.sus) as
| TextChannel
| undefined;
if (!isTextChannel(logChannel)) {
this.container.logger.error('Warn: Could not fetch log channel');
info.message = `Warned ${user} but could not find the log channel. This has been logged to the database.`;
return info;
} else if (!logChannel.isSendable()) {
this.container.logger.error(
'Warn: The bot does not have permission to send in the logs channel!',
);
info.message = `Warned ${user}, but the bot does not have permission to send in the logs channel!`;
return info;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(IDs.channels.logs.sus)) as
| TextChannel
| undefined;
if (logChannel === undefined) {
container.logger.error('Warn Error: Could not fetch log channel');
info.message = `Warned ${user} but could not find the log channel. This has been logged to the database.`;
return info;
}
}
const message = new EmbedBuilder()

View File

@ -18,15 +18,12 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { EmbedBuilder, MessageFlagsBitField } from 'discord.js';
import { ChannelType, EmbedBuilder } from 'discord.js';
import type { Message, Guild, User } from 'discord.js';
import IDs from '#utils/ids';
import { fetchWarnings } from '#utils/database/moderation/warnings';
import { checkStaff } from '#utils/checker';
import { createWarningsEmbed } from '#utils/embeds';
import { isUser } from '#utils/typeChecking';
import { isTextChannel } from '@sapphire/discord.js-utilities';
import { getUser } from '#utils/fetcher';
export class WarningsCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -68,17 +65,15 @@ export class WarningsCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
const staffChannel = checkStaff(interaction.channel);
await interaction.deferReply({
flags: staffChannel ? undefined : MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: !staffChannel });
const info = await this.warnings(user, guild);
@ -106,10 +101,10 @@ export class WarningsCommand extends Command {
return;
}
if (!isUser(user)) {
if (user === undefined) {
const { channel } = message;
if (!isTextChannel(channel)) {
if (channel.type !== ChannelType.GuildText) {
await message.react('❌');
await message.reply('User was not provided!');
return;
@ -124,16 +119,18 @@ export class WarningsCommand extends Command {
// eslint-disable-next-line prefer-destructuring
const userId = topic[2];
user = await getUser(userId);
user = guild.client.users.cache.get(userId);
if (user === undefined) {
user = await guild.client.users.fetch(userId);
}
}
}
}
if (!isUser(user)) {
if (user === undefined) {
await message.react('❌');
await message.reply(
'User was not provided! (You most likely provided a user incorrectly.)',
);
await message.reply('User was not provided!');
return;
}

View File

@ -19,12 +19,7 @@
import { Subcommand } from '@sapphire/plugin-subcommands';
import { RegisterBehavior } from '@sapphire/framework';
import {
ChannelType,
MessageFlagsBitField,
PermissionsBitField,
Snowflake,
} from 'discord.js';
import { ChannelType, PermissionsBitField, Snowflake } from 'discord.js';
import { updateUser } from '#utils/database/dbExistingUser';
import {
addStatUser,
@ -41,11 +36,6 @@ import {
} from '#utils/database/outreach';
import IDs from '#utils/ids';
import { EmbedBuilder } from 'discord.js';
import {
isGuildMember,
isTextBasedChannel,
} from '@sapphire/discord.js-utilities';
import { getGuildMember, getTextBasedChannel } from '#utils/fetcher';
export class OutreachCommand extends Subcommand {
public constructor(
@ -194,21 +184,23 @@ export class OutreachCommand extends Subcommand {
interaction: Subcommand.ChatInputCommandInteraction,
) {
// const start = interaction.options.getBoolean('start');
const mod = interaction.member;
const modUser = interaction.user;
const { guild } = interaction;
if (guild === null) {
await interaction.reply({
content: 'Mod or guild was not found!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
if (!isGuildMember(mod)) {
const mod = guild.members.cache.get(modUser.id);
if (mod === undefined) {
await interaction.reply({
content: 'Outreach Leader was not found!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -216,7 +208,7 @@ export class OutreachCommand extends Subcommand {
if (!mod.roles.cache.has(IDs.roles.staff.outreachLeader)) {
await interaction.reply({
content: 'You need to be an Outreach Leader to run this command!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -224,37 +216,39 @@ export class OutreachCommand extends Subcommand {
if (await checkActiveEvent()) {
await interaction.reply({
content: 'There is already an active event!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
await updateUser(mod);
await createEvent(mod.id);
await createEvent(modUser.id);
await interaction.reply({
content: 'Created the event!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
}
public async eventEnd(interaction: Subcommand.ChatInputCommandInteraction) {
const mod = interaction.member;
const modUser = interaction.user;
const { guild } = interaction;
if (guild === null) {
await interaction.reply({
content: 'Guild not found!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
if (!isGuildMember(mod)) {
const mod = guild.members.cache.get(modUser.id);
if (mod === undefined) {
await interaction.reply({
content: 'Your guild member was not found!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -262,14 +256,12 @@ export class OutreachCommand extends Subcommand {
if (!mod.roles.cache.has(IDs.roles.staff.outreachLeader)) {
await interaction.reply({
content: 'You need to be an Outreach Leader to run this command!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const event = await getCurrentEvent();
@ -307,9 +299,9 @@ export class OutreachCommand extends Subcommand {
educated += group.educated;
});
const activist = await getTextBasedChannel(IDs.channels.activism.activism);
const activist = guild.channels.cache.get(IDs.channels.activism.activism);
if (!isTextBasedChannel(activist)) {
if (activist === undefined || !activist.isTextBased()) {
await interaction.editReply(
'Event has now ended, but could not post statistics!',
);
@ -359,14 +351,12 @@ export class OutreachCommand extends Subcommand {
if (guild === null) {
await interaction.reply({
content: 'Guild not found!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
if ((await getStatFromLeader(leader.id)) !== null) {
await interaction.editReply(
@ -387,9 +377,9 @@ export class OutreachCommand extends Subcommand {
const statGroups = await getStatGroups(event.id);
const groupNo = statGroups.length + 1;
const leaderMember = await getGuildMember(leader.id, guild);
const leaderMember = await guild.members.cache.get(leader.id);
if (!isGuildMember(leaderMember)) {
if (leaderMember === undefined) {
await interaction.editReply({
content: `Could not find ${leader}'s guild member.`,
});
@ -466,27 +456,18 @@ export class OutreachCommand extends Subcommand {
public async groupAdd(interaction: Subcommand.ChatInputCommandInteraction) {
const user = interaction.options.getUser('user', true);
const group = interaction.options.getRole('group');
const leader = interaction.member;
const leader = interaction.user;
const { guild } = interaction;
if (guild === null) {
await interaction.reply({
content: 'Could not find guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
if (!isGuildMember(leader)) {
await interaction.editReply({
content: 'Could not find your GuildMember!',
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
let statId: number;
let roleId: Snowflake | undefined;
@ -502,9 +483,18 @@ export class OutreachCommand extends Subcommand {
return;
}
const leaderMember = guild.members.cache.get(leader.id);
if (leaderMember === undefined) {
await interaction.editReply({
content: 'Could not find your GuildMember in cache!',
});
return;
}
if (
leader.id !== stat.stat.leaderId &&
!leader.roles.cache.has(IDs.roles.staff.outreachLeader)
!leaderMember.roles.cache.has(IDs.roles.staff.outreachLeader)
) {
await interaction.editReply({
content: `You are not the leader for ${group}`,
@ -536,9 +526,9 @@ export class OutreachCommand extends Subcommand {
return;
}
const member = await getGuildMember(user.id, guild);
const member = guild.members.cache.get(user.id);
if (!isGuildMember(member)) {
if (member === undefined) {
await interaction.editReply({
content: 'Could not fetch the member!',
});
@ -578,9 +568,15 @@ export class OutreachCommand extends Subcommand {
educated: educated !== null ? educated : 0,
};
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
if (leader === null) {
await interaction.reply({
content: 'Could not find your user!',
ephemeral: true,
});
return;
}
await interaction.deferReply({ ephemeral: true });
const stat = await getStatFromLeader(leader.id);

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class BookClubCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -65,15 +62,13 @@ export class BookClubCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageBookClub(user, mod, guild);
@ -93,6 +88,14 @@ export class BookClubCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Event coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -112,16 +115,16 @@ export class BookClubCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const bookClub = await getRole(IDs.roles.bookClub, guild);
const member = guild.members.cache.get(user.id);
const bookClub = guild.roles.cache.get(IDs.roles.bookClub);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(bookClub)) {
if (bookClub === undefined) {
info.message = 'Error fetching book club role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class DebateHostCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -66,15 +63,13 @@ export class DebateHostCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageDebateHost(user, mod, guild);
@ -94,6 +89,14 @@ export class DebateHostCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Event coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -113,16 +116,16 @@ export class DebateHostCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const debateHost = await getRole(IDs.roles.debateHost, guild);
const member = guild.members.cache.get(user.id);
const debateHost = guild.roles.cache.get(IDs.roles.debateHost);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(debateHost)) {
if (debateHost === undefined) {
info.message = 'Error fetching debate host role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class GameNightHostCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -65,15 +62,13 @@ export class GameNightHostCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageGameNight(user, mod, guild);
@ -93,6 +88,14 @@ export class GameNightHostCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Event coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -112,16 +115,16 @@ export class GameNightHostCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const gameNightHost = await getRole(IDs.roles.gameNightHost, guild);
const member = guild.members.cache.get(user.id);
const gameNightHost = guild.roles.cache.get(IDs.roles.gameNightHost);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(gameNightHost)) {
if (gameNightHost === undefined) {
info.message = 'Error fetching game night host role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class GuestCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -65,15 +62,13 @@ export class GuestCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageGuest(user, mod, guild);
@ -93,6 +88,14 @@ export class GuestCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Event coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -112,16 +115,16 @@ export class GuestCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const guest = await getRole(IDs.roles.guest, guild);
const member = guild.members.cache.get(user.id);
const guest = guild.roles.cache.get(IDs.roles.guest);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(guest)) {
if (guest === undefined) {
info.message = 'Error fetching guest role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { isRole } from '#utils/typeChecking';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class MentorCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -66,15 +63,13 @@ export class MentorCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageMentor(user, mod, guild);
@ -94,6 +89,14 @@ export class MentorCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Mentor coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -113,16 +116,16 @@ export class MentorCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const mentor = await getRole(IDs.roles.staff.mentor, guild);
const member = guild.members.cache.get(user.id);
const mentor = guild.roles.cache.get(IDs.roles.staff.mentor);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(mentor)) {
if (mentor === undefined) {
info.message = 'Error fetching mentor role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class ModCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -65,15 +62,13 @@ export class ModCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageMod(user, mod, guild);
@ -93,6 +88,14 @@ export class ModCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Mod coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -112,16 +115,16 @@ export class ModCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const moderator = await getRole(IDs.roles.staff.moderator, guild);
const member = guild.members.cache.get(user.id);
const moderator = guild.roles.cache.get(IDs.roles.staff.moderator);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(moderator)) {
if (moderator === undefined) {
info.message = 'Error fetching the moderator role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class RestrictedAccessCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -66,15 +63,13 @@ export class RestrictedAccessCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageRestrictedAccess(user, mod, guild);
@ -94,6 +89,14 @@ export class RestrictedAccessCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Mod coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -113,16 +116,16 @@ export class RestrictedAccessCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const restricted = await getRole(IDs.roles.staff.restricted, guild);
const member = guild.members.cache.get(user.id);
const restricted = guild.roles.cache.get(IDs.roles.staff.restricted);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(restricted)) {
if (restricted === undefined) {
info.message = 'Error fetching the restricted access role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class StageHostCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -65,15 +62,13 @@ export class StageHostCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageStageHost(user, mod, guild);
@ -93,6 +88,14 @@ export class StageHostCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Event coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -112,16 +115,16 @@ export class StageHostCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const stageHost = await getRole(IDs.roles.stageHost, guild);
const member = guild.members.cache.get(user.id);
const stageHost = guild.roles.cache.get(IDs.roles.stageHost);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(stageHost)) {
if (stageHost === undefined) {
info.message = 'Error fetching stage host role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class TrialModCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -66,15 +63,13 @@ export class TrialModCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageMod(user, mod, guild);
@ -94,6 +89,14 @@ export class TrialModCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Mod coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -113,16 +116,16 @@ export class TrialModCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const moderator = await getRole(IDs.roles.staff.trialModerator, guild);
const member = guild.members.cache.get(user.id);
const moderator = guild.roles.cache.get(IDs.roles.staff.trialModerator);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(moderator)) {
if (moderator === undefined) {
info.message = 'Error fetching the trial moderator role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class TrialVerifierCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -65,15 +62,13 @@ export class TrialVerifierCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageTrialVerifier(user, mod, guild);
@ -93,6 +88,14 @@ export class TrialVerifierCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Verifier coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -112,16 +115,16 @@ export class TrialVerifierCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const trialVerifier = await getRole(IDs.roles.staff.trialVerifier, guild);
const member = guild.members.cache.get(user.id);
const trialVerifier = guild.roles.cache.get(IDs.roles.staff.trialVerifier);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(trialVerifier)) {
if (trialVerifier === undefined) {
info.message = 'Error fetching the trial verifier role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class VerifierCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -65,15 +62,13 @@ export class VerifierCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageVerifier(user, mod, guild);
@ -93,6 +88,14 @@ export class VerifierCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Verifier coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -112,16 +115,16 @@ export class VerifierCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const verifier = await getRole(IDs.roles.staff.verifier, guild);
const member = guild.members.cache.get(user.id);
const verifier = guild.roles.cache.get(IDs.roles.staff.verifier);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(verifier)) {
if (verifier === undefined) {
info.message = 'Error fetching verifier role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class ActivistCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -68,15 +65,13 @@ export class ActivistCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageActivist(user, mod, guild);
@ -96,6 +91,12 @@ export class ActivistCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply('Staff not found! Try again or contact a developer!');
return;
}
const { guild } = message;
if (guild === null) {
@ -115,22 +116,22 @@ export class ActivistCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const modMember = await getGuildMember(mod.id, guild);
const activist = await getRole(IDs.roles.vegan.activist, guild);
const member = guild.members.cache.get(user.id);
const modMember = guild.members.cache.get(mod.id);
const activist = guild.roles.cache.get(IDs.roles.vegan.activist);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isGuildMember(modMember)) {
if (modMember === undefined) {
info.message = "Error fetching the staff's guild member!";
return info;
}
if (!isRole(activist)) {
if (activist === undefined) {
info.message = 'Error fetching activist role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class ARAVeganCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -67,15 +64,13 @@ export class ARAVeganCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageVegan(user, mod, guild);
@ -95,6 +90,12 @@ export class ARAVeganCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply('Staff not found! Try again or contact a developer!');
return;
}
const { guild } = message;
if (guild === null) {
@ -114,22 +115,22 @@ export class ARAVeganCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const modMember = await getGuildMember(mod.id, guild);
const vegan = await getRole(IDs.roles.vegan.araVegan, guild);
const member = guild.members.cache.get(user.id);
const modMember = guild.members.cache.get(mod.id);
const vegan = guild.roles.cache.get(IDs.roles.vegan.araVegan);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isGuildMember(modMember)) {
if (modMember === undefined) {
info.message = "Error fetching the staff's guild member!";
return info;
}
if (!isRole(vegan)) {
if (vegan === undefined) {
info.message = 'Error fetching vegan role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class ConvincedCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -66,15 +63,13 @@ export class ConvincedCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageConvinced(user, mod, guild);
@ -94,6 +89,12 @@ export class ConvincedCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply('Mod not found! Try again or contact a developer!');
return;
}
const { guild } = message;
if (guild === null) {
@ -113,16 +114,16 @@ export class ConvincedCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const convinced = await getRole(IDs.roles.nonvegan.convinced, guild);
const member = guild.members.cache.get(user.id);
const convinced = guild.roles.cache.get(IDs.roles.nonvegan.convinced);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(convinced)) {
if (convinced === undefined) {
info.message = 'Error fetching coordinator role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class PlusCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -66,7 +63,7 @@ export class PlusCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -91,6 +88,14 @@ export class PlusCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply(
'Coordinator not found! Try again or contact a developer!',
);
return;
}
const { guild } = message;
if (guild === null) {
@ -110,16 +115,16 @@ export class PlusCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const plus = await getRole(IDs.roles.vegan.plus, guild);
const member = guild.members.cache.get(user.id);
const plus = guild.roles.cache.get(IDs.roles.vegan.plus);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(plus)) {
if (plus === undefined) {
info.message = 'Error fetching plus role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class TrustedCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -66,15 +63,13 @@ export class TrustedCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageTrusted(user, mod, guild);
@ -94,6 +89,12 @@ export class TrustedCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply('Mod not found! Try again or contact a developer!');
return;
}
const { guild } = message;
if (guild === null) {
@ -113,16 +114,16 @@ export class TrustedCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const trusted = await getRole(IDs.roles.trusted, guild);
const member = guild.members.cache.get(user.id);
const trusted = guild.roles.cache.get(IDs.roles.trusted);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isRole(trusted)) {
if (trusted === undefined) {
info.message = 'Error fetching trusted role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class VeganCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -68,15 +65,13 @@ export class VeganCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageVegan(user, mod, guild);
@ -96,6 +91,12 @@ export class VeganCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply('Staff not found! Try again or contact a developer!');
return;
}
const { guild } = message;
if (guild === null) {
@ -115,22 +116,22 @@ export class VeganCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const modMember = await getGuildMember(mod.id, guild);
const vegan = await getRole(IDs.roles.vegan.vegan, guild);
const member = guild.members.cache.get(user.id);
const modMember = guild.members.cache.get(mod.id);
const vegan = guild.roles.cache.get(IDs.roles.vegan.vegan);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isGuildMember(modMember)) {
if (modMember === undefined) {
info.message = "Error fetching the staff's guild member!";
return info;
}
if (!isRole(vegan)) {
if (vegan === undefined) {
info.message = 'Error fetching vegan role from cache!';
return info;
}

View File

@ -18,12 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { Guild, User, Message, MessageFlagsBitField } from 'discord.js';
import type { Guild, User, Message } from 'discord.js';
import IDs from '#utils/ids';
import { roleAddLog, roleRemoveLog } from '#utils/logging/role';
import { getGuildMember, getRole } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
import { isRole } from '#utils/typeChecking';
export class VegCuriousCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -66,15 +63,13 @@ export class VegCuriousCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const info = await this.manageVegCurious(user, mod, guild);
@ -94,6 +89,12 @@ export class VegCuriousCommand extends Command {
const mod = message.author;
if (mod === null) {
await message.react('❌');
await message.reply('Staff not found! Try again or contact a developer!');
return;
}
const { guild } = message;
if (guild === null) {
@ -113,22 +114,22 @@ export class VegCuriousCommand extends Command {
message: '',
success: false,
};
const member = await getGuildMember(user.id, guild);
const modMember = await getGuildMember(mod.id, guild);
const vegCurious = await getRole(IDs.roles.nonvegan.vegCurious, guild);
const member = guild.members.cache.get(user.id);
const modMember = guild.members.cache.get(mod.id);
const vegCurious = guild.roles.cache.get(IDs.roles.nonvegan.vegCurious);
// Checks if user's GuildMember was found in cache
if (!isGuildMember(member)) {
if (member === undefined) {
info.message = 'Error fetching guild member for the user!';
return info;
}
if (!isGuildMember(modMember)) {
if (modMember === undefined) {
info.message = "Error fetching the staff's guild member!";
return info;
}
if (!isRole(vegCurious)) {
if (vegCurious === undefined) {
info.message = 'Error fetching veg curious role from cache!';
return info;
}

View File

@ -18,7 +18,7 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { Message, MessageFlagsBitField } from 'discord.js';
import type { Message } from 'discord.js';
export class ApplyCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -47,8 +47,8 @@ export class ApplyCommand extends Command {
public async chatInputRun(interaction: Command.ChatInputCommandInteraction) {
await interaction.reply({
content: this.message,
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
fetchReply: true,
ephemeral: true,
});
}

View File

@ -18,10 +18,8 @@
*/
import { Command, RegisterBehavior } from '@sapphire/framework';
import { Message, MessageFlagsBitField } from 'discord.js';
import type { Message } from 'discord.js';
import IDs from '#utils/ids';
import { getRole } from '#utils/fetcher';
import { isRole } from '#utils/typeChecking';
export class RenameUserCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -49,22 +47,22 @@ export class RenameUserCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await guild.members.fetch();
const vegan = await getRole(IDs.roles.vegan.vegan, guild);
const notVegan = await getRole(IDs.roles.nonvegan.nonvegan, guild);
const vegan = await guild.roles.cache.get(IDs.roles.vegan.vegan);
const notVegan = await guild.roles.cache.get(IDs.roles.nonvegan.nonvegan);
if (!isRole(vegan) || !isRole(notVegan)) {
if (vegan === undefined || notVegan === undefined) {
await interaction.reply({
content: 'Error fetching roles!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -73,7 +71,7 @@ export class RenameUserCommand extends Command {
content:
`${vegan.name}s: \`${vegan.members.size}\`` +
`\n${notVegan.name}s: \`${notVegan.members.size}\``,
withResponse: true,
fetchReply: true,
});
}
@ -90,8 +88,8 @@ export class RenameUserCommand extends Command {
await guild.members.fetch();
const vegan = guild.roles.cache.get(IDs.roles.vegan.vegan);
const notVegan = guild.roles.cache.get(IDs.roles.nonvegan.nonvegan);
const vegan = await guild.roles.cache.get(IDs.roles.vegan.vegan);
const notVegan = await guild.roles.cache.get(IDs.roles.nonvegan.nonvegan);
if (vegan === undefined || notVegan === undefined) {
await message.react('❌');

View File

@ -19,7 +19,6 @@
import { Command, RegisterBehavior } from '@sapphire/framework';
import IDs from '#utils/ids';
import { MessageFlagsBitField } from 'discord.js';
export class InfoCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -67,7 +66,11 @@ export class InfoCommand extends Command {
const option = interaction.options.getString('info', true);
let ephemeral = interaction.options.getBoolean('visible');
ephemeral = ephemeral !== true;
if (ephemeral === null) {
ephemeral = true;
} else {
ephemeral = !ephemeral;
}
let message: string;
@ -112,7 +115,7 @@ export class InfoCommand extends Command {
await interaction.reply({
content: message,
flags: ephemeral ? MessageFlagsBitField.Flags.Ephemeral : undefined,
ephemeral,
});
}
}

View File

@ -18,21 +18,13 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import {
Message,
User,
Guild,
Snowflake,
MessageFlagsBitField,
} from 'discord.js';
import type { Message, User, Guild, Snowflake } from 'discord.js';
import IDs from '#utils/ids';
import {
finishVerifyMessages,
giveVerificationRoles,
} from '#utils/verification';
import { manualVerification } from '#utils/database/verification';
import { getGuildMember } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class VerifyCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -85,8 +77,8 @@ export class VerifyCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
@ -101,7 +93,7 @@ export class VerifyCommand extends Command {
await interaction.reply({
content: verify.message,
withResponse: true,
fetchReply: true,
});
}
@ -167,12 +159,15 @@ export class VerifyCommand extends Command {
convinced: false,
};
const member = await getGuildMember(user.id, guild);
let member = guild.members.cache.get(user.id);
// Checks if member is null
if (!isGuildMember(member)) {
info.message = 'Failed to fetch member';
return info;
if (member === undefined) {
member = await guild.members.fetch(user.id).catch(() => undefined);
if (member === undefined) {
info.message = 'Failed to fetch member';
return info;
}
}
if (member.roles.cache.hasAny(...IDs.roles.restrictions.restricted)) {
@ -180,12 +175,15 @@ export class VerifyCommand extends Command {
return info;
}
const verifier = await getGuildMember(verifierId, guild);
let verifier = guild.members.cache.get(verifierId);
// Checks if verifier is null
if (!isGuildMember(verifier)) {
info.message = 'Failed to fetch verifier';
return info;
if (verifier === undefined) {
verifier = await guild.members.fetch(user.id).catch(() => undefined);
if (verifier === undefined) {
info.message = 'Failed to fetch verifier';
return info;
}
}
const roleArgs = rolesString.split(' ');

View File

@ -20,9 +20,6 @@
import { Command, RegisterBehavior } from '@sapphire/framework';
import IDs from '#utils/ids';
import { checkVerificationFinish } from '#utils/database/verification';
import { MessageFlagsBitField } from 'discord.js';
import { getGuildMember } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class VerifyTimeoutRemoveCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -63,21 +60,22 @@ export class VerifyTimeoutRemoveCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Error fetching guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
withResponse: true,
ephemeral: true,
fetchReply: true,
});
return;
}
await interaction.deferReply({
flags: MessageFlagsBitField.Flags.Ephemeral,
});
await interaction.deferReply({ ephemeral: true });
const member = await getGuildMember(user.id, guild);
let member = guild.members.cache.get(user.id);
if (!isGuildMember(member)) {
await interaction.editReply(`${user} is not on this server!`);
return;
if (member === undefined) {
member = await guild.members.fetch(user.id).catch(undefined);
if (member === undefined) {
await interaction.editReply(`${user} is not on this server!`);
return;
}
}
if (!member.roles.cache.has(IDs.roles.verifyBlock)) {

View File

@ -18,11 +18,9 @@
*/
import { Args, Command, RegisterBehavior } from '@sapphire/framework';
import { User, Guild, Message, MessageFlagsBitField } from 'discord.js';
import type { User, Guild, Message } from 'discord.js';
import { EmbedBuilder } from 'discord.js';
import { getRank, xpToNextLevel } from '#utils/database/fun/xp';
import { getGuildMember } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class RankCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
@ -57,7 +55,7 @@ export class RankCommand extends Command {
if (guild === null) {
await interaction.reply({
content: 'Could not find the guild!',
flags: MessageFlagsBitField.Flags.Ephemeral,
ephemeral: true,
});
return;
}
@ -110,11 +108,14 @@ export class RankCommand extends Command {
success: false,
};
const member = await getGuildMember(user.id, guild);
let member = guild.members.cache.get(user.id);
if (!isGuildMember(member)) {
info.message = 'The user is not on this server!';
return info;
if (member === undefined) {
member = await guild.members.fetch(user.id).catch(() => undefined);
if (member === undefined) {
info.message = 'The user is not on this server!';
return info;
}
}
const rank = await getRank(user.id);

View File

@ -21,9 +21,12 @@ import {
InteractionHandler,
InteractionHandlerTypes,
} from '@sapphire/framework';
import { ButtonInteraction, MessageFlagsBitField } from 'discord.js';
import {
ButtonInteraction,
GuildMember,
MessageFlagsBitField,
} from 'discord.js';
import IDs from '#utils/ids';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class NonVeganAccessButtonHandler extends InteractionHandler {
public constructor(
@ -43,13 +46,13 @@ export class NonVeganAccessButtonHandler extends InteractionHandler {
}
public async run(interaction: ButtonInteraction) {
const { member } = interaction;
let { member } = interaction;
const errorMessage =
'There was an error giving you the role, please try again later or contact ModMail/the developer ' +
'to sort out this problem.';
if (!isGuildMember(member)) {
if (member === null) {
await interaction.reply({
content: errorMessage,
flags: MessageFlagsBitField.Flags.Ephemeral,
@ -57,22 +60,28 @@ export class NonVeganAccessButtonHandler extends InteractionHandler {
return;
}
if (!member.roles.cache.has(IDs.roles.vegan.vegan)) {
await interaction.reply({
content: 'You need to be vegan to use this button!',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
} else if (member.roles.cache.has(IDs.roles.vegan.nvAccess)) {
await member.roles.remove(IDs.roles.vegan.nvAccess);
await interaction.reply({
content:
'Your access from the non vegan section has been removed. ' +
'If you want to gain access again, click this button again.',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
} else {
try {
member = member as GuildMember;
if (!member.roles.cache.has(IDs.roles.vegan.vegan)) {
await interaction.reply({
content: 'You need to be vegan to use this button!',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
}
if (member.roles.cache.has(IDs.roles.vegan.nvAccess)) {
await member.roles.remove(IDs.roles.vegan.nvAccess);
await interaction.reply({
content:
'Your access from the non vegan section has been removed. ' +
'If you want to gain access again, click this button again.',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
}
await member.roles.add(IDs.roles.vegan.nvAccess);
await interaction.reply({
content:
@ -80,6 +89,12 @@ export class NonVeganAccessButtonHandler extends InteractionHandler {
'If you want to remove access again, click this button again.',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
} catch (error) {
this.container.logger.error(`Non Vegan Access Interaction: ${error}`);
await interaction.reply({
content: errorMessage,
flags: MessageFlagsBitField.Flags.Ephemeral,
});
}
}
}

View File

@ -21,12 +21,14 @@ import {
InteractionHandler,
InteractionHandlerTypes,
} from '@sapphire/framework';
import { ButtonInteraction, MessageFlagsBitField } from 'discord.js';
import {
ButtonInteraction,
GuildMember,
MessageFlagsBitField,
} from 'discord.js';
import IDs from '#utils/ids';
import { checkActive } from '#utils/database/moderation/restriction';
import { addUser } from '#utils/database/dbExistingUser';
import { getTextBasedChannel } from '#utils/fetcher';
import { isGuildMember, isTextChannel } from '@sapphire/discord.js-utilities';
export class WelcomeButtonHandler extends InteractionHandler {
public constructor(
@ -47,7 +49,9 @@ export class WelcomeButtonHandler extends InteractionHandler {
public async run(interaction: ButtonInteraction) {
const { member } = interaction;
const general = await getTextBasedChannel(IDs.channels.nonVegan.general);
let general = this.container.client.channels.cache.get(
IDs.channels.nonVegan.general,
);
// Messages that are used multiple times
const roleErrorMessage =
@ -59,21 +63,32 @@ export class WelcomeButtonHandler extends InteractionHandler {
'to be verified and gain access to more channels.';
// Checks if general is not in the cache
if (!isTextChannel(general)) {
this.container.logger.error(
'WelcomeButtonHandler: Could not find and fetch the general channel!',
);
await interaction.reply({
content:
'Sorry there was a problem trying to give you access to the server. Please try again later.',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
if (general === undefined) {
// Sends an API request to get the channel
const generalFetch = await this.container.client.channels
.fetch(IDs.channels.nonVegan.general)
.catch(() => undefined);
return;
// If general does not exist
if (generalFetch === null || generalFetch === undefined) {
this.container.logger.error(
'WelcomeButtonHandler: Could not find and fetch the general channel!',
);
await interaction.reply({
content:
'Sorry there was a problem trying to give you access to the server. Please try again later.',
flags: MessageFlagsBitField.Flags.Ephemeral,
});
return;
}
// Replace fetched version of general with the cached version
general = generalFetch;
}
// If the member could not be found
if (!isGuildMember(member)) {
if (!(member instanceof GuildMember)) {
await interaction.reply({
content: roleErrorMessage,
flags: MessageFlagsBitField.Flags.Ephemeral,

View File

@ -19,12 +19,10 @@
import { Listener } from '@sapphire/framework';
import type { GuildBan } from 'discord.js';
import { AuditLogEvent, EmbedBuilder } from 'discord.js';
import { AuditLogEvent, EmbedBuilder, TextChannel } from 'discord.js';
import { addBan, checkBan } from '#utils/database/moderation/ban';
import IDs from '#utils/ids';
import { addEmptyUser, addExistingUser } from '#utils/database/dbExistingUser';
import { getGuildMember, getTextBasedChannel } from '#utils/fetcher';
import { isGuildMember, isTextChannel } from '@sapphire/discord.js-utilities';
export class BanListener extends Listener {
public constructor(
@ -84,12 +82,17 @@ export class BanListener extends Listener {
const { guild } = ban;
// Gets mod's GuildMember
const mod = await getGuildMember(executor.id, guild);
let mod = guild.members.cache.get(executor.id);
// Checks if GuildMember is null
if (!isGuildMember(mod)) {
this.container.logger.error('UnbanListener: Could not fetch moderator.');
return;
if (mod === undefined) {
mod = await guild.members.fetch(executor.id).catch(() => undefined);
if (mod === undefined) {
this.container.logger.error(
'UnbanListener: Could not fetch moderator.',
);
return;
}
}
// Check if mod is in database
@ -115,11 +118,18 @@ export class BanListener extends Listener {
await addBan(user.id, mod.id, `${reason}`);
// Log the ban
const logChannel = await getTextBasedChannel(IDs.channels.logs.restricted);
let logChannel = guild.channels.cache.get(IDs.channels.logs.restricted) as
| TextChannel
| undefined;
if (!isTextChannel(logChannel)) {
this.container.logger.error('BanListener: Could not fetch log channel');
return;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(
IDs.channels.logs.restricted,
)) as TextChannel | undefined;
if (logChannel === undefined) {
this.container.logger.error('BanListener: Could not fetch log channel');
return;
}
}
const log = new EmbedBuilder()

View File

@ -19,12 +19,10 @@
import { Listener } from '@sapphire/framework';
import type { GuildBan } from 'discord.js';
import { AuditLogEvent, EmbedBuilder } from 'discord.js';
import { AuditLogEvent, EmbedBuilder, TextChannel } from 'discord.js';
import { addBan, checkBan, removeBan } from '#utils/database/moderation/ban';
import IDs from '#utils/ids';
import { addEmptyUser, addExistingUser } from '#utils/database/dbExistingUser';
import { getGuildMember, getTextBasedChannel } from '#utils/fetcher';
import { isTextBasedChannel } from '@sapphire/discord.js-utilities';
export class UnbanListener extends Listener {
public constructor(
@ -73,12 +71,17 @@ export class UnbanListener extends Listener {
const { guild } = ban;
// Gets mod's GuildMember
const mod = await getGuildMember(executor.id, guild);
let mod = guild.members.cache.get(executor.id);
// Checks if GuildMember is null
if (mod === undefined) {
this.container.logger.error('UnbanListener: Could not fetch moderator.');
return;
mod = await guild.members.fetch(executor.id).catch(() => undefined);
if (mod === undefined) {
this.container.logger.error(
'UnbanListener: Could not fetch moderator.',
);
return;
}
}
// Check if mod is in database
@ -97,11 +100,20 @@ export class UnbanListener extends Listener {
await removeBan(user.id, mod.id);
// Log the ban
const logChannel = await getTextBasedChannel(IDs.channels.logs.restricted);
let logChannel = guild.channels.cache.get(IDs.channels.logs.restricted) as
| TextChannel
| undefined;
if (!isTextBasedChannel(logChannel)) {
this.container.logger.error('UnbanListener: Could not fetch log channel');
return;
if (logChannel === undefined) {
logChannel = (await guild.channels.fetch(
IDs.channels.logs.restricted,
)) as TextChannel | undefined;
if (logChannel === undefined) {
this.container.logger.error(
'UnbanListener: Could not fetch log channel',
);
return;
}
}
const log = new EmbedBuilder()

View File

@ -44,22 +44,19 @@ export class XpListener extends Listener {
return;
}
if (!message.channel.isSendable()) {
this.container.logger.error(
'Counting: The bot does not have permission to send messages in the counting chat!',
);
return;
}
let lastCount = await getLastCount();
// If no counts exist on the database, then create the first count from the bot
if (lastCount === null) {
if (this.container.client.id === null) {
if (!message.channel.isSendable()) {
// TODO manage logging/errors properly
return;
}
message.channel.send(
'An unexpected error occurred trying to set up the counting channel, please contact a developer!',
);
return;
}
@ -71,10 +68,14 @@ export class XpListener extends Listener {
lastCount = await getLastCount();
if (lastCount === null) {
if (!message.channel.isSendable()) {
// TODO manage logging/errors properly
return;
}
message.channel.send(
'An unexpected error occurred, please contact a developer!',
);
return;
}
}

View File

@ -22,12 +22,11 @@
import { Listener } from '@sapphire/framework';
import { DurationFormatter } from '@sapphire/time-utilities';
import { Client } from 'discord.js';
import IDs from '#utils/ids';
import { fetchRoles } from '#utils/database/dbExistingUser';
import { checkActive } from '#utils/database/moderation/restriction';
import { getUser } from '#utils/database/fun/xp';
import { getGuild, getTextBasedChannel } from '#utils/fetcher';
import { isTextBasedChannel } from '@sapphire/discord.js-utilities';
export class FixRolesOnReady extends Listener {
public constructor(
@ -46,13 +45,13 @@ export class FixRolesOnReady extends Listener {
});
}
public async run() {
public async run(client: Client) {
this.container.logger.info(
'FixRolesOnReady: Preparation before starting to fix the roles for each user...',
);
// Fetching the Guild
const guild = await getGuild(IDs.guild);
const guild = await client.guilds.fetch(IDs.guild).catch(() => undefined);
if (guild === undefined) {
this.container.logger.error('FixRolesOnReady: Could not find the server');
@ -61,8 +60,8 @@ export class FixRolesOnReady extends Listener {
// Fetching the channel for the logs
// Leave the snowflake parameter empty for no logs
const logChannel = await getTextBasedChannel('');
const sendLogs = isTextBasedChannel(logChannel);
const logChannel = await client.channels.fetch('').catch(() => null);
const sendLogs = logChannel !== null;
if (!sendLogs) {
this.container.logger.error(
@ -135,7 +134,11 @@ export class FixRolesOnReady extends Listener {
if (
restricted ||
member.roles.cache.hasAny(...IDs.roles.restrictions.restricted)
member.roles.cache.has(IDs.roles.restrictions.restricted1) ||
member.roles.cache.has(IDs.roles.restrictions.restricted2) ||
member.roles.cache.has(IDs.roles.restrictions.restricted3) ||
member.roles.cache.has(IDs.roles.restrictions.restricted4) ||
member.roles.cache.has(IDs.roles.restrictions.restrictedVegan)
) {
continue;
}

View File

@ -18,6 +18,7 @@
*/
import { Listener } from '@sapphire/framework';
import { ChannelType } from 'discord.js';
import type { GuildChannel, EmbedBuilder } from 'discord.js';
import { setTimeout } from 'timers/promises';
import IDs from '#utils/ids';
@ -32,9 +33,6 @@ import {
createWarningsEmbed,
} from '#utils/embeds';
import { fetchWarnings } from '#utils/database/moderation/warnings';
import { isTextChannel } from '@sapphire/discord.js-utilities';
import { getUser } from '#utils/fetcher';
import { isUser } from '#utils/typeChecking';
export class ModMailCreateListener extends Listener {
public constructor(
@ -52,7 +50,8 @@ export class ModMailCreateListener extends Listener {
if (channel.parentId !== IDs.categories.modMail) return;
// Checks if the channel is not a text channel
if (!isTextChannel(channel)) return;
if (!channel.isTextBased()) return;
if (channel.type !== ChannelType.GuildText) return;
// Gets the guild
const { guild } = channel;
@ -65,10 +64,13 @@ export class ModMailCreateListener extends Listener {
const userId = topic[2];
// Gets user who created ModMail
const user = await getUser(userId);
let user = guild.client.users.cache.get(userId);
if (!isUser(user)) {
return;
if (user === undefined) {
user = await guild.client.users.fetch(userId);
if (user === undefined) {
return;
}
}
// Check if the user is currently restricted on the database

View File

@ -20,9 +20,8 @@
import { Listener } from '@sapphire/framework';
import { ButtonStyle, ActionRowBuilder, ButtonBuilder } from 'discord.js';
import type { Client, TextChannel } from 'discord.js';
import IDs from '#utils/ids';
import { getTextBasedChannel } from '#utils/fetcher';
import { isTextBasedChannel } from '@sapphire/discord.js-utilities';
export class NonVeganAccessReady extends Listener {
public constructor(
@ -36,12 +35,18 @@ export class NonVeganAccessReady extends Listener {
});
}
public async run() {
const roles = await getTextBasedChannel(IDs.channels.information.roles);
if (!isTextBasedChannel(roles)) {
this.container.logger.error('nonVeganAccess: Roles not found');
return;
public async run(client: Client) {
let roles = client.channels.cache.get(IDs.channels.information.roles) as
| TextChannel
| undefined;
if (roles === undefined) {
roles = (await client.channels.fetch(IDs.channels.information.roles)) as
| TextChannel
| undefined;
if (roles === undefined) {
this.container.logger.error('nonVeganAccess: Roles not found');
return;
}
}
const botId = this.container.client.id;

View File

@ -23,8 +23,6 @@
import { Listener } from '@sapphire/framework';
import type { Client } from 'discord.js';
import IDs from '#utils/ids';
import { getTextBasedChannel } from '#utils/fetcher';
import { isTextBasedChannel } from '@sapphire/discord.js-utilities';
export class ReadyListener extends Listener {
public constructor(
@ -42,9 +40,9 @@ export class ReadyListener extends Listener {
const { username, id } = client.user!;
this.container.logger.info(`Successfully logged in as ${username} (${id})`);
const botLogChannel = await getTextBasedChannel(IDs.channels.logs.bot);
const botLogChannel = await client.channels.fetch(IDs.channels.logs.bot);
if (!isTextBasedChannel(botLogChannel)) {
if (botLogChannel === null) {
this.container.logger.error(
'ReadyListener: Could not find the channel for bot logs.',
);

View File

@ -18,7 +18,14 @@
*/
import { Listener } from '@sapphire/framework';
import type { GuildMember, Snowflake, CategoryChannel } from 'discord.js';
import type {
GuildMember,
Snowflake,
CategoryChannel,
Guild,
TextChannel,
} from 'discord.js';
import { ChannelType } from 'discord.js';
import { fetchRoles, getLeaveRoles } from '#utils/database/dbExistingUser';
import { blockTime } from '#utils/database/verification';
import {
@ -27,12 +34,6 @@ import {
} from '#utils/database/moderation/restriction';
import { blockedRoles, blockedRolesAfterRestricted } from '#utils/blockedRoles';
import IDs from '#utils/ids';
import { getCategoryChannel, getVoiceChannel } from '#utils/fetcher';
import {
isCategoryChannel,
isTextChannel,
isVoiceChannel,
} from '@sapphire/discord.js-utilities';
export class RolesJoinServerListener extends Listener {
public constructor(
@ -76,11 +77,14 @@ export class RolesJoinServerListener extends Listener {
// Add user to the restricted vegan channel
if (section === 5) {
const restrictedCategory = await getCategoryChannel(
const restrictedCategory = member.guild.channels.cache.get(
IDs.categories.restricted,
);
if (isCategoryChannel(restrictedCategory)) {
await this.restrictRun(member.id, restrictedCategory);
if (
restrictedCategory !== undefined &&
restrictedCategory.type === ChannelType.GuildCategory
) {
await this.restrictRun(member.id, restrictedCategory, member.guild);
}
}
}
@ -99,77 +103,74 @@ export class RolesJoinServerListener extends Listener {
await member.roles.add(roles);
}
const privateCategory = await getCategoryChannel(IDs.categories.private);
const privateCategory = member.guild.channels.cache.get(
IDs.categories.private,
);
if (isCategoryChannel(privateCategory)) {
await this.privateRun(member.id, privateCategory);
if (
privateCategory !== undefined &&
privateCategory.type === ChannelType.GuildCategory
) {
await this.privateRun(member.id, privateCategory, member.guild);
}
// TODO add access back to diversity team
}
private async restrictRun(userId: Snowflake, category: CategoryChannel) {
const textChannels = category.children.cache.filter((channel) =>
isTextChannel(channel),
private async restrictRun(
userId: Snowflake,
category: CategoryChannel,
guild: Guild,
) {
const textChannels = category.children.cache.filter(
(c) => c.type === ChannelType.GuildText,
);
for (const c of textChannels) {
const channel = c[1];
if (!isTextChannel(channel)) {
continue;
}
textChannels.forEach((c) => {
const textChannel = c as TextChannel;
// Checks if the channel topic has the user's snowflake
if (channel.topic !== null && channel.topic.includes(userId)) {
const topic = channel.topic.split(' ');
if (textChannel.topic?.includes(userId)) {
const topic = textChannel.topic.split(' ');
const vcId = topic[topic.indexOf(userId) + 1];
const voiceChannel = await getVoiceChannel(vcId);
const voiceChannel = guild.channels.cache.get(vcId);
if (
isVoiceChannel(voiceChannel) &&
voiceChannel.parentId === IDs.categories.restricted
voiceChannel !== undefined &&
voiceChannel.parentId === IDs.categories.restricted &&
voiceChannel.isVoiceBased()
) {
await voiceChannel.permissionOverwrites.edit(userId, {
ViewChannel: true,
});
voiceChannel.permissionOverwrites.edit(userId, { ViewChannel: true });
}
await channel.permissionOverwrites.edit(userId, { ViewChannel: true });
textChannel.permissionOverwrites.edit(userId, { ViewChannel: true });
}
}
});
}
private async privateRun(userId: Snowflake, category: CategoryChannel) {
const textChannels = category.children.cache.filter((channel) =>
isTextChannel(channel),
private async privateRun(
userId: Snowflake,
category: CategoryChannel,
guild: Guild,
) {
const textChannels = category.children.cache.filter(
(c) => c.type === ChannelType.GuildText,
);
for (const c of textChannels) {
const channel = c[1];
if (!isTextChannel(channel)) {
continue;
}
textChannels.forEach((c) => {
const textChannel = c as TextChannel;
// Checks if the channel topic has the user's snowflake
if (channel.topic !== null && channel.topic.includes(userId)) {
const topic = channel.topic.split(' ');
if (textChannel.topic?.includes(userId)) {
const topic = textChannel.topic.split(' ');
const vcId = topic[topic.indexOf(userId) + 2];
const voiceChannel = await getVoiceChannel(vcId);
const voiceChannel = guild.channels.cache.get(vcId);
if (
isVoiceChannel(voiceChannel) &&
voiceChannel.parentId === IDs.categories.private
voiceChannel !== undefined &&
voiceChannel.parentId === IDs.categories.private &&
voiceChannel.isVoiceBased()
) {
await voiceChannel.permissionOverwrites.edit(userId, {
ViewChannel: true,
});
voiceChannel.permissionOverwrites.edit(userId, { ViewChannel: true });
}
await channel.permissionOverwrites.edit(userId, { ViewChannel: true });
textChannel.permissionOverwrites.edit(userId, { ViewChannel: true });
}
}
});
}
private blockedRole(role: Snowflake) {

View File

@ -21,8 +21,6 @@ import { Listener } from '@sapphire/framework';
import { EmbedBuilder } from 'discord.js';
import type { Message } from 'discord.js';
import IDs from '#utils/ids';
import { getTextBasedChannel } from '#utils/fetcher';
import { isTextChannel } from '@sapphire/discord.js-utilities';
export class Suggestions extends Listener {
public constructor(
@ -40,19 +38,14 @@ export class Suggestions extends Listener {
return;
}
const mailbox = await getTextBasedChannel(IDs.channels.staff.mailbox);
const mailbox = await this.container.client.channels.cache.get(
IDs.channels.staff.mailbox,
);
if (!isTextChannel(mailbox)) {
if (mailbox === undefined || !mailbox.isTextBased()) {
this.container.logger.error(
'Mailbox is not a TextBased channel or is undefined',
);
return;
} else if (!mailbox.isSendable()) {
this.container.logger.error(
'Suggestions: The bot does not have permissions to send messages in the mailbox!',
);
return;
}
@ -90,6 +83,11 @@ export class Suggestions extends Listener {
return;
}
if (!mailbox.isSendable()) {
// TODO manage logging/errors properly
return;
}
const sent = await mailbox.send({
embeds: [suggestion],
content: message.author.toString(),

View File

@ -20,7 +20,6 @@
import { Listener } from '@sapphire/framework';
import type { VoiceState } from 'discord.js';
import { checkActive, removeMute } from '#utils/database/moderation/vcMute';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class VCMuteListener extends Listener {
public constructor(
@ -38,7 +37,7 @@ export class VCMuteListener extends Listener {
if (oldState.channel === null && newState.channel !== null) {
const { member } = newState;
if (!isGuildMember(member)) {
if (member === null) {
this.container.logger.error(
'VCMute Listener - GuildMember not found when joining',
);

View File

@ -19,8 +19,10 @@
import { container, Listener } from '@sapphire/framework';
import type {
CategoryChannel,
ColorResolvable,
TextChannel,
VoiceChannel,
VoiceState,
GuildMember,
Guild,
@ -28,6 +30,7 @@ import type {
} from 'discord.js';
import {
time,
ChannelType,
PermissionsBitField,
ButtonBuilder,
ButtonInteraction,
@ -51,16 +54,6 @@ import { findNotes } from '#utils/database/moderation/sus';
import { addExistingUser } from '#utils/database/dbExistingUser';
import { rolesToString } from '#utils/formatter';
import IDs from '#utils/ids';
import {
getCategoryChannel,
getGuildMember,
getVoiceChannel,
} from '#utils/fetcher';
import {
isCategoryChannel,
isGuildMember,
isVoiceChannel,
} from '@sapphire/discord.js-utilities';
export class VerificationJoinVCListener extends Listener {
public constructor(
@ -91,19 +84,20 @@ export class VerificationJoinVCListener extends Listener {
const { client } = container;
const guild = client.guilds.cache.get(newState.guild.id);
if (member === null || guild === undefined) {
if (channel === null || member === null || guild === undefined) {
this.container.logger.error('Verification channel not found');
return;
}
// Get current category and channel
const category = await getCategoryChannel(IDs.categories.verification);
const currentChannel = await getVoiceChannel(channel.id);
if (!isCategoryChannel(category) || !isVoiceChannel(currentChannel)) {
const categoryGuild = guild.channels.cache.get(IDs.categories.verification);
const currentChannelGuild = guild.channels.cache.get(channel.id);
if (currentChannelGuild === undefined || categoryGuild === undefined) {
this.container.logger.error('Verification channel not found');
return;
}
const currentChannel = currentChannelGuild as VoiceChannel;
const category = categoryGuild as CategoryChannel;
const roles: Snowflake[] = [];
@ -173,8 +167,8 @@ export class VerificationJoinVCListener extends Listener {
}
// Check how many voice channels there are
const listVoiceChannels = category.children.cache.filter((channel) =>
isVoiceChannel(channel),
const listVoiceChannels = category.children.cache.filter(
(c) => c.type === ChannelType.GuildVoice,
);
// Create a text channel for verifiers only
@ -306,12 +300,11 @@ export class VerificationJoinVCListener extends Listener {
i += 1
) {
// Get mod name
const modGuildMember = await getGuildMember(notes[i].modId, guild);
const modGuildMember = guild.members.cache.get(notes[i].modId);
let mod = notes[i].modId;
if (isGuildMember(modGuildMember)) {
if (modGuildMember !== undefined) {
mod = modGuildMember.displayName;
}
// Add sus note to embed
embed.addFields({
name: `Sus ID: ${
@ -502,8 +495,10 @@ export class VerificationJoinVCListener extends Listener {
// Confirming and finishing the verification
if (button.customId === 'confirm' && info.page >= questionLength) {
// Check verifier is on the database
const verifierGuildMember = await getGuildMember(button.user.id, guild);
if (!isGuildMember(verifierGuildMember)) {
const verifierGuildMember = await guild.members.cache.get(
button.user.id,
);
if (verifierGuildMember === undefined) {
await message.edit({ content: 'Verifier not found!' });
return;
}

View File

@ -18,8 +18,13 @@
*/
import { Listener } from '@sapphire/framework';
import type { VoiceState } from 'discord.js';
import { time } from 'discord.js';
import type {
VoiceState,
CategoryChannel,
VoiceChannel,
TextChannel,
} from 'discord.js';
import { time, ChannelType } from 'discord.js';
import { createVerificationVoice } from '#utils/verification';
import { maxVCs, leaveBan } from '#utils/verificationConfig';
import {
@ -30,13 +35,6 @@ import {
import { fetchRoles } from '#utils/database/dbExistingUser';
import { fibonacci } from '#utils/maths';
import IDs from '#utils/ids';
import {
isCategoryChannel,
isGuildMember,
isTextChannel,
isVoiceChannel,
} from '@sapphire/discord.js-utilities';
import { getCategoryChannel, getGuildMember } from '#utils/fetcher';
export class VerificationLeaveVCListener extends Listener {
public constructor(
@ -65,44 +63,46 @@ export class VerificationLeaveVCListener extends Listener {
const { channel } = oldState;
const { guild } = newState;
if (!isVoiceChannel(channel) || guild === undefined) {
if (channel === null || guild === undefined) {
this.container.logger.error('Verification channel not found');
return;
}
// Get the category
const category = await getCategoryChannel(IDs.categories.verification);
if (!isCategoryChannel(category)) {
const categoryGuild = guild.channels.cache.get(IDs.categories.verification);
if (categoryGuild === null) {
this.container.logger.error('Verification channel not found');
return;
}
const category = categoryGuild as CategoryChannel;
// Get the user that was being verified
const userSnowflake = await getUser(channel.id);
if (userSnowflake === null) {
verifier = true;
} else {
// Allow more people to join VC if there are less than 10 VCs
const member = await getGuildMember(userSnowflake, guild);
}
// Allow more people to join VC if there are less than 10 VCs
if (!verifier) {
const user = guild.members.cache.get(userSnowflake!);
// Remove verify as vegan and give non vegan role
if (!(await checkFinish(channel.id)) && isGuildMember(member)) {
if (!(await checkFinish(channel.id)) && user !== undefined) {
// Get roles to give back to the user
const roles = await fetchRoles(member.id);
const roles = await fetchRoles(user.id);
roles.push(IDs.roles.verifyBlock);
await member.roles
await user.roles
.add(roles)
.catch(() =>
this.container.logger.error(
'Verification: User left but bot still tried to add roles',
),
);
// Create timeout block for user
// Counts the recent times they have incomplete verifications
const incompleteCount =
(await countIncomplete(member.id)) % (leaveBan + 1);
(await countIncomplete(user.id)) % (leaveBan + 1);
// Creates the length of the time for the ban
const banLength = fibonacci(incompleteCount) * 3600_000;
@ -110,14 +110,14 @@ export class VerificationLeaveVCListener extends Listener {
{
name: 'verifyUnblock',
payload: {
userId: member.id,
userId: user.id,
guildId: guild.id,
},
},
banLength,
);
await member.user
await user.user
.send(
'You have been timed out as a verifier had not joined for 15 minutes or you disconnected from verification.\n\n' +
`You can verify again at: ${time(
@ -129,8 +129,8 @@ export class VerificationLeaveVCListener extends Listener {
}
// Check how many voice channels there are
const listVoiceChannels = category.children.cache.filter((channel) =>
isVoiceChannel(channel),
const listVoiceChannels = category.children.cache.filter(
(c) => c.type === ChannelType.GuildVoice,
);
// Check that it is not deleting the 'Verification' channel (in case bot crashes)
@ -142,22 +142,19 @@ export class VerificationLeaveVCListener extends Listener {
// Delete text channel
if (!verifier) {
// Gets a list of all the text channels in the verification category
const listTextChannels = category.children.cache.filter((channel) =>
isTextChannel(channel),
const listTextChannels = category.children.cache.filter(
(c) => c.type === ChannelType.GuildText,
);
for (const c of listTextChannels) {
const channel = c[1];
if (!isTextChannel(channel)) {
continue;
}
listTextChannels.forEach((c) => {
const textChannel = c as TextChannel;
// Checks if the channel topic has the user's snowflake
if (channel.topic !== null && channel.topic.includes(userSnowflake!)) {
await channel.delete();
if (
textChannel.topic !== null &&
textChannel.topic.includes(userSnowflake!)
) {
textChannel.delete();
}
}
});
}
// If there are no VCs left in verification after having the channel deleted
@ -171,9 +168,9 @@ export class VerificationLeaveVCListener extends Listener {
return;
}
const verification = listVoiceChannels.last();
const verification = listVoiceChannels.last() as VoiceChannel | undefined;
if (!isVoiceChannel(verification)) {
if (verification === undefined) {
this.container.logger.error(
'Verification: Verification channel not found.',
);

View File

@ -18,15 +18,15 @@
*/
import { Listener } from '@sapphire/framework';
import type { VoiceChannel } from 'discord.js';
import type {
Client,
CategoryChannel,
TextChannel,
VoiceChannel,
} from 'discord.js';
import { ChannelType } from 'discord.js';
import { createVerificationVoice } from '#utils/verification';
import IDs from '#utils/ids';
import { getCategoryChannel } from '#utils/fetcher';
import {
isCategoryChannel,
isTextChannel,
isVoiceChannel,
} from '@sapphire/discord.js-utilities';
export class VerificationReady extends Listener {
public constructor(
@ -40,67 +40,62 @@ export class VerificationReady extends Listener {
});
}
public async run() {
public async run(client: Client) {
// Get verification category
const category = await getCategoryChannel(IDs.categories.verification);
if (!isCategoryChannel(category)) {
this.container.logger.error('verifyStart: Channel not found');
return;
let category = client.channels.cache.get(IDs.categories.verification) as
| CategoryChannel
| undefined;
if (category === undefined) {
category = (await client.channels.fetch(IDs.categories.verification)) as
| CategoryChannel
| undefined;
if (category === undefined) {
this.container.logger.error('verifyStart: Channel not found');
return;
}
}
// Check how many voice channels there are
const voiceChannels = category.children.cache.filter((channel) =>
isVoiceChannel(channel),
const voiceChannels = category.children.cache.filter(
(c) => c.type === ChannelType.GuildVoice,
);
const currentVCs: VoiceChannel[] = [];
const emptyVC: string[] = [];
// Delete voice channels
for (const c of voiceChannels) {
const channel = c[1];
if (!isVoiceChannel(channel)) {
continue;
}
if (channel.members.size === 0) {
emptyVC.push(channel.id);
await channel.delete();
voiceChannels.forEach((c) => {
const voiceChannel = c as VoiceChannel;
if (voiceChannel.members.size === 0) {
emptyVC.push(voiceChannel.id);
voiceChannel.delete();
} else {
currentVCs.push(channel);
}
}
// Delete text channels
const textChannels = category.children.cache.filter((channel) =>
isTextChannel(channel),
);
for (const c of textChannels) {
const channel = c[1];
if (!isTextChannel(channel)) {
continue;
}
// Checks if the channel topic has the user's snowflake
for (const snowflake in emptyVC) {
if (channel.topic !== null && channel.topic.includes(snowflake)) {
await channel.delete();
}
}
}
// Check if there is no voice channels, create verification
let verification = false;
currentVCs.forEach((channel) => {
if (channel.name === 'Verification') {
verification = true;
currentVCs.push(voiceChannel);
}
});
// Delete text channels
const textChannels = category.children.cache.filter(
(c) => c.type === ChannelType.GuildText,
);
textChannels.forEach((c) => {
const textChannel = c as TextChannel;
// Checks if the channel topic has the user's snowflake
emptyVC.forEach((snowflake) => {
if (
textChannel.topic !== null &&
textChannel.topic.includes(snowflake)
) {
textChannel.delete();
}
});
});
// Check if there is no voice channels, create verification
let verification = false;
currentVCs.forEach((c) => {
if (c.name === 'Verification') {
verification = true;
}
});
if (!verification) {
await createVerificationVoice(category);
}

View File

@ -21,8 +21,6 @@ import { Listener } from '@sapphire/framework';
import { GuildMember } from 'discord.js';
import IDs from '#utils/ids';
import { noModHistory, userPreviouslyHadRole } from '#utils/database/memberMod';
import { getRole } from '#utils/fetcher';
import { isRole } from '#utils/typeChecking';
/**
* Gives the trusted role to users who have levelled up to level 5
@ -53,9 +51,9 @@ export class TrustedListener extends Listener {
}
const { guild } = member;
const trusted = await getRole(IDs.roles.trusted, guild);
const trusted = guild.roles.cache.get(IDs.roles.trusted);
if (!isRole(trusted)) {
if (trusted === undefined) {
this.container.logger.error(
'TrustedXP Listener: the Trusted role could not be found in the guild.',
);

View File

@ -20,9 +20,8 @@
import { Listener } from '@sapphire/framework';
import { ButtonStyle, ActionRowBuilder, ButtonBuilder } from 'discord.js';
import type { Client, TextChannel } from 'discord.js';
import IDs from '#utils/ids';
import { getTextBasedChannel } from '#utils/fetcher';
import { isTextBasedChannel } from '@sapphire/discord.js-utilities';
export class VerificationReady extends Listener {
public constructor(
@ -36,13 +35,19 @@ export class VerificationReady extends Listener {
});
}
public async run() {
public async run(client: Client) {
// Get verification category
const welcome = await getTextBasedChannel(IDs.channels.welcome);
if (!isTextBasedChannel(welcome)) {
this.container.logger.error('verifyStart: Welcome not found');
return;
let welcome = client.channels.cache.get(IDs.channels.welcome) as
| TextChannel
| undefined;
if (welcome === undefined) {
welcome = (await client.channels.fetch(IDs.channels.welcome)) as
| TextChannel
| undefined;
if (welcome === undefined) {
this.container.logger.error('verifyStart: Welcome not found');
return;
}
}
const botId = this.container.client.id;

View File

@ -18,9 +18,9 @@
*/
import { ScheduledTask } from '@sapphire/plugin-scheduled-tasks';
import { container } from '@sapphire/framework';
import type { TextChannel } from 'discord.js';
import IDs from '#utils/ids';
import { getTextBasedChannel } from '#utils/fetcher';
import { isTextBasedChannel } from '@sapphire/discord.js-utilities';
export class DiversityMonMessageTask extends ScheduledTask {
public constructor(
@ -34,6 +34,8 @@ export class DiversityMonMessageTask extends ScheduledTask {
}
public async run() {
const { client } = container;
const message =
'**📌 Diversity Section Code of Conduct**\n\n' +
'❤️ Be *Kind*\n' +
@ -45,16 +47,12 @@ export class DiversityMonMessageTask extends ScheduledTask {
'❤️ Respect the creativity of others.\n' +
'🧡 Actively seek to include others, especially moderators, in heated discourse for the purpose of de-escalation.';
const lgbtqia = await getTextBasedChannel(IDs.channels.diversity.lgbtqia);
const potgm = await getTextBasedChannel(IDs.channels.diversity.potgm);
if (!isTextBasedChannel(lgbtqia) || !isTextBasedChannel(potgm)) {
this.container.logger.error(
'Diversity Monday: The bot could not find both of the channels!',
);
return;
}
const lgbtqia = client.channels.cache.get(
IDs.channels.diversity.lgbtqia,
) as TextChannel;
const potgm = client.channels.cache.get(
IDs.channels.diversity.potgm,
) as TextChannel;
await lgbtqia.send(message);
await potgm.send(message);

View File

@ -18,9 +18,9 @@
*/
import { ScheduledTask } from '@sapphire/plugin-scheduled-tasks';
import { container } from '@sapphire/framework';
import type { TextChannel } from 'discord.js';
import IDs from '#utils/ids';
import { getTextBasedChannel } from '#utils/fetcher';
import { isTextBasedChannel } from '@sapphire/discord.js-utilities';
export class DiversityWedMessageTask extends ScheduledTask {
public constructor(
@ -34,6 +34,8 @@ export class DiversityWedMessageTask extends ScheduledTask {
}
public async run() {
const { client } = container;
const message =
'**📌 Diversity Section Code of Conduct**\n\n' +
'❤️ Be *Kind*\n' +
@ -45,18 +47,12 @@ export class DiversityWedMessageTask extends ScheduledTask {
'❤️ Respect the creativity of others.\n' +
'🧡 Actively seek to include others, especially moderators, in heated discourse for the purpose of de-escalation.';
const women = await getTextBasedChannel(IDs.channels.diversity.women);
const disabilities = await getTextBasedChannel(
const women = client.channels.cache.get(
IDs.channels.diversity.women,
) as TextChannel;
const disabilities = client.channels.cache.get(
IDs.channels.diversity.disabilities,
);
if (!isTextBasedChannel(women) || !isTextBasedChannel(disabilities)) {
this.container.logger.error(
'Diversity Wednesday: The bot could not find both of the channels!',
);
return;
}
) as TextChannel;
await women.send(message);
await disabilities.send(message);

View File

@ -18,9 +18,9 @@
*/
import { ScheduledTask } from '@sapphire/plugin-scheduled-tasks';
import { container } from '@sapphire/framework';
import type { TextChannel } from 'discord.js';
import IDs from '#utils/ids';
import { getTextBasedChannel } from '#utils/fetcher';
import { isTextBasedChannel } from '@sapphire/discord.js-utilities';
export class RestrictedMessageTask extends ScheduledTask {
public constructor(
@ -34,20 +34,14 @@ export class RestrictedMessageTask extends ScheduledTask {
}
public async run() {
const restricted = await getTextBasedChannel(
const { client } = container;
const restricted = client.channels.cache.get(
IDs.channels.restricted.restricted,
);
const tolerance = await getTextBasedChannel(
) as TextChannel;
const tolerance = client.channels.cache.get(
IDs.channels.restricted.tolerance,
);
if (!isTextBasedChannel(restricted) || !isTextBasedChannel(tolerance)) {
this.container.logger.error(
'Restricted Reminder: The bot could not find both of the channels!',
);
return;
}
) as TextChannel;
await restricted.send(this.message(IDs.roles.restrictions.restricted1));
await tolerance.send(this.message(IDs.roles.restrictions.restricted3));

View File

@ -18,9 +18,9 @@
*/
import { ScheduledTask } from '@sapphire/plugin-scheduled-tasks';
import { container } from '@sapphire/framework';
import type { TextChannel } from 'discord.js';
import IDs from '#utils/ids';
import { getTextBasedChannel } from '#utils/fetcher';
import { isTextBasedChannel } from '@sapphire/discord.js-utilities';
export class StandupTask extends ScheduledTask {
public constructor(
@ -34,15 +34,11 @@ export class StandupTask extends ScheduledTask {
}
public async run() {
const channel = await getTextBasedChannel(IDs.channels.staff.coordinators);
const { client } = container;
if (!isTextBasedChannel(channel)) {
this.container.logger.error(
'Standup: The bot could not find the channel to post the standup in!',
);
return;
}
const channel = client.channels.cache.get(
IDs.channels.staff.coordinators,
) as TextChannel;
await channel.send(`Hiya <@&${IDs.roles.staff.coordinator}> it's time for your weekly standup!
\nPlease submit it in <#${IDs.channels.staff.standup}> :)`);

View File

@ -18,9 +18,9 @@
*/
import { ScheduledTask } from '@sapphire/plugin-scheduled-tasks';
import { container } from '@sapphire/framework';
import type { TextChannel } from 'discord.js';
import IDs from '#utils/ids';
import { getTextBasedChannel } from '#utils/fetcher';
import { isTextBasedChannel } from '@sapphire/discord.js-utilities';
export class VerifyReminder extends ScheduledTask {
public constructor(
@ -34,6 +34,8 @@ export class VerifyReminder extends ScheduledTask {
}
public async run() {
const { client } = container;
// Get the total messages sent in non-vegan general since last message
const redisKey = 'verifyReminderMessageCounter';
@ -43,15 +45,9 @@ export class VerifyReminder extends ScheduledTask {
if (!messageCount || +messageCount < 100) return;
// Send verification reminder to non-vegan general
const channel = await getTextBasedChannel(IDs.channels.nonVegan.general);
if (!isTextBasedChannel(channel)) {
this.container.logger.error(
'Verify Reminder: The bot could not find the channel to post the reminder!',
);
return;
}
const channel = client.channels.cache.get(
IDs.channels.nonVegan.general,
) as TextChannel;
await channel.send(
"If you want to have the vegan or activist role, you'll need to do a voice verification. " +

View File

@ -25,9 +25,6 @@ import {
checkTempBan,
removeTempBan,
} from '#utils/database/moderation/tempBan';
import { getGuild, getTextBasedChannel, getUser } from '#utils/fetcher';
import { isUser } from '#utils/typeChecking';
import { isTextChannel } from '@sapphire/discord.js-utilities';
export class TempBan extends ScheduledTask {
public constructor(
@ -39,24 +36,30 @@ export class TempBan extends ScheduledTask {
public async run(payload: { userId: string; guildId: string }) {
this.container.logger.debug('Temp Unban Task: Currently running unban');
// Get the guild where the user is in
const guild = await getGuild(payload.guildId);
let guild = this.container.client.guilds.cache.get(payload.guildId);
if (guild === undefined) {
this.container.logger.error('Temp Unban Task: Guild not found!');
return;
guild = await this.container.client.guilds
.fetch(payload.guildId)
.catch(() => undefined);
if (guild === undefined) {
this.container.logger.error('Temp Unban Task: Guild not found!');
return;
}
}
const { userId } = payload;
const user = await getUser(userId);
let user = guild.client.users.cache.get(userId);
if (!isUser(user)) {
this.container.logger.error(
'Temp Unban Task: Could not fetch banned user!',
);
return;
if (user === undefined) {
user = await guild.client.users.fetch(userId).catch(() => undefined);
if (user === undefined) {
this.container.logger.error(
'Temp Unban Task: Could not fetch banned user!',
);
return;
}
}
if ((await checkBan(userId)) || !(await checkTempBan(userId))) {
@ -72,11 +75,25 @@ export class TempBan extends ScheduledTask {
await removeTempBan(userId);
// Log unban
const logChannel = await getTextBasedChannel(IDs.channels.logs.restricted);
let logChannel = guild.channels.cache.get(IDs.channels.logs.restricted);
if (!isTextChannel(logChannel)) {
if (logChannel === undefined) {
const logChannelFetch = await guild.channels
.fetch(IDs.channels.logs.restricted)
.catch(() => null);
if (logChannelFetch === null) {
this.container.logger.error(
`Temp Ban Listener: Could not fetch log channel. User Snowflake: ${userId}`,
);
return;
}
logChannel = logChannelFetch;
}
if (!logChannel.isTextBased()) {
this.container.logger.error(
`Temp Ban Listener: Could not fetch log channel. User Snowflake: ${userId}`,
'Temp Ban Listener: Log channel is not a text based channel!',
);
return;
}

View File

@ -18,11 +18,7 @@
*/
import { ScheduledTask } from '@sapphire/plugin-scheduled-tasks';
import { getGuildMember, getVoiceBasedChannel } from '#utils/fetcher';
import {
isGuildMember,
isVoiceBasedChannel,
} from '@sapphire/discord.js-utilities';
import { ChannelType } from 'discord.js';
export class VerifyTimeout extends ScheduledTask {
public constructor(
@ -34,17 +30,29 @@ export class VerifyTimeout extends ScheduledTask {
public async run(payload: { channelId: string; userId: string }) {
// Get the guild where the user is in
const channel = await getVoiceBasedChannel(payload.channelId);
let channel = this.container.client.channels.cache.get(payload.channelId);
if (channel === undefined) {
const channelFetch = await this.container.client.channels
.fetch(payload.channelId)
.catch(() => null);
if (channelFetch === null) {
this.container.logger.error('verifyTimeout: Channel not found!');
return;
}
if (!isVoiceBasedChannel(channel)) {
this.container.logger.error('verifyTimeout: Channel not found!');
channel = channelFetch;
}
if (channel.type !== ChannelType.GuildVoice) {
this.container.logger.error(
'verifyTimeout: Channel is not a voice channel!',
);
return;
}
if (channel.members.size < 2 && channel.members.has(payload.userId)) {
const user = await getGuildMember(payload.userId, channel.guild);
if (!isGuildMember(user)) {
const user = channel.members.get(payload.userId);
if (user === undefined) {
this.container.logger.error('verifyTimeout: GuildMember not found!');
return;
}

View File

@ -19,8 +19,6 @@
import { ScheduledTask } from '@sapphire/plugin-scheduled-tasks';
import IDs from '#utils/ids';
import { getGuild, getGuildMember } from '#utils/fetcher';
import { isGuildMember } from '@sapphire/discord.js-utilities';
export class VerifyUnblock extends ScheduledTask {
public constructor(
@ -32,23 +30,29 @@ export class VerifyUnblock extends ScheduledTask {
public async run(payload: { userId: string; guildId: string }) {
// Get the guild where the user is in
const guild = await getGuild(payload.guildId);
let guild = this.container.client.guilds.cache.get(payload.guildId);
if (guild === undefined) {
this.container.logger.error('verifyUnblock: Guild not found!');
return;
guild = await this.container.client.guilds
.fetch(payload.guildId)
.catch(() => undefined);
if (guild === undefined) {
this.container.logger.error('verifyUnblock: Guild not found!');
return;
}
}
// Find GuildMember for the user
const member = await getGuildMember(payload.userId, guild);
if (!isGuildMember(member)) {
this.container.logger.error('verifyUnblock: GuildMember not found!');
return;
let user = guild.members.cache.get(payload.userId);
if (user === undefined) {
user = await guild.members.fetch(payload.userId).catch(() => undefined);
if (user === undefined) {
this.container.logger.error('verifyUnblock: GuildMember not found!');
return;
}
}
// Remove the 'verify block' role
await member.roles.remove(IDs.roles.verifyBlock);
await user.roles.remove(IDs.roles.verifyBlock);
}
}

View File

@ -19,8 +19,7 @@
import type { TextBasedChannel } from 'discord.js';
import IDs from '#utils/ids';
import { Nullish } from '@sapphire/utilities';
import { isTextChannel } from '@sapphire/discord.js-utilities';
import { ChannelType } from 'discord.js';
/**
* Checks if the channel is in the staff category.
@ -28,8 +27,12 @@ import { isTextChannel } from '@sapphire/discord.js-utilities';
* @returns {boolean} true if is in staff channel
*/
export function checkStaff(channel: TextBasedChannel | Nullish): boolean {
if (!isTextChannel(channel)) {
export function checkStaff(channel: TextBasedChannel | null) {
if (channel === null) {
return false;
}
if (channel.type !== ChannelType.GuildText) {
return false;
}

View File

@ -1,245 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
Animal Rights Advocates Discord Bot
Copyright (C) 2025 Anthony Berg
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {
CategoryChannel,
Guild,
GuildMember,
Role,
Snowflake,
TextBasedChannel,
User,
VoiceBasedChannel,
VoiceChannel,
} from 'discord.js';
import { isRole, isUser } from '#utils/typeChecking';
import { container } from '@sapphire/framework';
import {
isCategoryChannel,
isGuildMember,
isTextBasedChannel,
isVoiceBasedChannel,
isVoiceChannel,
} from '@sapphire/discord.js-utilities';
/**
* Gets a User from their Snowflake.
* Checks the cache first, if it is not in the cache, will fetch from Discord.
* @param userId Snowflake of the user fetch
*/
export async function getUser(userId: Snowflake): Promise<User | undefined> {
// Attempts to get the User from the cache first
let user = container.client.users.cache.get(userId);
// If the user is not in the cache, fetch from Discord
if (!isUser(user)) {
user = await container.client.users.fetch(userId).catch(() => undefined);
}
return user;
}
/**
* Gets the Guild from the Snowflake.
* Checks if it is in the cache first, if not, attempts to fetch from Discord.
* @param guildId the Snowflake of the Guild
*/
export async function getGuild(guildId: Snowflake): Promise<Guild | undefined> {
// Attempts to get the GuildMember from the cache first
let guild = container.client.guilds.cache.get(guildId);
// If the Role is not in the cache, fetch from Discord
if (!(guild instanceof Guild)) {
guild = await container.client.guilds.fetch(guildId).catch(() => undefined);
}
return guild;
}
/**
* Gets the GuildMember from their Snowflake.
* Checks if it is in the cache first, if not, attempts to fetch from Discord.
* @param memberId the Snowflake of the GuildMember
* @param guild the Guild to get the GuildMember from
*/
export async function getGuildMember(
memberId: Snowflake,
guild: Guild,
): Promise<GuildMember | undefined> {
// Attempts to get the GuildMember from the cache first
let member = guild.members.cache.get(memberId);
// If the GuildMember is not in the cache, fetch from Discord
if (!isGuildMember(member)) {
member = await guild.members.fetch(memberId).catch(() => undefined);
}
return member;
}
/**
* Gets the Role from the Snowflake.
* Checks if it is in the cache first, if not, attempts to fetch from Discord.
* @param roleId the Snowflake of the Role
* @param guild the Guild to get the Role from
*/
export async function getRole(
roleId: Snowflake,
guild: Guild,
): Promise<Role | undefined> {
// Attempts to get the Role from the cache first
const role = guild.roles.cache.get(roleId);
// If the Role is not in the cache, fetch from Discord
if (isRole(role)) {
return role;
}
const fetchRole = await guild.roles.fetch(roleId).catch(() => undefined);
if (isRole(fetchRole)) {
return fetchRole;
} else {
return undefined;
}
}
/**
* Gets a TextBasedChannel from a Snowflake.
* Checks if it is in the cache first, if not, attempts to fetch from Discord.
* @param channelId the Snowflake of the TextBasedChannel
*/
export async function getTextBasedChannel(
channelId: Snowflake,
): Promise<TextBasedChannel | undefined> {
// Attempts to get the TextChannel from the cache first
const channel = container.client.channels.cache.get(channelId);
if (channel !== undefined) {
if (channel.isTextBased()) {
return channel;
} else {
return undefined;
}
}
// Fetches the Channel from Discord if the channel is not found in cache
const fetchChannel = await container.client.channels
.fetch(channelId)
.catch(() => undefined);
if (isTextBasedChannel(fetchChannel)) {
return fetchChannel;
} else {
return undefined;
}
}
/**
* Gets a CategoryChannel from a Snowflake.
* Checks if it is in the cache first, if not, attempts to fetch from Discord.
* @param categoryId the Snowflake of the Category
*/
export async function getCategoryChannel(
categoryId: Snowflake,
): Promise<CategoryChannel | undefined> {
// Attempts to get the CategoryChannel from the cache first
const category = container.client.channels.cache.get(categoryId);
if (category !== undefined) {
if (isCategoryChannel(category)) {
return category;
} else {
return undefined;
}
}
// Fetches the Channel from Discord if the channel is not found in cache
const fetchCategory = await container.client.channels
.fetch(categoryId)
.catch(() => undefined);
if (isCategoryChannel(fetchCategory)) {
return fetchCategory;
} else {
return undefined;
}
}
/**
* Gets a VoiceChannel from a Snowflake.
* Checks if it is in the cache first, if not, attempts to fetch from Discord.
* @param vcId the Snowflake of the VoiceChannel
*/
export async function getVoiceChannel(
vcId: Snowflake,
): Promise<VoiceChannel | undefined> {
// Attempts to get the VoiceChannel from the cache first
const vc = container.client.channels.cache.get(vcId);
if (vc !== undefined) {
if (isVoiceChannel(vc)) {
return vc;
} else {
return undefined;
}
}
// Fetches the Channel from Discord if the channel is not found in cache
const fetchVC = await container.client.channels
.fetch(vcId)
.catch(() => undefined);
if (isVoiceChannel(fetchVC)) {
return fetchVC;
} else {
return undefined;
}
}
/**
* Gets a VoiceBasedChannel from a Snowflake.
* Checks if it is in the cache first, if not, attempts to fetch from Discord.
* @param vcId the Snowflake of the VoiceBasedChannel
*/
export async function getVoiceBasedChannel(
vcId: Snowflake,
): Promise<VoiceBasedChannel | undefined> {
// Attempts to get the VoiceBasedChannel from the cache first
const vc = container.client.channels.cache.get(vcId);
if (vc !== undefined) {
if (isVoiceBasedChannel(vc)) {
return vc;
} else {
return undefined;
}
}
// Fetches the Channel from Discord if the channel is not found in cache
const fetchVC = await container.client.channels
.fetch(vcId)
.catch(() => undefined);
if (isVoiceBasedChannel(fetchVC)) {
return fetchVC;
} else {
return undefined;
}
}

View File

@ -1,37 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
Animal Rights Advocates Discord Bot
Copyright (C) 2025 Anthony Berg
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Role, User } from 'discord.js';
import { Nullish } from '@sapphire/utilities';
/**
* Checks if a user is a `User`, and that they are not `undefined`/`null`.
* @param user The user to check
*/
export function isUser(user: User | Nullish): user is User {
return user instanceof User;
}
/**
* Checks if the role is a `Role` type, and they are not `undefined`/`null`.
* @param role the role to check
*/
export function isRole(role: Role | Nullish): role is Role {
return role instanceof Role;
}

View File

@ -23,16 +23,12 @@ import {
ChannelType,
GuildMember,
PermissionsBitField,
TextChannel,
time,
User,
} from 'discord.js';
import type { Snowflake, VoiceBasedChannel } from 'discord.js';
import IDs from '#utils/ids';
import { getTextBasedChannel } from '#utils/fetcher';
import {
isDMChannel,
isTextBasedChannel,
} from '@sapphire/discord.js-utilities';
export async function createVerificationText(
member: GuildMember,
@ -256,16 +252,12 @@ export async function finishVerifyMessages(
// Not vegan
if (!roles.vegan) {
const general = await getTextBasedChannel(IDs.channels.nonVegan.general);
if (!isTextBasedChannel(general)) {
container.logger.error(
'Verification: Could not find general chat to welcome a non-vegan!',
);
const general = container.client.channels.cache.get(
IDs.channels.nonVegan.general,
) as TextChannel | undefined;
if (general === undefined) {
return;
}
let msg =
`${user}, you have been verified! Please check <#${IDs.channels.information.roles}> ` +
`and remember to follow the <#${IDs.channels.information.conduct}> and to respect ongoing discussion and debates.`;
@ -278,13 +270,10 @@ export async function finishVerifyMessages(
}
// Vegan
const general = await getTextBasedChannel(IDs.channels.vegan.general);
if (!isTextBasedChannel(general)) {
container.logger.error(
'Verification: Could not find general chat to welcome a vegan!',
);
const general = container.client.channels.cache.get(
IDs.channels.vegan.general,
) as TextChannel | undefined;
if (general === undefined) {
return;
}
const msg = `Welcome ${user}! Please check out <#${IDs.channels.information.roles}> :)`;
@ -300,16 +289,14 @@ export async function finishVerifyMessages(
'3. Have evidence for claims you make. "I don\'t know" is an acceptable answer. Chances are someone here knows or you can take time to find out\n' +
"4. Don't advocate for baby steps towards veganism. Participation in exploitation can stop today\n" +
'5. Differences in opinion between activists should be resolved in vegan spaces, not in the chat with non-vegans';
await user.send(activistMsg).catch(async () => {
const activist = await getTextBasedChannel(
await user.send(activistMsg).catch(() => {
const activist = container.client.channels.cache.get(
IDs.channels.activism.activism,
);
if (!isDMChannel(activist)) {
) as TextChannel | undefined;
if (activist === undefined) {
return;
}
await activist.send(activistMsg);
activist.send(activistMsg);
});
}
}