Skip to content

Commit

Permalink
Merge pull request #50 from jag3dagster/refactor-editreply
Browse files Browse the repository at this point in the history
refactor: Make command structure more consistent
  • Loading branch information
juddisjudd authored Jan 30, 2025
2 parents fd343a1 + 63f8ed6 commit f5caa9f
Show file tree
Hide file tree
Showing 14 changed files with 72 additions and 117 deletions.
7 changes: 3 additions & 4 deletions src/commands/fun/magic8ball.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CommandInteraction, SlashCommandBuilder } from 'discord.js';
import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js';
import { Command } from '../../interfaces/command';

const responses = [
Expand Down Expand Up @@ -31,9 +31,8 @@ const Magic8Ball: Command = {
.addStringOption((option) =>
option.setName('question').setDescription('Your question for the magic 8-ball').setRequired(true)
),
async run(interaction: CommandInteraction) {
const questionOption = interaction.options.get('question', true);
const question = questionOption.value;
async run(interaction: ChatInputCommandInteraction) {
const question = interaction.options.getString('question', true);
const answer = responses[Math.floor(Math.random() * responses.length)];
await interaction.reply(`🎱 *Question:* ${question}\n🔮 *Answer:* ${answer}`);
},
Expand Down
6 changes: 3 additions & 3 deletions src/commands/fun/rps.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CommandInteraction, SlashCommandBuilder } from 'discord.js';
import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js';
import { Command } from '../../interfaces/command';

const choices = ['rock', 'paper', 'scissors'];
Expand Down Expand Up @@ -32,8 +32,8 @@ const RockPaperScissors: Command = {
.setRequired(true)
.addChoices(...choices.map((choice) => ({ name: choice, value: choice })))
),
async run(interaction: CommandInteraction) {
const userChoice = interaction.options.get('choice', true)?.value as string;
async run(interaction: ChatInputCommandInteraction) {
const userChoice = interaction.options.getString('choice', true);
const botChoice = choices[Math.floor(Math.random() * choices.length)];
const result = determineWinner(userChoice, botChoice);

Expand Down
7 changes: 4 additions & 3 deletions src/commands/misc/guild.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SlashCommandBuilder } from 'discord.js';
import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js';
import { Command } from '../../interfaces/command';

const Guild: Command = {
Expand All @@ -18,8 +18,9 @@ const Guild: Command = {
{ name: 'Cfx.re', value: 'cfx' }
)
),
run: async (interaction) => {
const guildName = interaction.options.get('name')?.value as string;

run: async (interaction: ChatInputCommandInteraction) => {
const guildName = interaction.options.getString('name');

switch (guildName) {
case 'qbox':
Expand Down
21 changes: 8 additions & 13 deletions src/commands/moderation/ban.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SlashCommandBuilder, PermissionFlagsBits, CommandInteraction } from 'discord.js';
import { SlashCommandBuilder, PermissionFlagsBits, ChatInputCommandInteraction } from 'discord.js';
import { PrismaClient } from '@prisma/client';
import { Command } from '../../interfaces/command';
import logger from '../../utils/logger';
Expand All @@ -9,6 +9,7 @@ const Ban: Command = {
data: new SlashCommandBuilder()
.setName('ban')
.setDescription('Ban a user')
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
.addUserOption((option) => option.setName('user').setDescription('The user to ban').setRequired(true))
.addStringOption((option) => option.setName('reason').setDescription('The reason for the ban').setRequired(false))
.addIntegerOption((option) =>
Expand All @@ -18,24 +19,18 @@ const Ban: Command = {
.setRequired(false)
),

async run(interaction: CommandInteraction) {
async run(interaction: ChatInputCommandInteraction) {
if (!interaction.guild) {
await interaction.reply({ content: 'This command can only be used in a guild.', ephemeral: true });
return;
}

if (!interaction.memberPermissions?.has(PermissionFlagsBits.BanMembers)) {
await interaction.reply({ content: 'Insufficient permissions.', ephemeral: true });
return;
}

const userOption = interaction.options.get('user');
const reasonOption = interaction.options.get('reason');
const deleteMessageDaysOption = interaction.options.get('delete_message_days');
const user = interaction.options.getUser('user', true);
const reasonOption = interaction.options.getString('reason');
const deleteMessageDaysOption = interaction.options.getInteger('delete_message_days');

const user = userOption?.user;
const reason = (reasonOption?.value as string) || 'No reason provided';
const deleteMessageDays = deleteMessageDaysOption ? parseInt(deleteMessageDaysOption.value as string) : 0;
const reason = (reasonOption as string) || 'No reason provided';
const deleteMessageDays = deleteMessageDaysOption || 0;

if (!user) {
await interaction.reply({ content: 'User not found!', ephemeral: true });
Expand Down
13 changes: 4 additions & 9 deletions src/commands/moderation/bulkunban.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
import { SlashCommandBuilder, PermissionFlagsBits } from 'discord.js';
import { SlashCommandBuilder, PermissionFlagsBits, ChatInputCommandInteraction } from 'discord.js';
import { Command } from '../../interfaces/command';
import logger from '../../utils/logger';

const BulkUnban: Command = {
data: new SlashCommandBuilder()
.setName('bulkunban')
.setDescription('Unban all people with the reason included')
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
.addStringOption((option) =>
option
.setName('reason')
.setDescription('The reason to check for, this checks if the provided string is included in the reason')
.setRequired(true)
),
async run(interaction) {
async run(interaction: ChatInputCommandInteraction) {
if (!interaction.guild) {
await interaction.reply('This command can only be run in a guild.');
return;
}

if (!interaction.memberPermissions?.has(PermissionFlagsBits.BanMembers)) {
await interaction.reply('Insufficient permissions.');
return;
}

const reasonOptionRaw = interaction.options.get('reason')?.value;
const reasonOption = typeof reasonOptionRaw === 'string' ? reasonOptionRaw : 'No reason provided';
const reasonOption = interaction.options.getString('reason', true);

let amount = 0;

Expand Down
24 changes: 8 additions & 16 deletions src/commands/moderation/clearwarns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const ClearWarn: Command = {
data: new SlashCommandBuilder()
.setName('clearwarn')
.setDescription('Clear warnings of a user')
.setDefaultMemberPermissions(PermissionFlagsBits.KickMembers)
.addUserOption((option) =>
option.setName('user').setDescription('The user whose warnings will be cleared').setRequired(true)
)
Expand All @@ -25,16 +26,13 @@ const ClearWarn: Command = {
return;
}

if (!interaction.memberPermissions?.has(PermissionFlagsBits.KickMembers)) {
await interaction.reply({ content: 'Insufficient permissions.', ephemeral: true });
return;
}
interaction.deferReply({ ephemeral: true });

const userOption = interaction.options.getUser('user', true);
const member: GuildMember | null = await interaction.guild.members.fetch(userOption.id).catch(() => null);

if (!member) {
await interaction.reply({ content: 'User not found in the guild.', ephemeral: true });
await interaction.editReply('User not found in the guild.');
return;
}
const warnIdOption = interaction.options.getString('warnid', true);
Expand All @@ -55,15 +53,12 @@ const ClearWarn: Command = {
await member.timeout(null);
}

await interaction.reply({
content: `Cleared all warnings and removed timeout for <@${userOption.id}>.`,
ephemeral: true,
});
await interaction.editReply(`Cleared all warnings and removed timeout for <@${userOption.id}>.`);
} else {
// Clear specific warning
const warnId = parseInt(warnIdOption);
if (isNaN(warnId)) {
await interaction.reply({ content: 'Invalid warning ID provided.', ephemeral: true });
await interaction.editReply('Invalid warning ID provided.');
return;
}

Expand All @@ -75,17 +70,14 @@ const ClearWarn: Command = {
});

if (result.count === 0) {
await interaction.reply({ content: 'No warning found with the provided ID for this user.', ephemeral: true });
await interaction.editReply('No warning found with the provided ID for this user.');
} else {
await interaction.reply({
content: `Cleared warning ID ${warnId} for <@${userOption.id}>.`,
ephemeral: true,
});
await interaction.editReply(`Cleared warning ID ${warnId} for <@${userOption.id}>.`);
}
}
} catch (error) {
logger.error(error);
await interaction.reply({ content: 'An error occurred while clearing the warnings.', ephemeral: true });
await interaction.editReply('An error occurred while clearing the warnings.');
}
},
};
Expand Down
26 changes: 7 additions & 19 deletions src/commands/moderation/editwarning.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SlashCommandBuilder, PermissionFlagsBits, CommandInteraction } from 'discord.js';
import { SlashCommandBuilder, PermissionFlagsBits, ChatInputCommandInteraction } from 'discord.js';
import { PrismaClient, Prisma } from '@prisma/client';
import { Command } from '../../interfaces/command';
import logger from '../../utils/logger';
Expand All @@ -9,39 +9,27 @@ const EditWarning: Command = {
data: new SlashCommandBuilder()
.setName('editwarning')
.setDescription('Edit the reason for a given warning')
.setDefaultMemberPermissions(PermissionFlagsBits.KickMembers)
.addIntegerOption((option) =>
option.setName('id').setDescription('The ID of the warning to edit').setRequired(true)
)
.addStringOption((option) =>
option.setName('newmessage').setDescription('The new warning message').setRequired(true)
),

async run(interaction: CommandInteraction) {
async run(interaction: ChatInputCommandInteraction) {
if (!interaction.guild) {
await interaction.reply({ content: 'This command can only be used in a guild.', ephemeral: true });
return;
}

if (!interaction.memberPermissions?.has(PermissionFlagsBits.KickMembers)) {
await interaction.reply({ content: 'Insufficient permissions.', ephemeral: true });
return;
}

const warningIdOption = interaction.options.get('id');
const newMessageOption = interaction.options.get('newmessage');

const warningId = warningIdOption ? parseInt(warningIdOption.value as string) : null;
const newMessage = newMessageOption ? (newMessageOption.value as string) : null;

if (warningId === null || newMessage === null) {
await interaction.reply({ content: 'Invalid command usage.', ephemeral: true });
return;
}
const warningIdOption = interaction.options.getInteger('id', true);
const newMessageOption = interaction.options.getString('newmessage', true);

try {
const updatedWarning = await prisma.warn.update({
where: { id: warningId },
data: { reason: newMessage },
where: { id: warningIdOption },
data: { reason: newMessageOption },
});

await interaction.reply({ content: `Warning ID ${updatedWarning.id} has been updated.`, ephemeral: true });
Expand Down
6 changes: 1 addition & 5 deletions src/commands/moderation/kick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const Kick: Command = {
data: new SlashCommandBuilder()
.setName('kick')
.setDescription('Kick a user from the server')
.setDefaultMemberPermissions(PermissionFlagsBits.KickMembers)
.addUserOption((option) => option.setName('user').setDescription('User to kick').setRequired(true))
.addStringOption((option) => option.setName('reason').setDescription('Reason for kicking')),

Expand All @@ -15,11 +16,6 @@ const Kick: Command = {
return;
}

if (!interaction.memberPermissions?.has(PermissionFlagsBits.KickMembers)) {
await interaction.reply({ content: 'You do not have permission to kick members.', ephemeral: true });
return;
}

const memberOption = interaction.options.getMember('user');
const member = memberOption as GuildMember | null;

Expand Down
27 changes: 10 additions & 17 deletions src/commands/moderation/purge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,16 @@ const Purge: Command = {
return;
}

interaction.deferReply({ ephemeral: true });

if (subcommand === 'any') {
try {
const messages = await interaction.channel.messages.fetch({ limit: count ?? undefined });
await interaction.channel.bulkDelete(messages, true);
await interaction.reply({ content: `Successfully deleted ${messages.size} messages.`, ephemeral: true });
await interaction.editReply(`Successfully deleted ${messages.size} messages.`);
} catch (error) {
logger.error(error);
await interaction.reply({ content: 'An error occurred while deleting messages.', ephemeral: true });
await interaction.editReply('An error occurred while deleting messages.');
}
} else if (subcommand === 'user') {
const user = interaction.options.getUser('user', true);
Expand All @@ -64,16 +66,10 @@ const Purge: Command = {
const messagesToDelete = userMessages.first(count ?? 0);
const deletedMessages = await interaction.channel.bulkDelete(messagesToDelete, true);

await interaction.reply({
content: `Successfully deleted ${deletedMessages.size} messages from ${user.tag}.`,
ephemeral: true,
});
await interaction.editReply(`Successfully deleted ${deletedMessages.size} messages from ${user.tag}.`);
} catch (error) {
logger.error(error);
await interaction.reply({
content: 'An error occurred while deleting messages.',
ephemeral: true,
});
await interaction.editReply('An error occurred while deleting messages.');
}
}

Expand All @@ -82,7 +78,7 @@ const Purge: Command = {
const countOption = interaction.options.getInteger('count');

if (!messageIdOption) {
await interaction.reply({ content: 'Invalid message ID.', ephemeral: true });
await interaction.editReply('Invalid message ID.');
return;
}

Expand All @@ -95,7 +91,7 @@ const Purge: Command = {
const startIndex = messagesArray.findIndex((m) => m.id === messageId);

if (startIndex === -1) {
await interaction.reply({ content: 'Message ID not found in the last 100 messages.', ephemeral: true });
await interaction.editReply('Message ID not found in the last 100 messages.');
return;
}

Expand All @@ -104,13 +100,10 @@ const Purge: Command = {
messagesAfterSpecified.length > count ? messagesAfterSpecified.slice(0, count) : messagesAfterSpecified;

await interaction.channel.bulkDelete(messagesToDelete, true);
await interaction.reply({
content: `Successfully deleted ${messagesToDelete.length} messages after the specified message.`,
ephemeral: true,
});
await interaction.editReply(`Successfully deleted ${messagesToDelete.length} messages after the specified message.`);
} catch (error) {
logger.error(error);
await interaction.reply({ content: 'An error occurred while deleting messages.', ephemeral: true });
await interaction.editReply('An error occurred while deleting messages.');
}
}
},
Expand Down
12 changes: 5 additions & 7 deletions src/commands/moderation/unban.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const Unban: Command = {
data: new SlashCommandBuilder()
.setName('unban')
.setDescription('Unban a user')
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
.addUserOption((option) => option.setName('user').setDescription('The user to unban').setRequired(true))
.addStringOption((option) =>
option.setName('reason').setDescription('The reason for the unban').setRequired(false)
Expand All @@ -20,10 +21,7 @@ const Unban: Command = {
return;
}

if (!interaction.memberPermissions?.has(PermissionFlagsBits.BanMembers)) {
await interaction.reply({ content: 'Insufficient permissions.', ephemeral: true });
return;
}
await interaction.deferReply({ ephemeral: true });

const userOption = interaction.options.get('user');
const reasonOption = interaction.options.get('reason');
Expand All @@ -32,7 +30,7 @@ const Unban: Command = {
const reason = (reasonOption?.value as string) || 'No reason provided';

if (!user) {
await interaction.reply({ content: 'User not found!', ephemeral: true });
await interaction.editReply('User not found!');
return;
}

Expand All @@ -52,10 +50,10 @@ const Unban: Command = {
}

await interaction.guild.members.unban(user, reason);
await interaction.reply({ content: `Unbanned <@${user.id}>. Reason: ${reason}`, ephemeral: true });
await interaction.editReply(`Unbanned <@${user.id}>. Reason: ${reason}`);
} catch (error) {
logger.error(error);
await interaction.reply({ content: 'An error occurred while processing the unban.', ephemeral: true });
await interaction.editReply('An error occurred while processing the unban.');
}
},
};
Expand Down
Loading

0 comments on commit f5caa9f

Please sign in to comment.