Introduce several new slash commands including ban, kick, timeout, and userinfo. Enhance existing commands like config and rank with new features and configurations. Add new listeners for welcome and goodbye messages. Implement XP tracking for user leveling and integrate it with role rewards. Update documentation to reflect these changes. Replit-Commit-Author: Agent Replit-Commit-Session-Id: aed2e46d-25bb-4b73-81a1-bb9e8437c261 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: 1be8d824-5029-4875-bed8-0bd1d810892d Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3bdfff67-975a-46ad-9845-fbb6b4a4c4b5/aed2e46d-25bb-4b73-81a1-bb9e8437c261/SQxsvtx Replit-Helium-Checkpoint-Created: true
93 lines
3 KiB
JavaScript
93 lines
3 KiB
JavaScript
const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } = require('discord.js');
|
|
|
|
module.exports = {
|
|
data: new SlashCommandBuilder()
|
|
.setName('ban')
|
|
.setDescription('Ban a user from the server')
|
|
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
|
.addUserOption(option =>
|
|
option.setName('user')
|
|
.setDescription('User to ban')
|
|
.setRequired(true)
|
|
)
|
|
.addStringOption(option =>
|
|
option.setName('reason')
|
|
.setDescription('Reason for ban')
|
|
.setRequired(false)
|
|
.setMaxLength(500)
|
|
)
|
|
.addIntegerOption(option =>
|
|
option.setName('delete_days')
|
|
.setDescription('Days of messages to delete (0-7)')
|
|
.setRequired(false)
|
|
.setMinValue(0)
|
|
.setMaxValue(7)
|
|
),
|
|
|
|
async execute(interaction, supabase, client) {
|
|
const target = interaction.options.getUser('user');
|
|
const reason = interaction.options.getString('reason') || 'No reason provided';
|
|
const deleteDays = interaction.options.getInteger('delete_days') || 0;
|
|
const moderator = interaction.user;
|
|
|
|
if (target.id === interaction.user.id) {
|
|
return interaction.reply({ content: 'You cannot ban yourself.', ephemeral: true });
|
|
}
|
|
|
|
const member = await interaction.guild.members.fetch(target.id).catch(() => null);
|
|
|
|
if (member && !member.bannable) {
|
|
return interaction.reply({ content: 'I cannot ban this user. They may have higher permissions.', ephemeral: true });
|
|
}
|
|
|
|
try {
|
|
await target.send({
|
|
embeds: [
|
|
new EmbedBuilder()
|
|
.setColor(0xff0000)
|
|
.setTitle(`Banned from ${interaction.guild.name}`)
|
|
.addFields({ name: 'Reason', value: reason })
|
|
.setTimestamp()
|
|
]
|
|
}).catch(() => {});
|
|
|
|
await interaction.guild.members.ban(target, {
|
|
reason: `${reason} | Banned by ${moderator.tag}`,
|
|
deleteMessageSeconds: deleteDays * 24 * 60 * 60
|
|
});
|
|
|
|
if (supabase) {
|
|
try {
|
|
await supabase.from('mod_actions').insert({
|
|
guild_id: interaction.guildId,
|
|
action: 'ban',
|
|
user_id: target.id,
|
|
user_tag: target.tag,
|
|
moderator_id: moderator.id,
|
|
moderator_tag: moderator.tag,
|
|
reason: reason,
|
|
});
|
|
} catch (e) {
|
|
console.warn('Failed to log ban:', e.message);
|
|
}
|
|
}
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setColor(0xff0000)
|
|
.setTitle('User Banned')
|
|
.setThumbnail(target.displayAvatarURL())
|
|
.addFields(
|
|
{ name: 'User', value: `${target.tag} (${target.id})`, inline: true },
|
|
{ name: 'Moderator', value: moderator.tag, inline: true },
|
|
{ name: 'Reason', value: reason }
|
|
)
|
|
.setTimestamp();
|
|
|
|
await interaction.reply({ embeds: [embed] });
|
|
|
|
} catch (error) {
|
|
console.error('Ban error:', error);
|
|
await interaction.reply({ content: 'Failed to ban user.', ephemeral: true });
|
|
}
|
|
},
|
|
};
|