wsb-bott / src /commands /createChannels.js
APRKDEV's picture
Upload 43 files
e5c9966 verified
const { ChannelType, PermissionFlagsBits } = require('discord.js');
const { Categories } = require('../config');
const { stmts } = require('../database');
const { successEmbed, infoEmbed } = require('../utils/embeds');
module.exports = {
name: 'create channels',
async execute(client, message) {
const guildId = process.env.GUILD_ID;
const guild = await client.guilds.fetch(guildId);
await message.reply({ embeds: [infoEmbed('Creating Channels', 'Setting up categories and channels...')] });
const results = [];
// Build a role map for permission overwrites
const roleMap = new Map();
roleMap.set('everyone', guild.roles.everyone);
guild.roles.cache.forEach(r => roleMap.set(r.name, r));
for (const catDef of Categories) {
// Check if category already exists
let category = guild.channels.cache.find(
c => c.type === ChannelType.GuildCategory && c.name === catDef.name
);
if (!category) {
// Build category-level permission overwrites
const catOverwrites = buildCategoryOverwrites(catDef, roleMap);
category = await guild.channels.create({
name: catDef.name,
type: ChannelType.GuildCategory,
permissionOverwrites: catOverwrites,
reason: 'WSB Setup',
});
results.push(`πŸ“ **${catDef.name}** β€” category created`);
} else {
results.push(`πŸ“ **${catDef.name}** β€” already exists`);
}
// Create child channels
for (const chDef of catDef.channels) {
const existing = guild.channels.cache.find(
c => c.name === chDef.name && c.parentId === category.id
);
if (existing) {
// Store channel ID in bot state for later reference
stmts.setState.run(`channel_${chDef.name}`, existing.id);
results.push(` β”” **${chDef.name}** β€” already exists`);
continue;
}
const channelType = chDef.type === 'voice'
? ChannelType.GuildVoice
: ChannelType.GuildText;
// Build channel-specific permission overwrites
const channelOverwrites = buildChannelOverwrites(catDef, chDef, roleMap);
const channel = await guild.channels.create({
name: chDef.name,
type: channelType,
parent: category.id,
permissionOverwrites: channelOverwrites,
reason: 'WSB Setup',
});
// Store in bot state
stmts.setState.run(`channel_${chDef.name}`, channel.id);
results.push(` β”” **${chDef.name}** β€” created`);
}
}
await message.reply({
embeds: [successEmbed('Channels Created', results.join('\n'))],
});
},
};
/**
* Build permission overwrites for a category.
*/
function buildCategoryOverwrites(catDef, roleMap) {
const overrideMap = catDef.permOverrides(roleMap);
const overwrites = [];
for (const [roleName, perms] of Object.entries(overrideMap)) {
const role = roleName === 'everyone' ? roleMap.get('everyone') : roleMap.get(roleName);
if (!role) continue;
const allow = [];
const deny = [];
if (perms.view === true) allow.push(PermissionFlagsBits.ViewChannel);
if (perms.view === false) deny.push(PermissionFlagsBits.ViewChannel);
if (perms.send === true) allow.push(PermissionFlagsBits.SendMessages);
if (perms.send === false) deny.push(PermissionFlagsBits.SendMessages);
overwrites.push({ id: role.id || role, allow, deny });
}
return overwrites;
}
/**
* Build channel-specific overwrites, handling readOnly, staffOnly, noEmbeds, and special flags.
*/
function buildChannelOverwrites(catDef, chDef, roleMap) {
const overrideMap = catDef.permOverrides(roleMap);
const overwrites = [];
for (const [roleName, perms] of Object.entries(overrideMap)) {
const role = roleName === 'everyone' ? roleMap.get('everyone') : roleMap.get(roleName);
if (!role) continue;
const allow = [];
const deny = [];
// Public channels: @everyone can view (overrides category deny)
if (chDef.public && roleName === 'everyone') {
allow.push(PermissionFlagsBits.ViewChannel);
allow.push(PermissionFlagsBits.ReadMessageHistory);
allow.push(PermissionFlagsBits.AddReactions);
} else {
if (perms.view === true) allow.push(PermissionFlagsBits.ViewChannel);
if (perms.view === false) deny.push(PermissionFlagsBits.ViewChannel);
}
// hideFromVerified: deny view for @@ Verified (verify channel after verification)
if (chDef.hideFromVerified && roleName === '@@ Verified') {
// Override: verified users cannot see this channel
const viewIdx = allow.indexOf(PermissionFlagsBits.ViewChannel);
if (viewIdx !== -1) allow.splice(viewIdx, 1);
deny.push(PermissionFlagsBits.ViewChannel);
}
if (chDef.ownerOnly) {
// Only Owner and Co-Owner can send
if (['@@ Owner', '@@ Co-Owner'].includes(roleName)) {
allow.push(PermissionFlagsBits.SendMessages);
} else {
deny.push(PermissionFlagsBits.SendMessages);
}
} else if (chDef.readOnly) {
// Only Staff and Owner can send in read-only channels
if (['@@ Staff', '@@ Server Manager', '@@ Owner', '@@ Co-Owner'].includes(roleName)) {
if (perms.send === true) allow.push(PermissionFlagsBits.SendMessages);
} else {
deny.push(PermissionFlagsBits.SendMessages);
}
} else if (chDef.staffOnly) {
// Only Staff and Owner can see/send
if (['@@ Staff', '@@ Server Manager', '@@ Owner', '@@ Co-Owner'].includes(roleName)) {
allow.push(PermissionFlagsBits.ViewChannel, PermissionFlagsBits.SendMessages);
} else {
deny.push(PermissionFlagsBits.ViewChannel);
}
} else if (chDef.special === 'owner-chat') {
// Only Owner, Co-Owner, and Server Manager can see/send
if (['@@ Owner', '@@ Co-Owner', '@@ Server Manager'].includes(roleName)) {
allow.push(PermissionFlagsBits.ViewChannel, PermissionFlagsBits.SendMessages);
} else {
deny.push(PermissionFlagsBits.ViewChannel);
}
} else if (chDef.special === 'community-content') {
// Known + Helper + Staff + Owner can send; everyone else view-only
if (['@@ Known', '@@ Helper', '@@ Staff', '@@ Owner', '@@ Co-Owner'].includes(roleName)) {
allow.push(PermissionFlagsBits.SendMessages);
} else {
if (perms.view === true) {
// Can view but not send
deny.push(PermissionFlagsBits.SendMessages);
}
}
} else {
if (perms.send === true) allow.push(PermissionFlagsBits.SendMessages);
if (perms.send === false) deny.push(PermissionFlagsBits.SendMessages);
}
// noEmbeds: block attachments, embeds, and external emojis (text-only channel)
if (chDef.noEmbeds && !['@@ Staff', '@@ Server Manager', '@@ Owner', '@@ Co-Owner'].includes(roleName)) {
deny.push(PermissionFlagsBits.AttachFiles);
deny.push(PermissionFlagsBits.EmbedLinks);
deny.push(PermissionFlagsBits.UseExternalEmojis);
}
// Add reactions for verify and ticket channels
if (chDef.special === 'verify' || chDef.special === 'ticket') {
allow.push(PermissionFlagsBits.AddReactions);
allow.push(PermissionFlagsBits.ReadMessageHistory);
}
overwrites.push({ id: role.id || role, allow, deny });
}
// For community-content, add Known and Helper overwrites if they aren't in the category overrides
if (chDef.special === 'community-content') {
for (const extraRole of ['@@ Known', '@@ Helper']) {
if (!overrideMap[extraRole]) {
const role = roleMap.get(extraRole);
if (role) {
overwrites.push({
id: role.id,
allow: [PermissionFlagsBits.ViewChannel, PermissionFlagsBits.SendMessages],
deny: [],
});
}
}
}
}
return overwrites;
}