Moderation Update

This commit is contained in:
2025-10-09 06:13:48 -04:00
parent 2ae7202445
commit ff10bb3183
20 changed files with 2056 additions and 381 deletions

View File

@@ -0,0 +1,167 @@
const { SlashCommandBuilder, PermissionsBitField } = require('discord.js');
// Helper function to parse user from mention or ID
function parseUser(input, guild) {
// Check if it's a mention <@123456> or <@!123456>
const mentionMatch = input.match(/^<@!?(\d+)>$/);
if (mentionMatch) {
return guild.members.cache.get(mentionMatch[1])?.user;
}
// Check if it's a user ID
if (/^\d{15,20}$/.test(input)) {
return guild.members.cache.get(input)?.user;
}
// Try to find by username or global name
const member = guild.members.cache.find(m =>
(m.user.global_name && m.user.global_name.toLowerCase().includes(input.toLowerCase())) ||
m.user.username.toLowerCase().includes(input.toLowerCase()) ||
(m.user.global_name && m.user.global_name.toLowerCase() === input.toLowerCase()) ||
m.user.username.toLowerCase() === input.toLowerCase()
);
return member?.user;
}
// Helper function to log moderation actions
async function logModerationAction(guildId, action, targetUserId, targetUsername, moderatorUserId, moderatorUsername, reason, duration = null, endDate = null) {
try {
const logData = {
guildId,
action,
targetUserId,
targetUsername,
moderatorUserId,
moderatorUsername,
reason,
duration,
endDate
};
const response = await fetch(`${process.env.BACKEND_BASE || 'http://localhost:3001'}/internal/log-moderation`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(logData)
});
if (!response.ok) {
console.error('Failed to log moderation action:', response.statusText);
}
} catch (error) {
console.error('Error logging moderation action:', error);
}
}
module.exports = {
name: 'kick',
description: 'Kick a user from the server',
enabled: true,
builder: new SlashCommandBuilder()
.setName('kick')
.setDescription('Kick a user from the server')
.addStringOption(option =>
option.setName('user')
.setDescription('The user to kick (mention or user ID)')
.setRequired(true))
.addStringOption(option =>
option.setName('reason')
.setDescription('Reason for the kick (minimum 3 words)')
.setRequired(true)),
async execute(interaction) {
// Check if user has kick permissions
if (!interaction.member.permissions.has(PermissionsBitField.Flags.KickMembers)) {
return await interaction.reply({
content: 'You do not have permission to kick members.',
flags: 64
});
}
// Check if bot has kick permissions
if (!interaction.guild.members.me.permissions.has(PermissionsBitField.Flags.KickMembers)) {
return await interaction.reply({
content: 'I do not have permission to kick members.',
flags: 64
});
}
const userInput = interaction.options.getString('user');
const reason = interaction.options.getString('reason');
// Parse the user from the input
const user = parseUser(userInput, interaction.guild);
if (!user) {
return await interaction.reply({
content: 'Could not find that user. Please provide a valid user mention or user ID.',
flags: 64
});
}
// Validate reason has at least 3 words
const reasonWords = reason.trim().split(/\s+/);
if (reasonWords.length < 3) {
return await interaction.reply({
content: 'Reason must be at least 3 words long.',
flags: 64
});
}
// Cannot kick yourself
if (user.id === interaction.user.id) {
return await interaction.reply({
content: 'You cannot kick yourself.',
flags: 64
});
}
// Cannot kick the bot
if (user.id === interaction.guild.members.me.id) {
return await interaction.reply({
content: 'I cannot kick myself.',
flags: 64
});
}
// Check if user is in the server
const member = interaction.guild.members.cache.get(user.id);
if (!member) {
return await interaction.reply({
content: 'That user is not in this server.',
flags: 64
});
}
// Check role hierarchy
if (member.roles.highest.position >= interaction.member.roles.highest.position && interaction.user.id !== interaction.guild.ownerId) {
return await interaction.reply({
content: 'You cannot kick a member with a higher or equal role.',
flags: 64
});
}
if (member.roles.highest.position >= interaction.guild.members.me.roles.highest.position) {
return await interaction.reply({
content: 'I cannot kick a member with a higher or equal role.',
flags: 64
});
}
try {
await member.kick(reason);
await interaction.reply({
content: `Successfully kicked ${user.global_name || user.username} for: ${reason}`,
flags: 64
});
// Log the action
await logModerationAction(interaction.guildId, 'kick', user.id, user.global_name || user.username, interaction.user.id, interaction.user.global_name || interaction.user.username, reason);
} catch (error) {
console.error('Error kicking user:', error);
await interaction.reply({
content: 'Failed to kick the user. Please try again.',
flags: 64
});
}
}
};