mirror of
https://github.com/ahmadk953/poixpixel-discord-bot.git
synced 2025-05-10 02:33:06 +00:00
chore: improve safety of commands
This commit is contained in:
parent
83bbf7b098
commit
7c2a99daf5
28 changed files with 329 additions and 235 deletions
|
@ -2,6 +2,7 @@
|
||||||
"token": "DISCORD_BOT_TOKEN",
|
"token": "DISCORD_BOT_TOKEN",
|
||||||
"clientId": "DISCORD_BOT_ID",
|
"clientId": "DISCORD_BOT_ID",
|
||||||
"guildId": "DISCORD_SERVER_ID",
|
"guildId": "DISCORD_SERVER_ID",
|
||||||
|
"serverInvite": "DISCORD_SERVER_INVITE_LINK",
|
||||||
"database": {
|
"database": {
|
||||||
"dbConnectionString": "POSTGRESQL_CONNECTION_STRING",
|
"dbConnectionString": "POSTGRESQL_CONNECTION_STRING",
|
||||||
"maxRetryAttempts": "MAX_RETRY_ATTEMPTS",
|
"maxRetryAttempts": "MAX_RETRY_ATTEMPTS",
|
||||||
|
|
|
@ -148,8 +148,9 @@ const command = {
|
||||||
),
|
),
|
||||||
|
|
||||||
async execute(interaction: ChatInputCommandInteraction) {
|
async execute(interaction: ChatInputCommandInteraction) {
|
||||||
await interaction.deferReply();
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
|
await interaction.deferReply();
|
||||||
const subcommand = interaction.options.getSubcommand();
|
const subcommand = interaction.options.getSubcommand();
|
||||||
|
|
||||||
switch (subcommand) {
|
switch (subcommand) {
|
||||||
|
|
|
@ -33,8 +33,9 @@ const command: SubcommandCommand = {
|
||||||
),
|
),
|
||||||
|
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
if (!interaction.isChatInputCommand()) return;
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
|
await interaction.deferReply();
|
||||||
const subcommand = interaction.options.getSubcommand();
|
const subcommand = interaction.options.getSubcommand();
|
||||||
|
|
||||||
if (subcommand === 'status') {
|
if (subcommand === 'status') {
|
||||||
|
@ -82,33 +83,30 @@ const command: SubcommandCommand = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await interaction.reply({ embeds: [embed] });
|
await interaction.editReply({ embeds: [embed] });
|
||||||
} else if (subcommand === 'setcount') {
|
} else if (subcommand === 'setcount') {
|
||||||
if (
|
if (
|
||||||
!interaction.memberPermissions?.has(
|
!interaction.memberPermissions?.has(
|
||||||
PermissionsBitField.Flags.Administrator,
|
PermissionsBitField.Flags.Administrator,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'You need administrator permissions to use this command.',
|
content: 'You need administrator permissions to use this command.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const count = interaction.options.getInteger('count');
|
const count = interaction.options.getInteger('count');
|
||||||
if (count === null) {
|
if (count === null) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'Invalid count specified.',
|
content: 'Invalid count specified.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await setCount(count);
|
await setCount(count);
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: `Count has been set to **${count}**. The next number should be **${count + 1}**.`,
|
content: `Count has been set to **${count}**. The next number should be **${count + 1}**.`,
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -74,12 +74,11 @@ const command: SubcommandCommand = {
|
||||||
),
|
),
|
||||||
|
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
if (!interaction.isChatInputCommand()) return;
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
await interaction.deferReply({
|
await interaction.deferReply({
|
||||||
flags: ['Ephemeral'],
|
flags: ['Ephemeral'],
|
||||||
});
|
});
|
||||||
await interaction.editReply('Processing...');
|
|
||||||
|
|
||||||
const config = loadConfig();
|
const config = loadConfig();
|
||||||
const subcommand = interaction.options.getSubcommand();
|
const subcommand = interaction.options.getSubcommand();
|
||||||
|
@ -100,7 +99,7 @@ const command: SubcommandCommand = {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
const approvalChannel = interaction.guild?.channels.cache.get(
|
const approvalChannel = interaction.guild.channels.cache.get(
|
||||||
config.channels.factApproval,
|
config.channels.factApproval,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {
|
||||||
builder,
|
builder,
|
||||||
} from '@/util/giveaways/giveawayManager.js';
|
} from '@/util/giveaways/giveawayManager.js';
|
||||||
import { createPaginationButtons } from '@/util/helpers.js';
|
import { createPaginationButtons } from '@/util/helpers.js';
|
||||||
|
import { loadConfig } from '@/util/configLoader';
|
||||||
|
|
||||||
const command: SubcommandCommand = {
|
const command: SubcommandCommand = {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
|
@ -53,16 +54,30 @@ const command: SubcommandCommand = {
|
||||||
),
|
),
|
||||||
|
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
if (!interaction.isChatInputCommand()) return;
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
|
const config = loadConfig();
|
||||||
|
const communityManagerRoleId = config.roles.staffRoles.find(
|
||||||
|
(role) => role.name === 'Community Manager',
|
||||||
|
)?.roleId;
|
||||||
|
|
||||||
|
if (!communityManagerRoleId) {
|
||||||
|
await interaction.reply({
|
||||||
|
content:
|
||||||
|
'Community Manager role not found in the configuration. Please contact a server admin.',
|
||||||
|
flags: ['Ephemeral'],
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!interaction.memberPermissions?.has(
|
!interaction.guild.members.cache
|
||||||
PermissionsBitField.Flags.ModerateMembers,
|
.find((member) => member.id === interaction.user.id)
|
||||||
)
|
?.roles.cache.has(communityManagerRoleId)
|
||||||
) {
|
) {
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: 'You do not have permission to manage giveaways.',
|
content: 'You do not have permission to manage giveaways.',
|
||||||
ephemeral: true,
|
flags: ['Ephemeral'],
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +167,7 @@ async function handleListGiveaways(interaction: ChatInputCommandInteraction) {
|
||||||
if (i.user.id !== interaction.user.id) {
|
if (i.user.id !== interaction.user.id) {
|
||||||
await i.reply({
|
await i.reply({
|
||||||
content: 'You cannot use these buttons.',
|
content: 'You cannot use these buttons.',
|
||||||
ephemeral: true,
|
flags: ['Ephemeral'],
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,12 @@ const command: OptionsCommand = {
|
||||||
.setRequired(false),
|
.setRequired(false),
|
||||||
),
|
),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
if (!interaction.guild) return;
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
await interaction.deferReply();
|
await interaction.deferReply();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const usersPerPage =
|
const usersPerPage = interaction.options.getInteger('limit') || 10;
|
||||||
(interaction.options.get('limit')?.value as number) || 10;
|
|
||||||
|
|
||||||
const allUsers = await getLevelLeaderboard(100);
|
const allUsers = await getLevelLeaderboard(100);
|
||||||
|
|
||||||
|
|
|
@ -15,18 +15,16 @@ const command: OptionsCommand = {
|
||||||
.setRequired(false),
|
.setRequired(false),
|
||||||
),
|
),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
const member = await interaction.guild?.members.fetch(
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
(interaction.options.get('user')?.value as string) || interaction.user.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!member) {
|
|
||||||
await interaction.reply('User not found in this server.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await interaction.deferReply();
|
await interaction.deferReply();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const member = await interaction.guild.members.fetch(
|
||||||
|
(interaction.options.get('user')?.value as string) ||
|
||||||
|
interaction.user.id,
|
||||||
|
);
|
||||||
|
|
||||||
const userData = await getUserLevel(member.id);
|
const userData = await getUserLevel(member.id);
|
||||||
const rankCard = await generateRankCard(member, userData);
|
const rankCard = await generateRankCard(member, userData);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { PermissionsBitField, SlashCommandBuilder } from 'discord.js';
|
||||||
import { updateMember, updateMemberModerationHistory } from '@/db/db.js';
|
import { updateMember, updateMemberModerationHistory } from '@/db/db.js';
|
||||||
import { parseDuration, scheduleUnban } from '@/util/helpers.js';
|
import { parseDuration, scheduleUnban } from '@/util/helpers.js';
|
||||||
import { OptionsCommand } from '@/types/CommandTypes.js';
|
import { OptionsCommand } from '@/types/CommandTypes.js';
|
||||||
|
import { loadConfig } from '@/util/configLoader.js';
|
||||||
import logAction from '@/util/logging/logAction.js';
|
import logAction from '@/util/logging/logAction.js';
|
||||||
|
|
||||||
const command: OptionsCommand = {
|
const command: OptionsCommand = {
|
||||||
|
@ -30,40 +31,62 @@ const command: OptionsCommand = {
|
||||||
.setRequired(false),
|
.setRequired(false),
|
||||||
),
|
),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
const moderator = await interaction.guild?.members.fetch(
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
interaction.user.id,
|
|
||||||
);
|
|
||||||
const member = await interaction.guild?.members.fetch(
|
|
||||||
interaction.options.get('member')!.value as string,
|
|
||||||
);
|
|
||||||
const reason = interaction.options.get('reason')?.value as string;
|
|
||||||
const banDuration = interaction.options.get('duration')?.value as
|
|
||||||
| string
|
|
||||||
| undefined;
|
|
||||||
|
|
||||||
if (
|
await interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
!interaction.memberPermissions?.has(
|
|
||||||
PermissionsBitField.Flags.BanMembers,
|
|
||||||
) ||
|
|
||||||
moderator!.roles.highest.position <= member!.roles.highest.position ||
|
|
||||||
!member?.bannable
|
|
||||||
) {
|
|
||||||
await interaction.reply({
|
|
||||||
content:
|
|
||||||
'You do not have permission to ban members or this member cannot be banned.',
|
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await member.user.send(
|
const moderator = await interaction.guild.members.fetch(
|
||||||
banDuration
|
interaction.user.id,
|
||||||
? `You have been banned from ${interaction.guild!.name} for ${banDuration}. Reason: ${reason}. You can join back at ${new Date(
|
|
||||||
Date.now() + parseDuration(banDuration),
|
|
||||||
).toUTCString()} using the link below:\nhttps://discord.gg/KRTGjxx7gY`
|
|
||||||
: `You been indefinitely banned from ${interaction.guild!.name}. Reason: ${reason}.`,
|
|
||||||
);
|
);
|
||||||
|
const member = await interaction.guild.members.fetch(
|
||||||
|
interaction.options.get('member')!.value as string,
|
||||||
|
);
|
||||||
|
const reason = interaction.options.get('reason')?.value as string;
|
||||||
|
const banDuration = interaction.options.get('duration')?.value as
|
||||||
|
| string
|
||||||
|
| undefined;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!interaction.memberPermissions?.has(
|
||||||
|
PermissionsBitField.Flags.BanMembers,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
await interaction.reply({
|
||||||
|
content: 'You do not have permission to ban members.',
|
||||||
|
flags: ['Ephemeral'],
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moderator.roles.highest.position <= member.roles.highest.position) {
|
||||||
|
await interaction.reply({
|
||||||
|
content:
|
||||||
|
'You cannot ban a member with equal or higher role than yours.',
|
||||||
|
flags: ['Ephemeral'],
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!member.bannable) {
|
||||||
|
await interaction.reply({
|
||||||
|
content: 'I do not have permission to ban this member.',
|
||||||
|
flags: ['Ephemeral'],
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await member.user.send(
|
||||||
|
banDuration
|
||||||
|
? `You have been banned from ${interaction.guild!.name} for ${banDuration}. Reason: ${reason}. You can join back at ${new Date(
|
||||||
|
Date.now() + parseDuration(banDuration),
|
||||||
|
).toUTCString()} using the link below:\n${interaction.guild.vanityURLCode ?? loadConfig().serverInvite}`
|
||||||
|
: `You been indefinitely banned from ${interaction.guild!.name}. Reason: ${reason}.`,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to send DM:', error);
|
||||||
|
}
|
||||||
await member.ban({ reason });
|
await member.ban({ reason });
|
||||||
|
|
||||||
if (banDuration) {
|
if (banDuration) {
|
||||||
|
@ -97,20 +120,19 @@ const command: OptionsCommand = {
|
||||||
guild: interaction.guild!,
|
guild: interaction.guild!,
|
||||||
action: 'ban',
|
action: 'ban',
|
||||||
target: member,
|
target: member,
|
||||||
moderator: moderator!,
|
moderator,
|
||||||
reason,
|
reason,
|
||||||
});
|
});
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: banDuration
|
content: banDuration
|
||||||
? `<@${member.id}> has been banned for ${banDuration}. Reason: ${reason}`
|
? `<@${member.id}> has been banned for ${banDuration}. Reason: ${reason}`
|
||||||
: `<@${member.id}> has been indefinitely banned. Reason: ${reason}`,
|
: `<@${member.id}> has been indefinitely banned. Reason: ${reason}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ban command error:', error);
|
console.error('Ban command error:', error);
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'Unable to ban member.',
|
content: 'Unable to ban member.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { PermissionsBitField, SlashCommandBuilder } from 'discord.js';
|
||||||
|
|
||||||
import { updateMemberModerationHistory } from '@/db/db.js';
|
import { updateMemberModerationHistory } from '@/db/db.js';
|
||||||
import { OptionsCommand } from '@/types/CommandTypes.js';
|
import { OptionsCommand } from '@/types/CommandTypes.js';
|
||||||
|
import { loadConfig } from '@/util/configLoader.js';
|
||||||
import logAction from '@/util/logging/logAction.js';
|
import logAction from '@/util/logging/logAction.js';
|
||||||
|
|
||||||
const command: OptionsCommand = {
|
const command: OptionsCommand = {
|
||||||
|
@ -21,33 +22,48 @@ const command: OptionsCommand = {
|
||||||
.setRequired(true),
|
.setRequired(true),
|
||||||
),
|
),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
const moderator = await interaction.guild?.members.fetch(
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
interaction.user.id,
|
|
||||||
);
|
|
||||||
const member = await interaction.guild?.members.fetch(
|
|
||||||
interaction.options.get('member')!.value as string,
|
|
||||||
);
|
|
||||||
const reason = interaction.options.get('reason')?.value as string;
|
|
||||||
|
|
||||||
if (
|
await interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
!interaction.memberPermissions?.has(
|
|
||||||
PermissionsBitField.Flags.KickMembers,
|
|
||||||
) ||
|
|
||||||
moderator!.roles.highest.position <= member!.roles.highest.position ||
|
|
||||||
!member?.kickable
|
|
||||||
) {
|
|
||||||
await interaction.reply({
|
|
||||||
content:
|
|
||||||
'You do not have permission to kick members or this member cannot be kicked.',
|
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const moderator = await interaction.guild.members.fetch(
|
||||||
|
interaction.user.id,
|
||||||
|
);
|
||||||
|
const member = await interaction.guild.members.fetch(
|
||||||
|
interaction.options.get('member')!.value as string,
|
||||||
|
);
|
||||||
|
const reason = interaction.options.get('reason')?.value as string;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!interaction.memberPermissions?.has(
|
||||||
|
PermissionsBitField.Flags.KickMembers,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: 'You do not have permission to kick members.',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moderator!.roles.highest.position <= member.roles.highest.position) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content:
|
||||||
|
'You cannot kick a member with equal or higher role than yours.',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!member.kickable) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: 'I do not have permission to kick this member.',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await member.user.send(
|
await member.user.send(
|
||||||
`You have been kicked from ${interaction.guild!.name}. Reason: ${reason}. You can join back at: \nhttps://discord.gg/KRTGjxx7gY`,
|
`You have been kicked from ${interaction.guild!.name}. Reason: ${reason}. You can join back at: \n${interaction.guild.vanityURLCode ?? loadConfig().serverInvite}`,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to send DM to kicked user:', error);
|
console.error('Failed to send DM to kicked user:', error);
|
||||||
|
@ -68,18 +84,17 @@ const command: OptionsCommand = {
|
||||||
guild: interaction.guild!,
|
guild: interaction.guild!,
|
||||||
action: 'kick',
|
action: 'kick',
|
||||||
target: member,
|
target: member,
|
||||||
moderator: moderator!,
|
moderator,
|
||||||
reason,
|
reason,
|
||||||
});
|
});
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: `<@${member.id}> has been kicked. Reason: ${reason}`,
|
content: `<@${member.id}> has been kicked. Reason: ${reason}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Kick command error:', error);
|
console.error('Kick command error:', error);
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'Unable to kick member.',
|
content: 'Unable to kick member.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -30,38 +30,52 @@ const command: OptionsCommand = {
|
||||||
.setRequired(true),
|
.setRequired(true),
|
||||||
),
|
),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
const moderator = await interaction.guild?.members.fetch(
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
interaction.user.id,
|
|
||||||
);
|
|
||||||
const member = await interaction.guild?.members.fetch(
|
|
||||||
interaction.options.get('member')!.value as string,
|
|
||||||
);
|
|
||||||
const reason = interaction.options.get('reason')?.value as string;
|
|
||||||
const muteDuration = interaction.options.get('duration')?.value as string;
|
|
||||||
|
|
||||||
if (
|
await interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
!interaction.memberPermissions?.has(
|
|
||||||
PermissionsBitField.Flags.ModerateMembers,
|
|
||||||
) ||
|
|
||||||
moderator!.roles.highest.position <= member!.roles.highest.position ||
|
|
||||||
!member?.moderatable
|
|
||||||
) {
|
|
||||||
await interaction.reply({
|
|
||||||
content:
|
|
||||||
'You do not have permission to timeout members or this member cannot be timed out.',
|
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const moderator = await interaction.guild.members.fetch(
|
||||||
|
interaction.user.id,
|
||||||
|
);
|
||||||
|
const member = await interaction.guild.members.fetch(
|
||||||
|
interaction.options.get('member')!.value as string,
|
||||||
|
);
|
||||||
|
const reason = interaction.options.get('reason')?.value as string;
|
||||||
|
const muteDuration = interaction.options.get('duration')?.value as string;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!interaction.memberPermissions?.has(
|
||||||
|
PermissionsBitField.Flags.KickMembers,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: 'You do not have permission to mute members.',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moderator.roles.highest.position <= member.roles.highest.position) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content:
|
||||||
|
'You cannot mute a member with equal or higher role than yours.',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!member.moderatable) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: 'I do not have permission to mute this member.',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const durationMs = parseDuration(muteDuration);
|
const durationMs = parseDuration(muteDuration);
|
||||||
const maxTimeout = 28 * 24 * 60 * 60 * 1000;
|
const maxTimeout = 28 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
if (durationMs > maxTimeout) {
|
if (durationMs > maxTimeout) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'Timeout duration cannot exceed 28 days.',
|
content: 'Timeout duration cannot exceed 28 days.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -94,19 +108,18 @@ const command: OptionsCommand = {
|
||||||
guild: interaction.guild!,
|
guild: interaction.guild!,
|
||||||
action: 'mute',
|
action: 'mute',
|
||||||
target: member,
|
target: member,
|
||||||
moderator: moderator!,
|
moderator,
|
||||||
reason,
|
reason,
|
||||||
duration: muteDuration,
|
duration: muteDuration,
|
||||||
});
|
});
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: `<@${member.id}> has been timed out for ${muteDuration}. Reason: ${reason}`,
|
content: `<@${member.id}> has been muted for ${muteDuration}. Reason: ${reason}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Mute command error:', error);
|
console.error('Mute command error:', error);
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'Unable to timeout member.',
|
content: 'Unable to timeout member.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,52 +20,53 @@ const command: OptionsCommand = {
|
||||||
.setRequired(true),
|
.setRequired(true),
|
||||||
),
|
),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
const userId = interaction.options.get('userid')!.value as string;
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
const reason = interaction.options.get('reason')?.value as string;
|
|
||||||
|
|
||||||
if (
|
interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
!interaction.memberPermissions?.has(PermissionsBitField.Flags.BanMembers)
|
|
||||||
) {
|
|
||||||
await interaction.reply({
|
|
||||||
content: 'You do not have permission to unban users.',
|
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const userId = interaction.options.get('userid')?.value as string;
|
||||||
|
const reason = interaction.options.get('reason')?.value as string;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!interaction.memberPermissions?.has(
|
||||||
|
PermissionsBitField.Flags.BanMembers,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: 'You do not have permission to unban users.',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const ban = await interaction.guild?.bans.fetch(userId);
|
const ban = await interaction.guild.bans.fetch(userId);
|
||||||
if (!ban) {
|
if (!ban) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'This user is not banned.',
|
content: 'This user is not banned.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'Error getting ban. Is this user banned?',
|
content: 'Error getting ban. Is this user banned?',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeUnban(
|
await executeUnban(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guildId!,
|
interaction.guild.id,
|
||||||
userId,
|
userId,
|
||||||
reason,
|
reason,
|
||||||
);
|
);
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: `<@${userId}> has been unbanned. Reason: ${reason}`,
|
content: `<@${userId}> has been unbanned. Reason: ${reason}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'Unable to unban user.',
|
content: 'Unable to unban user.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,43 +20,44 @@ const command: OptionsCommand = {
|
||||||
.setRequired(true),
|
.setRequired(true),
|
||||||
),
|
),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
const moderator = await interaction.guild?.members.fetch(
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
interaction.user.id,
|
|
||||||
);
|
|
||||||
const member = await interaction.guild?.members.fetch(
|
|
||||||
interaction.options.get('member')!.value as string,
|
|
||||||
);
|
|
||||||
const reason = interaction.options.get('reason')?.value as string;
|
|
||||||
|
|
||||||
if (
|
await interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
!interaction.memberPermissions?.has(
|
|
||||||
PermissionsBitField.Flags.ModerateMembers,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
await interaction.reply({
|
|
||||||
content: 'You do not have permission to unmute members.',
|
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const moderator = await interaction.guild.members.fetch(
|
||||||
|
interaction.user.id,
|
||||||
|
);
|
||||||
|
const member = await interaction.guild.members.fetch(
|
||||||
|
interaction.options.get('member')!.value as string,
|
||||||
|
);
|
||||||
|
const reason = interaction.options.get('reason')?.value as string;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!interaction.memberPermissions?.has(
|
||||||
|
PermissionsBitField.Flags.ModerateMembers,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: 'You do not have permission to unmute members.',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
await executeUnmute(
|
await executeUnmute(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guild!.id,
|
interaction.guild.id,
|
||||||
member!.id,
|
member.id,
|
||||||
reason,
|
reason,
|
||||||
moderator,
|
moderator,
|
||||||
);
|
);
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: `<@${member!.id}>'s timeout has been removed. Reason: ${reason}`,
|
content: `<@${member.id}>'s timeout has been removed. Reason: ${reason}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Unmute command error:', error);
|
console.error('Unmute command error:', error);
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'Unable to unmute member.',
|
content: 'Unable to unmute member.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -21,29 +21,38 @@ const command: OptionsCommand = {
|
||||||
.setRequired(true),
|
.setRequired(true),
|
||||||
),
|
),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
const moderator = await interaction.guild?.members.fetch(
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
interaction.user.id,
|
|
||||||
);
|
|
||||||
const member = await interaction.guild?.members.fetch(
|
|
||||||
interaction.options.get('member')!.value as unknown as string,
|
|
||||||
);
|
|
||||||
const reason = interaction.options.get('reason')
|
|
||||||
?.value as unknown as string;
|
|
||||||
|
|
||||||
if (
|
await interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
!interaction.memberPermissions?.has(
|
|
||||||
PermissionsBitField.Flags.ModerateMembers,
|
|
||||||
) ||
|
|
||||||
moderator!.roles.highest.position <= member!.roles.highest.position
|
|
||||||
) {
|
|
||||||
await interaction.reply({
|
|
||||||
content: 'You do not have permission to warn this member.',
|
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const moderator = await interaction.guild.members.fetch(
|
||||||
|
interaction.user.id,
|
||||||
|
);
|
||||||
|
const member = await interaction.guild.members.fetch(
|
||||||
|
interaction.options.get('member')!.value as unknown as string,
|
||||||
|
);
|
||||||
|
const reason = interaction.options.getString('reason')!;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!interaction.memberPermissions?.has(
|
||||||
|
PermissionsBitField.Flags.ModerateMembers,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: 'You do not have permission to warn members.',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moderator.roles.highest.position <= member.roles.highest.position) {
|
||||||
|
await interaction.editReply({
|
||||||
|
content:
|
||||||
|
'You cannot warn a member with equal or higher role than yours.',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await updateMemberModerationHistory({
|
await updateMemberModerationHistory({
|
||||||
discordId: member!.user.id,
|
discordId: member!.user.id,
|
||||||
moderatorDiscordId: interaction.user.id,
|
moderatorDiscordId: interaction.user.id,
|
||||||
|
@ -61,14 +70,13 @@ const command: OptionsCommand = {
|
||||||
moderator: moderator!,
|
moderator: moderator!,
|
||||||
reason: reason,
|
reason: reason,
|
||||||
});
|
});
|
||||||
await interaction.reply(
|
await interaction.editReply(
|
||||||
`<@${member!.user.id}> has been warned. Reason: ${reason}`,
|
`<@${member!.user.id}> has been warned. Reason: ${reason}`,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'There was an error trying to warn the member.',
|
content: 'There was an error trying to warn the member.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,25 +8,27 @@ const command: Command = {
|
||||||
.setDescription('Simulates a new member joining'),
|
.setDescription('Simulates a new member joining'),
|
||||||
|
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
const guild = interaction.guild;
|
const guild = interaction.guild;
|
||||||
|
|
||||||
|
await interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!interaction.memberPermissions!.has(
|
!interaction.memberPermissions!.has(
|
||||||
PermissionsBitField.Flags.Administrator,
|
PermissionsBitField.Flags.Administrator,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'You do not have permission to use this command.',
|
content: 'You do not have permission to use this command.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fakeMember = await guild!.members.fetch(interaction.user.id);
|
const fakeMember = await guild.members.fetch(interaction.user.id);
|
||||||
guild!.client.emit('guildMemberAdd', fakeMember);
|
guild.client.emit('guildMemberAdd', fakeMember);
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'Triggered the join event!',
|
content: 'Triggered the join event!',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,25 +9,26 @@ const command: Command = {
|
||||||
.setDescription('Simulates a member leaving'),
|
.setDescription('Simulates a member leaving'),
|
||||||
|
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
const guild = interaction.guild;
|
const guild = interaction.guild;
|
||||||
|
|
||||||
|
await interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!interaction.memberPermissions!.has(
|
!interaction.memberPermissions!.has(
|
||||||
PermissionsBitField.Flags.Administrator,
|
PermissionsBitField.Flags.Administrator,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'You do not have permission to use this command.',
|
content: 'You do not have permission to use this command.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const fakeMember = await guild!.members.fetch(interaction.user.id);
|
const fakeMember = await guild.members.fetch(interaction.user.id);
|
||||||
guild!.client.emit('guildMemberRemove', fakeMember);
|
guild.client.emit('guildMemberRemove', fakeMember);
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'Triggered the leave event!',
|
content: 'Triggered the leave event!',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await updateMember({
|
await updateMember({
|
||||||
|
|
|
@ -14,12 +14,15 @@ const command: Command = {
|
||||||
.setDescription('(Admin Only) Display the current configuration')
|
.setDescription('(Admin Only) Display the current configuration')
|
||||||
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
|
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
|
await interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!interaction.memberPermissions?.has(PermissionFlagsBits.Administrator)
|
!interaction.memberPermissions?.has(PermissionFlagsBits.Administrator)
|
||||||
) {
|
) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'You do not have permission to use this command.',
|
content: 'You do not have permission to use this command.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -180,10 +183,9 @@ const command: Command = {
|
||||||
? [createPaginationButtons(pages.length, currentPage)]
|
? [createPaginationButtons(pages.length, currentPage)]
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
const reply = await interaction.reply({
|
const reply = await interaction.editReply({
|
||||||
embeds: [pages[currentPage]],
|
embeds: [pages[currentPage]],
|
||||||
components,
|
components,
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (pages.length <= 1) return;
|
if (pages.length <= 1) return;
|
||||||
|
|
|
@ -26,9 +26,11 @@ const command: OptionsCommand = {
|
||||||
),
|
),
|
||||||
|
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
try {
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
await interaction.deferReply();
|
|
||||||
|
|
||||||
|
await interaction.deferReply();
|
||||||
|
|
||||||
|
try {
|
||||||
const client = interaction.client as ExtendedClient;
|
const client = interaction.client as ExtendedClient;
|
||||||
const commandName = interaction.options.getString('command');
|
const commandName = interaction.options.getString('command');
|
||||||
|
|
||||||
|
@ -178,7 +180,7 @@ async function handleSpecificCommand(
|
||||||
const cmd = client.commands.get(commandName);
|
const cmd = client.commands.get(commandName);
|
||||||
|
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
return interaction.reply({
|
return interaction.editReply({
|
||||||
content: `Command \`${commandName}\` not found.`,
|
content: `Command \`${commandName}\` not found.`,
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
});
|
});
|
||||||
|
@ -227,7 +229,7 @@ async function handleSpecificCommand(
|
||||||
inline: false,
|
inline: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
return interaction.reply({ embeds: [embed] });
|
return interaction.editReply({ embeds: [embed] });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,6 +16,10 @@ const command: Command = {
|
||||||
.setName('members')
|
.setName('members')
|
||||||
.setDescription('Lists all non-bot members of the server'),
|
.setDescription('Lists all non-bot members of the server'),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
|
await interaction.deferReply();
|
||||||
|
|
||||||
let members = await getAllMembers();
|
let members = await getAllMembers();
|
||||||
members = members.sort((a, b) =>
|
members = members.sort((a, b) =>
|
||||||
(a.discordUsername ?? '').localeCompare(b.discordUsername ?? ''),
|
(a.discordUsername ?? '').localeCompare(b.discordUsername ?? ''),
|
||||||
|
@ -63,7 +67,7 @@ const command: Command = {
|
||||||
const components =
|
const components =
|
||||||
pages.length > 1 ? [getButtonActionRow(), getSelectMenuRow()] : [];
|
pages.length > 1 ? [getButtonActionRow(), getSelectMenuRow()] : [];
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
embeds: [pages[currentPage]],
|
embeds: [pages[currentPage]],
|
||||||
components,
|
components,
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,7 +8,7 @@ const command: Command = {
|
||||||
.setDescription('Check the latency from you to the bot'),
|
.setDescription('Check the latency from you to the bot'),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
await interaction.reply(
|
await interaction.reply(
|
||||||
`Pong! Latency: ${Date.now() - interaction.createdTimestamp}ms`,
|
`🏓 Pong! Latency: ${Date.now() - interaction.createdTimestamp}ms`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,21 +8,22 @@ const command: Command = {
|
||||||
.setName('recalculatelevels')
|
.setName('recalculatelevels')
|
||||||
.setDescription('(Admin Only) Recalculate all user levels'),
|
.setDescription('(Admin Only) Recalculate all user levels'),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
|
await interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
|
await interaction.editReply('Recalculating levels...');
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!interaction.memberPermissions?.has(
|
!interaction.memberPermissions?.has(
|
||||||
PermissionsBitField.Flags.Administrator,
|
PermissionsBitField.Flags.Administrator,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'You do not have permission to use this command.',
|
content: 'You do not have permission to use this command.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await interaction.deferReply();
|
|
||||||
await interaction.editReply('Recalculating levels...');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await recalculateUserLevels();
|
await recalculateUserLevels();
|
||||||
await interaction.editReply('Levels recalculated successfully!');
|
await interaction.editReply('Levels recalculated successfully!');
|
||||||
|
|
|
@ -36,7 +36,9 @@ const command: SubcommandCommand = {
|
||||||
),
|
),
|
||||||
|
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
if (!interaction.isChatInputCommand()) return;
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
|
await interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
|
|
||||||
const config = loadConfig();
|
const config = loadConfig();
|
||||||
const managerRoleId = config.roles.staffRoles.find(
|
const managerRoleId = config.roles.staffRoles.find(
|
||||||
|
@ -52,18 +54,15 @@ const command: SubcommandCommand = {
|
||||||
PermissionsBitField.Flags.Administrator,
|
PermissionsBitField.Flags.Administrator,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content:
|
content:
|
||||||
'You do not have permission to use this command. This command is restricted to users with the Manager role.',
|
'You do not have permission to use this command. This command is restricted to users with the Manager role.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const subcommand = interaction.options.getSubcommand();
|
const subcommand = interaction.options.getSubcommand();
|
||||||
|
|
||||||
await interaction.deferReply({ flags: ['Ephemeral'] });
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (subcommand === 'database') {
|
if (subcommand === 'database') {
|
||||||
await handleDatabaseReconnect(interaction);
|
await handleDatabaseReconnect(interaction);
|
||||||
|
|
|
@ -18,6 +18,10 @@ const command: Command = {
|
||||||
.setName('restart')
|
.setName('restart')
|
||||||
.setDescription('(Manager Only) Restart the bot'),
|
.setDescription('(Manager Only) Restart the bot'),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
|
await interaction.deferReply({ flags: ['Ephemeral'] });
|
||||||
|
|
||||||
const config = loadConfig();
|
const config = loadConfig();
|
||||||
const managerRoleId = config.roles.staffRoles.find(
|
const managerRoleId = config.roles.staffRoles.find(
|
||||||
(role) => role.name === 'Manager',
|
(role) => role.name === 'Manager',
|
||||||
|
@ -32,17 +36,15 @@ const command: Command = {
|
||||||
PermissionsBitField.Flags.Administrator,
|
PermissionsBitField.Flags.Administrator,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content:
|
content:
|
||||||
'You do not have permission to restart the bot. This command is restricted to users with the Manager role.',
|
'You do not have permission to restart the bot. This command is restricted to users with the Manager role.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'Restarting the bot... This may take a few moments.',
|
content: 'Restarting the bot... This may take a few moments.',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const dbConnected = await ensureDatabaseConnection();
|
const dbConnected = await ensureDatabaseConnection();
|
||||||
|
|
|
@ -7,8 +7,10 @@ const command: Command = {
|
||||||
.setName('server')
|
.setName('server')
|
||||||
.setDescription('Provides information about the server.'),
|
.setDescription('Provides information about the server.'),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
await interaction.reply(
|
await interaction.reply(
|
||||||
`The server **${interaction!.guild!.name}** has **${interaction!.guild!.memberCount}** members and was created on **${interaction!.guild!.createdAt}**. It is **${new Date().getFullYear() - interaction!.guild!.createdAt.getFullYear()!}** years old.`,
|
`The server **${interaction.guild.name}** has **${interaction.guild.memberCount}** members and was created on **${interaction.guild.createdAt}**. It is **${new Date().getFullYear() - interaction.guild.createdAt.getFullYear()}** years old.`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,13 +19,17 @@ const command: OptionsCommand = {
|
||||||
.setRequired(true),
|
.setRequired(true),
|
||||||
),
|
),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
|
await interaction.deferReply();
|
||||||
|
|
||||||
const userOption = interaction.options.get(
|
const userOption = interaction.options.get(
|
||||||
'user',
|
'user',
|
||||||
) as unknown as GuildMember;
|
) as unknown as GuildMember;
|
||||||
const user = userOption.user;
|
const user = userOption.user;
|
||||||
|
|
||||||
if (!userOption || !user) {
|
if (!userOption || !user) {
|
||||||
await interaction.reply('User not found');
|
await interaction.editReply('User not found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
|
@ -33,7 +37,7 @@ const command: OptionsCommand = {
|
||||||
PermissionsBitField.Flags.ModerateMembers,
|
PermissionsBitField.Flags.ModerateMembers,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
await interaction.reply(
|
await interaction.editReply(
|
||||||
'You do not have permission to view member information.',
|
'You do not have permission to view member information.',
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -140,7 +144,7 @@ const command: OptionsCommand = {
|
||||||
iconURL: interaction.user.displayAvatarURL(),
|
iconURL: interaction.user.displayAvatarURL(),
|
||||||
});
|
});
|
||||||
|
|
||||||
await interaction.reply({ embeds: [embed] });
|
await interaction.editReply({ embeds: [embed] });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -71,12 +71,16 @@ const command: SubcommandCommand = {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
execute: async (interaction) => {
|
execute: async (interaction) => {
|
||||||
if (!interaction.isChatInputCommand()) return;
|
if (!interaction.isChatInputCommand() || !interaction.guild) return;
|
||||||
|
|
||||||
const commandUser = interaction.guild?.members.cache.get(
|
const commandUser = interaction.guild.members.cache.get(
|
||||||
interaction.user.id,
|
interaction.user.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await interaction.deferReply({
|
||||||
|
flags: ['Ephemeral'],
|
||||||
|
});
|
||||||
|
|
||||||
const config = loadConfig();
|
const config = loadConfig();
|
||||||
const managerRoleId = config.roles.staffRoles.find(
|
const managerRoleId = config.roles.staffRoles.find(
|
||||||
(role) => role.name === 'Manager',
|
(role) => role.name === 'Manager',
|
||||||
|
@ -87,18 +91,12 @@ const command: SubcommandCommand = {
|
||||||
!managerRoleId ||
|
!managerRoleId ||
|
||||||
commandUser.roles.highest.comparePositionTo(managerRoleId) < 0
|
commandUser.roles.highest.comparePositionTo(managerRoleId) < 0
|
||||||
) {
|
) {
|
||||||
await interaction.reply({
|
await interaction.editReply({
|
||||||
content: 'You do not have permission to use this command',
|
content: 'You do not have permission to use this command',
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await interaction.deferReply({
|
|
||||||
flags: ['Ephemeral'],
|
|
||||||
});
|
|
||||||
await interaction.editReply('Processing...');
|
|
||||||
|
|
||||||
const subcommand = interaction.options.getSubcommand();
|
const subcommand = interaction.options.getSubcommand();
|
||||||
const user = interaction.options.getUser('user', true);
|
const user = interaction.options.getUser('user', true);
|
||||||
const amount = interaction.options.getInteger('amount', false);
|
const amount = interaction.options.getInteger('amount', false);
|
||||||
|
|
|
@ -12,9 +12,10 @@ async function startBot() {
|
||||||
GatewayIntentBits.Guilds,
|
GatewayIntentBits.Guilds,
|
||||||
GatewayIntentBits.GuildMembers,
|
GatewayIntentBits.GuildMembers,
|
||||||
GatewayIntentBits.GuildMessages,
|
GatewayIntentBits.GuildMessages,
|
||||||
|
GatewayIntentBits.GuildModeration,
|
||||||
|
GatewayIntentBits.GuildInvites,
|
||||||
GatewayIntentBits.MessageContent,
|
GatewayIntentBits.MessageContent,
|
||||||
GatewayIntentBits.GuildMessageReactions,
|
GatewayIntentBits.GuildMessageReactions,
|
||||||
GatewayIntentBits.GuildModeration,
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
config,
|
config,
|
||||||
|
|
|
@ -33,6 +33,10 @@ export class ExtendedClient extends Client {
|
||||||
console.log('Skipping command deployment (SKIP_COMMAND_DEPLOY=true)');
|
console.log('Skipping command deployment (SKIP_COMMAND_DEPLOY=true)');
|
||||||
const commandFiles = await this.loadCommandsWithoutDeploying();
|
const commandFiles = await this.loadCommandsWithoutDeploying();
|
||||||
|
|
||||||
|
if (!commandFiles?.length) {
|
||||||
|
throw new Error('No commands found');
|
||||||
|
}
|
||||||
|
|
||||||
await registerEvents(this);
|
await registerEvents(this);
|
||||||
console.log(
|
console.log(
|
||||||
`Loaded ${commandFiles.length} commands and registered events (without deployment)`,
|
`Loaded ${commandFiles.length} commands and registered events (without deployment)`,
|
||||||
|
|
|
@ -5,6 +5,7 @@ export interface Config {
|
||||||
token: string;
|
token: string;
|
||||||
clientId: string;
|
clientId: string;
|
||||||
guildId: string;
|
guildId: string;
|
||||||
|
serverInvite: string;
|
||||||
database: {
|
database: {
|
||||||
dbConnectionString: string;
|
dbConnectionString: string;
|
||||||
maxRetryAttempts: number;
|
maxRetryAttempts: number;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue