(Feat): Added a minimal pikanetwork client
This commit is contained in:
261
src/commands/utility/role.ts
Normal file
261
src/commands/utility/role.ts
Normal file
@@ -0,0 +1,261 @@
|
||||
/**
|
||||
* Role Command
|
||||
* Manage user roles (for officers)
|
||||
*/
|
||||
|
||||
import {
|
||||
SlashCommandBuilder,
|
||||
EmbedBuilder,
|
||||
type ChatInputCommandInteraction,
|
||||
} from 'discord.js';
|
||||
import type { Command } from '../../types/index.ts';
|
||||
import { PermissionLevel } from '../../types/index.ts';
|
||||
import type { EllyClient } from '../../client/EllyClient.ts';
|
||||
|
||||
export const roleCommand: Command = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('role')
|
||||
.setDescription('Manage user roles')
|
||||
.addSubcommand((sub) =>
|
||||
sub
|
||||
.setName('add')
|
||||
.setDescription('Add a role to a user')
|
||||
.addUserOption((opt) =>
|
||||
opt.setName('user').setDescription('User to add role to').setRequired(true)
|
||||
)
|
||||
.addRoleOption((opt) =>
|
||||
opt.setName('role').setDescription('Role to add').setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand((sub) =>
|
||||
sub
|
||||
.setName('remove')
|
||||
.setDescription('Remove a role from a user')
|
||||
.addUserOption((opt) =>
|
||||
opt.setName('user').setDescription('User to remove role from').setRequired(true)
|
||||
)
|
||||
.addRoleOption((opt) =>
|
||||
opt.setName('role').setDescription('Role to remove').setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand((sub) =>
|
||||
sub
|
||||
.setName('list')
|
||||
.setDescription('List manageable roles')
|
||||
),
|
||||
|
||||
permission: PermissionLevel.Officer,
|
||||
cooldown: 3,
|
||||
|
||||
async execute(interaction: ChatInputCommandInteraction): Promise<void> {
|
||||
const client = interaction.client as EllyClient;
|
||||
const subcommand = interaction.options.getSubcommand();
|
||||
|
||||
switch (subcommand) {
|
||||
case 'add':
|
||||
await handleAdd(interaction, client);
|
||||
break;
|
||||
case 'remove':
|
||||
await handleRemove(interaction, client);
|
||||
break;
|
||||
case 'list':
|
||||
await handleList(interaction, client);
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle adding a role
|
||||
*/
|
||||
async function handleAdd(
|
||||
interaction: ChatInputCommandInteraction,
|
||||
client: EllyClient
|
||||
): Promise<void> {
|
||||
const targetUser = interaction.options.getUser('user', true);
|
||||
const role = interaction.options.getRole('role', true);
|
||||
|
||||
// Check if role is manageable
|
||||
const manageableIds = client.config.roles.manageable?.ids ?? [];
|
||||
if (!manageableIds.includes(role.id)) {
|
||||
await interaction.reply({
|
||||
content: `❌ The role **${role.name}** is not in the list of manageable roles.`,
|
||||
ephemeral: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const member = interaction.guild?.members.cache.get(targetUser.id);
|
||||
if (!member) {
|
||||
await interaction.reply({
|
||||
content: '❌ User not found in this server.',
|
||||
ephemeral: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if user already has the role
|
||||
if (member.roles.cache.has(role.id)) {
|
||||
await interaction.reply({
|
||||
content: `❌ ${targetUser.tag} already has the **${role.name}** role.`,
|
||||
ephemeral: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await member.roles.add(role.id);
|
||||
|
||||
await interaction.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor(client.config.colors.success)
|
||||
.setTitle('✅ Role Added')
|
||||
.setDescription(`Added **${role.name}** to ${targetUser.tag}`)
|
||||
.setFooter({ text: `By ${interaction.user.tag}` })
|
||||
.setTimestamp(),
|
||||
],
|
||||
});
|
||||
|
||||
// Log to development channel
|
||||
await logRoleChange(client, interaction, targetUser.tag, role.name, 'added');
|
||||
} catch (error) {
|
||||
await interaction.reply({
|
||||
content: `❌ Failed to add role. Make sure I have the required permissions.`,
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle removing a role
|
||||
*/
|
||||
async function handleRemove(
|
||||
interaction: ChatInputCommandInteraction,
|
||||
client: EllyClient
|
||||
): Promise<void> {
|
||||
const targetUser = interaction.options.getUser('user', true);
|
||||
const role = interaction.options.getRole('role', true);
|
||||
|
||||
// Check if role is manageable
|
||||
const manageableIds = client.config.roles.manageable?.ids ?? [];
|
||||
if (!manageableIds.includes(role.id)) {
|
||||
await interaction.reply({
|
||||
content: `❌ The role **${role.name}** is not in the list of manageable roles.`,
|
||||
ephemeral: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const member = interaction.guild?.members.cache.get(targetUser.id);
|
||||
if (!member) {
|
||||
await interaction.reply({
|
||||
content: '❌ User not found in this server.',
|
||||
ephemeral: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if user has the role
|
||||
if (!member.roles.cache.has(role.id)) {
|
||||
await interaction.reply({
|
||||
content: `❌ ${targetUser.tag} doesn't have the **${role.name}** role.`,
|
||||
ephemeral: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await member.roles.remove(role.id);
|
||||
|
||||
await interaction.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor(client.config.colors.warning)
|
||||
.setTitle('✅ Role Removed')
|
||||
.setDescription(`Removed **${role.name}** from ${targetUser.tag}`)
|
||||
.setFooter({ text: `By ${interaction.user.tag}` })
|
||||
.setTimestamp(),
|
||||
],
|
||||
});
|
||||
|
||||
// Log to development channel
|
||||
await logRoleChange(client, interaction, targetUser.tag, role.name, 'removed');
|
||||
} catch (error) {
|
||||
await interaction.reply({
|
||||
content: `❌ Failed to remove role. Make sure I have the required permissions.`,
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle listing manageable roles
|
||||
*/
|
||||
async function handleList(
|
||||
interaction: ChatInputCommandInteraction,
|
||||
client: EllyClient
|
||||
): Promise<void> {
|
||||
const manageableIds = client.config.roles.manageable?.ids ?? [];
|
||||
|
||||
if (manageableIds.length === 0) {
|
||||
await interaction.reply({
|
||||
content: '📭 No manageable roles configured.',
|
||||
ephemeral: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const roles = manageableIds
|
||||
.map((id) => interaction.guild?.roles.cache.get(id))
|
||||
.filter((r) => r !== undefined)
|
||||
.map((r) => `• <@&${r!.id}> (\`${r!.id}\`)`);
|
||||
|
||||
await interaction.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor(client.config.colors.primary)
|
||||
.setTitle('📋 Manageable Roles')
|
||||
.setDescription(roles.join('\n') || 'No roles found')
|
||||
.setFooter({ text: `${roles.length} roles can be managed` })
|
||||
.setTimestamp(),
|
||||
],
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Log role change to development channel
|
||||
*/
|
||||
async function logRoleChange(
|
||||
client: EllyClient,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
targetTag: string,
|
||||
roleName: string,
|
||||
action: 'added' | 'removed'
|
||||
): Promise<void> {
|
||||
try {
|
||||
const logChannelName = client.config.channels.developmentLogs;
|
||||
const logChannel = interaction.guild?.channels.cache.find(
|
||||
(c) => c.name === logChannelName && c.isTextBased()
|
||||
);
|
||||
|
||||
if (logChannel && logChannel.isTextBased()) {
|
||||
await logChannel.send({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor(action === 'added' ? 0x57f287 : 0xfee75c)
|
||||
.setTitle(`📝 Role ${action === 'added' ? 'Added' : 'Removed'}`)
|
||||
.addFields(
|
||||
{ name: 'User', value: targetTag, inline: true },
|
||||
{ name: 'Role', value: roleName, inline: true },
|
||||
{ name: 'By', value: interaction.user.tag, inline: true }
|
||||
)
|
||||
.setTimestamp(),
|
||||
],
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// Ignore logging errors
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user