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
184 lines
6.3 KiB
JavaScript
184 lines
6.3 KiB
JavaScript
const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits, ChannelType } = require('discord.js');
|
|
|
|
module.exports = {
|
|
data: new SlashCommandBuilder()
|
|
.setName('config')
|
|
.setDescription('Configure server settings')
|
|
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
|
|
.addSubcommand(sub =>
|
|
sub.setName('view')
|
|
.setDescription('View current server configuration')
|
|
)
|
|
.addSubcommand(sub =>
|
|
sub.setName('welcome')
|
|
.setDescription('Set the welcome channel')
|
|
.addChannelOption(opt =>
|
|
opt.setName('channel')
|
|
.setDescription('Channel for welcome messages')
|
|
.addChannelTypes(ChannelType.GuildText)
|
|
.setRequired(true)
|
|
)
|
|
)
|
|
.addSubcommand(sub =>
|
|
sub.setName('goodbye')
|
|
.setDescription('Set the goodbye channel')
|
|
.addChannelOption(opt =>
|
|
opt.setName('channel')
|
|
.setDescription('Channel for goodbye messages')
|
|
.addChannelTypes(ChannelType.GuildText)
|
|
.setRequired(true)
|
|
)
|
|
)
|
|
.addSubcommand(sub =>
|
|
sub.setName('modlog')
|
|
.setDescription('Set the moderation log channel')
|
|
.addChannelOption(opt =>
|
|
opt.setName('channel')
|
|
.setDescription('Channel for mod logs')
|
|
.addChannelTypes(ChannelType.GuildText)
|
|
.setRequired(true)
|
|
)
|
|
)
|
|
.addSubcommand(sub =>
|
|
sub.setName('levelup')
|
|
.setDescription('Set the level-up announcement channel')
|
|
.addChannelOption(opt =>
|
|
opt.setName('channel')
|
|
.setDescription('Channel for level-up messages')
|
|
.addChannelTypes(ChannelType.GuildText)
|
|
.setRequired(true)
|
|
)
|
|
)
|
|
.addSubcommand(sub =>
|
|
sub.setName('autorole')
|
|
.setDescription('Set auto-role for new members')
|
|
.addRoleOption(opt =>
|
|
opt.setName('role')
|
|
.setDescription('Role to assign on join')
|
|
.setRequired(true)
|
|
)
|
|
)
|
|
.addSubcommand(sub =>
|
|
sub.setName('levelrole')
|
|
.setDescription('Add a role reward for reaching a level')
|
|
.addRoleOption(opt =>
|
|
opt.setName('role')
|
|
.setDescription('Role to give')
|
|
.setRequired(true)
|
|
)
|
|
.addIntegerOption(opt =>
|
|
opt.setName('level')
|
|
.setDescription('Level required')
|
|
.setRequired(true)
|
|
.setMinValue(1)
|
|
.setMaxValue(100)
|
|
)
|
|
),
|
|
|
|
async execute(interaction, supabase, client) {
|
|
if (!supabase) {
|
|
return interaction.reply({ content: 'Database not configured.', ephemeral: true });
|
|
}
|
|
|
|
const subcommand = interaction.options.getSubcommand();
|
|
await interaction.deferReply({ ephemeral: true });
|
|
|
|
try {
|
|
if (subcommand === 'view') {
|
|
const { data: config } = await supabase
|
|
.from('server_config')
|
|
.select('*')
|
|
.eq('guild_id', interaction.guildId)
|
|
.single();
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setColor(0x7c3aed)
|
|
.setTitle('Server Configuration')
|
|
.addFields(
|
|
{ name: 'Welcome Channel', value: config?.welcome_channel ? `<#${config.welcome_channel}>` : 'Not set', inline: true },
|
|
{ name: 'Goodbye Channel', value: config?.goodbye_channel ? `<#${config.goodbye_channel}>` : 'Not set', inline: true },
|
|
{ name: 'Mod Log Channel', value: config?.modlog_channel ? `<#${config.modlog_channel}>` : 'Not set', inline: true },
|
|
{ name: 'Level-Up Channel', value: config?.level_up_channel ? `<#${config.level_up_channel}>` : 'Not set', inline: true },
|
|
{ name: 'Auto Role', value: config?.auto_role ? `<@&${config.auto_role}>` : 'Not set', inline: true }
|
|
)
|
|
.setTimestamp();
|
|
|
|
const { data: levelRoles } = await supabase
|
|
.from('level_roles')
|
|
.select('role_id, level_required')
|
|
.eq('guild_id', interaction.guildId)
|
|
.order('level_required', { ascending: true });
|
|
|
|
if (levelRoles && levelRoles.length > 0) {
|
|
const roleText = levelRoles.map(lr => `Level ${lr.level_required}: <@&${lr.role_id}>`).join('\n');
|
|
embed.addFields({ name: 'Level Roles', value: roleText });
|
|
}
|
|
|
|
return interaction.editReply({ embeds: [embed] });
|
|
}
|
|
|
|
const updateField = {
|
|
welcome: 'welcome_channel',
|
|
goodbye: 'goodbye_channel',
|
|
modlog: 'modlog_channel',
|
|
levelup: 'level_up_channel',
|
|
autorole: 'auto_role',
|
|
};
|
|
|
|
if (subcommand === 'levelrole') {
|
|
const role = interaction.options.getRole('role');
|
|
const level = interaction.options.getInteger('level');
|
|
|
|
await supabase.from('level_roles').upsert({
|
|
guild_id: interaction.guildId,
|
|
role_id: role.id,
|
|
level_required: level,
|
|
}, { onConflict: 'guild_id,role_id' });
|
|
|
|
if (!client.serverConfigs) client.serverConfigs = new Map();
|
|
|
|
return interaction.editReply({
|
|
embeds: [
|
|
new EmbedBuilder()
|
|
.setColor(0x00ff00)
|
|
.setDescription(`${role} will now be given at level ${level}!`)
|
|
]
|
|
});
|
|
}
|
|
|
|
const fieldName = updateField[subcommand];
|
|
let value;
|
|
|
|
if (subcommand === 'autorole') {
|
|
value = interaction.options.getRole('role').id;
|
|
} else {
|
|
value = interaction.options.getChannel('channel').id;
|
|
}
|
|
|
|
await supabase.from('server_config').upsert({
|
|
guild_id: interaction.guildId,
|
|
[fieldName]: value,
|
|
updated_at: new Date().toISOString(),
|
|
}, { onConflict: 'guild_id' });
|
|
|
|
if (!client.serverConfigs) client.serverConfigs = new Map();
|
|
const current = client.serverConfigs.get(interaction.guildId) || {};
|
|
current[fieldName] = value;
|
|
client.serverConfigs.set(interaction.guildId, current);
|
|
|
|
const displayValue = subcommand === 'autorole' ? `<@&${value}>` : `<#${value}>`;
|
|
|
|
await interaction.editReply({
|
|
embeds: [
|
|
new EmbedBuilder()
|
|
.setColor(0x00ff00)
|
|
.setDescription(`${subcommand.charAt(0).toUpperCase() + subcommand.slice(1)} set to ${displayValue}!`)
|
|
]
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Config error:', error);
|
|
await interaction.editReply({ content: 'Failed to update configuration.' });
|
|
}
|
|
},
|
|
};
|