Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 60 additions & 18 deletions src/commands/Moderation/ban.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { SlashCommandBuilder, PermissionFlagsBits, PermissionsBitField, ChannelType } from 'discord.js';
import { createEmbed, errorEmbed, successEmbed, infoEmbed, warningEmbed } from '../../utils/embeds.js';
import { SlashCommandBuilder, PermissionFlagsBits } from 'discord.js';
import { errorEmbed, successEmbed } from '../../utils/embeds.js';
import { logModerationAction } from '../../utils/moderation.js';
import { logger } from '../../utils/logger.js';
import { InteractionHelper } from '../../utils/interactionHelper.js';
import { ModerationService } from '../../services/moderationService.js';
import { handleInteractionError } from '../../utils/errorHandler.js';

export default {
data: new SlashCommandBuilder()
.setName("ban")
Expand All @@ -18,43 +18,85 @@ export default {
.addStringOption((option) =>
option.setName("reason").setDescription("Reason for the ban"),
)
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers),
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers),
category: "moderation",

async execute(interaction, config, client) {
const deferSuccess = await InteractionHelper.safeDefer(interaction);
if (!deferSuccess) {
logger.warn(`Ban interaction defer failed`, {
userId: interaction.user.id,
guildId: interaction.guildId,
commandName: 'ban'
});
return;
}

try {
const user = interaction.options.getUser("target");
if (!interaction.member.permissions.has(PermissionFlagsBits.BanMembers)) {
throw new Error("You do not have permission to ban members.");
}

const targetUser = interaction.options.getUser("target");
const reason = interaction.options.getString("reason") || "No reason provided";

if (user.id === interaction.user.id) {
if (!targetUser) {
throw new Error("Could not find the target user.");
}

if (targetUser.id === interaction.user.id) {
throw new Error("You cannot ban yourself.");
}
if (user.id === client.user.id) {

if (targetUser.id === client.user.id) {
throw new Error("You cannot ban the bot.");
}


const result = await ModerationService.banUser({
// Ban the user
await interaction.guild.bans.create(targetUser.id, { reason });

const caseId = await logModerationAction({
client,
guild: interaction.guild,
user,
moderator: interaction.member,
reason
event: {
action: "Member Banned",
target: `${targetUser.tag} (${targetUser.id})`,
executor: `${interaction.user.tag} (${interaction.user.id})`,
reason: reason,
metadata: {
userId: targetUser.id,
moderatorId: interaction.user.id,
}
}
});

await InteractionHelper.universalReply(interaction, {
await InteractionHelper.safeEditReply(interaction, {
embeds: [
successEmbed(
`🚫 **Banned** ${user.tag}`,
`**Reason:** ${reason}\n**Case ID:** #${result.caseId}`,
`🚫 **Banned** ${targetUser.tag}`,
`**Reason:** ${reason}\n**Case ID:** #${caseId}`,
),
],
});

logger.info('User banned', {
guildId: interaction.guildId,
userId: targetUser.id,
moderatorId: interaction.user.id,
reason: reason
});

} catch (error) {
logger.error('Ban command error:', error);
await handleInteractionError(interaction, error, { subtype: 'ban_failed' });
await InteractionHelper.safeEditReply(interaction, {
embeds: [
errorEmbed(
"Ban Failed",
error.message || "An unexpected error occurred during the ban action. Please check my role permissions."
),
],
});
}
},
};



213 changes: 107 additions & 106 deletions src/commands/Moderation/kick.js
Original file line number Diff line number Diff line change
@@ -1,125 +1,126 @@
import { SlashCommandBuilder, PermissionFlagsBits, PermissionsBitField, ChannelType } from 'discord.js';
import { createEmbed, errorEmbed, successEmbed, infoEmbed, warningEmbed } from '../../utils/embeds.js';
import { SlashCommandBuilder, PermissionFlagsBits } from 'discord.js';
import { errorEmbed, successEmbed } from '../../utils/embeds.js';
import { logModerationAction } from '../../utils/moderation.js';
import { logger } from '../../utils/logger.js';
import { InteractionHelper } from '../../utils/interactionHelper.js';
import { TitanBotError, ErrorTypes } from '../../utils/errorHandler.js';
import { InteractionHelper } from '../../utils/interactionHelper.js';

export default {
data: new SlashCommandBuilder()
.setName("kick")
.setDescription("Kick a user from the server")
.addUserOption((option) =>
option
.setName("target")
.setDescription("The user to kick")
.setRequired(true),
)
.addStringOption((option) =>
option.setName("reason").setDescription("Reason for the kick"),
)
.setDefaultMemberPermissions(PermissionFlagsBits.KickMembers),
category: "moderation",
.setName("kick")
.setDescription("Kick a user from the server")
.addUserOption((option) =>
option
.setName("target")
.setDescription("The user to kick")
.setRequired(true),
)
.addStringOption((option) =>
option.setName("reason").setDescription("Reason for the kick"),
)
.setDefaultMemberPermissions(PermissionFlagsBits.KickMembers),
category: "moderation",

async execute(interaction, config, client) {
try {

if (!interaction.member.permissions.has(PermissionFlagsBits.KickMembers)) {
throw new TitanBotError(
"User lacks permission",
ErrorTypes.PERMISSION,
"You do not have permission to kick members."
);
}
async execute(interaction, config, client) {
const deferSuccess = await InteractionHelper.safeDefer(interaction);
if (!deferSuccess) {
logger.warn(`Kick interaction defer failed`, {
userId: interaction.user.id,
guildId: interaction.guildId,
commandName: 'kick'
});
return;
}

const targetUser = interaction.options.getUser("target");
const member = interaction.options.getMember("target");
const reason = interaction.options.getString("reason") || "No reason provided";
try {
if (!interaction.member.permissions.has(PermissionFlagsBits.KickMembers)) {
throw new TitanBotError(
"User lacks permission",
ErrorTypes.PERMISSION,
"You do not have permission to kick members."
);
}


if (targetUser.id === interaction.user.id) {
throw new TitanBotError(
"Cannot kick self",
ErrorTypes.VALIDATION,
"You cannot kick yourself."
);
}
const targetUser = interaction.options.getUser("target");
const member = interaction.options.getMember("target");
const reason = interaction.options.getString("reason") || "No reason provided";


if (targetUser.id === client.user.id) {
throw new TitanBotError(
"Cannot kick bot",
ErrorTypes.VALIDATION,
"You cannot kick the bot."
);
}
if (!targetUser) {
throw new TitanBotError(
"Target not found",
ErrorTypes.USER_INPUT,
"Could not find the target user."
);
}


if (!member) {
throw new TitanBotError(
"Target not found",
ErrorTypes.USER_INPUT,
"The target user is not currently in this server.",
{ subtype: 'user_not_found' }
);
}
if (targetUser.id === interaction.user.id) {
throw new TitanBotError(
"Cannot kick self",
ErrorTypes.VALIDATION,
"You cannot kick yourself."
);
}


if (interaction.member.roles.highest.position <= member.roles.highest.position) {
throw new TitanBotError(
"Cannot kick user",
ErrorTypes.PERMISSION,
"You cannot kick a user with an equal or higher role than you."
);
}
if (targetUser.id === client.user.id) {
throw new TitanBotError(
"Cannot kick bot",
ErrorTypes.VALIDATION,
"You cannot kick the bot."
);
}


if (!member.kickable) {
throw new TitanBotError(
"Bot cannot kick",
ErrorTypes.PERMISSION,
"I cannot kick this user. Please check my role position relative to the target user."
);
}
if (!member) {
throw new TitanBotError(
"Target not found",
ErrorTypes.USER_INPUT,
"The target user is not currently in this server."
);
}


await member.kick(reason);
if (!member.kickable) {
throw new TitanBotError(
"Cannot kick member",
ErrorTypes.PERMISSION,
"I cannot kick this user. They might have a higher role than me or you."
);
}


const caseId = await logModerationAction({
client,
guild: interaction.guild,
event: {
action: "Member Kicked",
target: `${targetUser.tag} (${targetUser.id})`,
executor: `${interaction.user.tag} (${interaction.user.id})`,
reason,
metadata: {
userId: targetUser.id,
moderatorId: interaction.user.id
}
}
});
await member.kick(reason);


await InteractionHelper.universalReply(interaction, {
embeds: [
successEmbed(
`👢 **Kicked** ${targetUser.tag}`,
`**Reason:** ${reason}\n**Case ID:** #${caseId}`,
),
],
});
} catch (error) {
logger.error('Kick command error:', error);
const errorEmbed_default = errorEmbed(
"An unexpected error occurred while trying to kick the user.",
error.message || "Could not kick the user"
);
await InteractionHelper.universalReply(interaction, { embeds: [errorEmbed_default] });
const caseId = await logModerationAction({
client,
guild: interaction.guild,
event: {
action: "Member Kicked",
target: `${targetUser.tag} (${targetUser.id})`,
executor: `${interaction.user.tag} (${interaction.user.id})`,
reason: reason,
metadata: {
userId: targetUser.id,
moderatorId: interaction.user.id,
}
}
});

await InteractionHelper.safeEditReply(interaction, {
embeds: [
successEmbed(
`👢 **Kicked** ${targetUser.tag}`,
`**Reason:** ${reason}\n**Case ID:** #${caseId}`,
),
],
});
} catch (error) {
logger.error('Kick command error:', error);
await InteractionHelper.safeEditReply(interaction, {
embeds: [
errorEmbed(
"Kick Failed",
error.userMessage || "An unexpected error occurred during the kick action. Please check my role permissions."
),
],
});
}
}
}
};



Loading