wsb-bot / src /commands /coOwnerRole.js
APRK01
fix: update co-owner role - add SendMessages, remove ManageRoles, block tickets
1745ca3
const { PermissionFlagsBits } = require('discord.js');
const { createEmbed } = require('../utils/embeds');
const { Colors } = require('../config');
/**
* Temporary command: creates a Co-Owner role with limited management permissions.
* - Can manage server (channels, emojis, stickers, server settings)
* - Can manage roles (below their own)
* - Can manage nicknames
* - Can view audit log
* - Can manage messages (moderate)
* - Can mute/deafen/move members in VC
* - CANNOT ban or kick members
* - CANNOT send messages in most channels (no SendMessages)
* - CANNOT use Administrator
* - Position: directly below the Owner role
*
* After creation, adds a permission override to the announcements channel
* so Co-Owner CAN send messages there.
*
* Usage: coownerrole
*/
module.exports = {
async execute(client, message) {
const guild = client.guilds.cache.first();
if (!guild) return message.reply({ content: '❌ No guild found.' });
const statusMsg = await message.reply({
embeds: [createEmbed({
title: 'πŸ”§ Creating Co-Owner Role',
description: 'Setting up limited management role...',
color: Colors.INFO
})]
});
try {
// Check if role already exists
const existing = guild.roles.cache.find(r => r.name === 'πŸ‘‘ Co-Owner');
if (existing) {
return statusMsg.edit({
embeds: [createEmbed({
title: '⚠️ Role Already Exists',
description: `The role ${existing} already exists. Delete it manually first if you want to recreate it.`,
color: Colors.WARNING
})]
});
}
// Find the Owner role to position Co-Owner below it
const ownerRole = guild.roles.cache.find(r => r.name === '@@ Owner');
const position = ownerRole ? ownerRole.position - 1 : guild.roles.cache.size - 2;
// Create the Co-Owner role with limited permissions
const coOwnerRole = await guild.roles.create({
name: 'πŸ‘‘ Co-Owner',
color: '#e74c3c',
hoist: true,
mentionable: false,
permissions: [
// Server management
PermissionFlagsBits.ManageGuild, // Server settings, emojis, stickers
PermissionFlagsBits.ManageChannels, // Create/edit/delete channels
PermissionFlagsBits.ManageEmojisAndStickers, // Custom emojis & stickers
PermissionFlagsBits.ManageWebhooks, // Webhooks
// Moderation (no ban/kick)
PermissionFlagsBits.ManageMessages, // Delete/pin messages
PermissionFlagsBits.ManageNicknames, // Change other's nicknames
PermissionFlagsBits.ManageEvents, // Server events
// Voice
PermissionFlagsBits.MuteMembers, // Mute in VC
PermissionFlagsBits.DeafenMembers, // Deafen in VC
PermissionFlagsBits.MoveMembers, // Move between VCs
// Chat & view
PermissionFlagsBits.ViewChannel, // See channels
PermissionFlagsBits.SendMessages, // Send messages everywhere
PermissionFlagsBits.EmbedLinks, // Embed links
PermissionFlagsBits.AttachFiles, // Attach files
PermissionFlagsBits.AddReactions, // Add reactions
PermissionFlagsBits.UseExternalEmojis, // External emojis
PermissionFlagsBits.ViewAuditLog, // Audit log access
PermissionFlagsBits.ReadMessageHistory, // Read history
// Voice join
PermissionFlagsBits.Connect, // Join VCs
PermissionFlagsBits.Speak, // Speak in VCs
// NOTE: No ManageRoles, no BanMembers, no KickMembers, no Administrator
],
reason: 'Co-Owner role created via coownerrole command'
});
// Position the role below Owner
await coOwnerRole.setPosition(position).catch(() => { });
// Find announcements channel and add SendMessages override
const announcementChannel = guild.channels.cache.find(
c => c.name.toLowerCase().includes('announcement') || c.name.toLowerCase().includes('πŸ“’')
);
let announcementNote = '';
// Block Co-Owner from ALL ticket channels/categories
const ticketChannels = guild.channels.cache.filter(
c => c.name.toLowerCase().includes('ticket') ||
c.name.toLowerCase().includes('🎫')
);
let ticketCount = 0;
for (const [, ch] of ticketChannels) {
await ch.permissionOverwrites.edit(coOwnerRole, {
ViewChannel: false,
SendMessages: false,
}).catch(() => { });
ticketCount++;
}
if (ticketCount > 0) {
announcementNote += `\nπŸ”’ **Blocked from ${ticketCount} ticket channel(s)**`;
}
await statusMsg.edit({
embeds: [createEmbed({
title: 'βœ… Co-Owner Role Created!',
description: [
`**Role:** ${coOwnerRole}`,
`**Position:** Below Owner`,
`**Color:** Red (#e74c3c)`,
'',
'**βœ… CAN:**',
'> Send messages in all channels',
'> Manage server, channels, emojis',
'> Manage messages, nicknames, events',
'> Mute/deafen/move in voice',
'> View audit log',
'',
'**❌ CANNOT:**',
'> Assign/manage roles',
'> Ban or kick members',
'> Access ticket channels',
'> Use Administrator',
'> Override Owner permissions',
'',
announcementNote,
'',
'> Assign this role to your co-owner manually.',
].join('\n'),
color: Colors.SUCCESS
})]
});
} catch (err) {
console.error('[CoOwnerRole Error]', err);
await statusMsg.edit({
embeds: [createEmbed({
title: '❌ Failed',
description: `Error: ${err.message}`,
color: Colors.ACCENT
})]
});
}
}
};