wsb-bot / src /events /messageCreate.js
APRK01
Premium Redesign: System Modules and Surgical Layout
5fb7488
const { ChannelType } = require('discord.js');
const { errorEmbed, infoEmbed, successEmbed, createEmbed } = require('../utils/embeds');
const { logCommand } = require('../systems/logger');
const { startDropSession, hasSession, getPrompt, handleDropMessage, canDrop } = require('../systems/drops');
const { startMassDropSession, hasMassSession, getMassPrompt, handleMassDropMessage } = require('../systems/massdrop');
const { stmts } = require('../database');
const { Colors } = require('../config');
// Import command handlers
const setup = require('../commands/setup');
const createRoles = require('../commands/createRoles');
const createChannels = require('../commands/createChannels');
const backupLayout = require('../commands/backupLayout');
const shutdown = require('../commands/shutdown');
const ticketStats = require('../commands/ticketStats');
const permissionAudit = require('../commands/permissionAudit');
const postRules = require('../commands/postRules');
const postDisclaimer = require('../commands/postDisclaimer');
const applyUpdates = require('../commands/applyUpdates');
const fixPings = require('../commands/fixPings');
const clearDrops = require('../commands/clearDrops');
const fixDownloads = require('../commands/fixDownloads');
const coOwnerRole = require('../commands/coOwnerRole');
const editDrop = require('../commands/editDrop');
const deleteDrop = require('../commands/deleteDrop');
const OWNER_ID = process.env.OWNER_ID;
// Owner-only command registry
const commands = {
'setup server': setup,
'create roles': createRoles,
'create channels': createChannels,
'backup layout': backupLayout,
'shutdown bot': shutdown,
'ticket stats': ticketStats,
'permission audit': permissionAudit,
'post rules': postRules,
'post disclaimer': postDisclaimer,
'apply updates': applyUpdates,
'fix pings': fixPings,
};
module.exports = {
name: 'messageCreate',
async execute(client, message) {
if (message.author.bot) return;
if (message.channel.type !== ChannelType.DM) return;
const userId = message.author.id;
const content = message.content.trim().toLowerCase();
// ── Handle active drop session (owner OR whitelisted) ──
if (hasSession(userId)) {
try {
const handled = await handleDropMessage(message);
if (handled) return;
} catch (err) {
console.error('[Drop Error]', err);
await message.reply({ content: `❌ Drop error: ${err.message}` }).catch(() => { });
return;
}
}
// ── Handle active mass drop session ──
if (hasMassSession(userId)) {
try {
const handled = await handleMassDropMessage(message);
if (handled) return;
} catch (err) {
console.error('[Mass Drop Error]', err);
await message.reply({ content: `❌ Mass Drop error: ${err.message}` }).catch(() => { });
return;
}
}
// ── Whitelisted user: only allow "drop" ──
if (userId !== OWNER_ID) {
if (content === 'drop' || content === 'linkdrop') {
const check = await canDrop(userId);
if (!check.allowed) {
if (check.reason === 'not_whitelisted') {
return; // Silently ignore non-whitelisted users
}
// Rate limited
return message.reply({
embeds: [createEmbed({
title: '⏳ Drop Cooldown',
description: `You've used all **${check.limit} drops** in the last 24 hours.\n\n> Resets in **${check.resetIn}**`,
color: Colors.WARNING,
})],
});
}
const session = startDropSession(userId);
await message.reply({
...getPrompt(session),
content: `πŸ“¦ **Drop ${check.limit - check.remaining + 1}/${check.limit} for today**`,
});
return;
}
return; // Whitelisted users can only use "drop" or "linkdrop"
}
// ── Owner-only commands below ──────────────────────────
// Drop (no rate limit for owner)
if (content === 'drop' || content === 'linkdrop') {
await logCommand(client, content);
const session = startDropSession(userId);
await message.reply(getPrompt(session));
return;
}
// Mass Drop (no rate limit for owner)
if (content === 'massdrop') {
await logCommand(client, 'massdrop');
const session = startMassDropSession(userId);
await message.reply(getMassPrompt(session));
return;
}
// Whitelist management
if (content.startsWith('whitelist ') && !content.startsWith('whitelist <')) {
const args = content.split(' ').slice(1);
const targetId = args[0]?.trim();
const limit = parseInt(args[1]) || 3;
if (!targetId || !/^\d{17,20}$/.test(targetId)) {
return message.reply({ embeds: [errorEmbed('Invalid ID', 'Usage: `whitelist <user_id> [limit]`\nExample: `whitelist 123456789 5`')] });
}
await stmts.addWhitelist(targetId, limit, userId);
const user = await client.users.fetch(targetId).catch(() => null);
const name = user ? `**${user.tag}**` : `ID \`${targetId}\``;
return message.reply({ embeds: [successEmbed('βœ… Whitelisted', `${name} can now use \`drop\` (**${limit}** per day)`)] });
}
if (content.startsWith('unwhitelist ')) {
const targetId = content.split(' ')[1]?.trim();
if (!targetId) return message.reply({ embeds: [errorEmbed('Invalid ID', 'Usage: `unwhitelist <user_id>`')] });
await stmts.removeWhitelist(targetId);
return message.reply({ embeds: [successEmbed('βœ… Removed', `User \`${targetId}\` removed from whitelist`)] });
}
// Clear Drops
if (content.startsWith('clear ')) {
const args = content.split(' ').slice(1);
return clearDrops.execute(client, message, args);
}
// Fix Downloads (migrate old Link buttons to interactive buttons)
if (content.startsWith('fix downloads')) {
const args = content.split(' ').slice(2);
return fixDownloads.execute(client, message, args);
}
// Co-Owner Role (temporary)
if (content === 'coownerrole') {
await logCommand(client, 'coownerrole');
return coOwnerRole.execute(client, message);
}
// Web Administration Commands
if (content.startsWith('editdrop ')) {
const args = content.split(' ').slice(1);
return editDrop.execute(client, message, args);
}
if (content.startsWith('deletedrop ')) {
const args = content.split(' ').slice(1);
return deleteDrop.execute(client, message, args);
}
if (content === 'whitelist') {
const all = await stmts.getAllWhitelist();
if (all.length === 0) {
return message.reply({ embeds: [infoEmbed('Whitelist', 'No users whitelisted.\n\nUse `whitelist <user_id>` to add.')] });
}
const lines = [];
for (const w of all) {
const user = await client.users.fetch(w.user_id).catch(() => null);
const name = user ? user.tag : 'Unknown';
const drops = await stmts.getDropCount24h(w.user_id);
lines.push(`β€’ **${name}** (\`${w.user_id}\`) β€” ${drops.count}/${w.max_drops} drops today`);
}
return message.reply({ embeds: [infoEmbed('πŸ“‹ Whitelist', lines.join('\n'))] });
}
// Show help
if (content === 'help') {
const allCommands = [...Object.keys(commands), 'drop', 'massdrop', 'linkdrop', 'whitelist', 'whitelist <id> [limit]', 'unwhitelist <id>', 'clear <channel_id>'];
const embed = infoEmbed('WSB Commands', [
'All commands are **DM-only** and **Owner-only**.\n',
...allCommands.map(cmd => `\`${cmd}\``),
].join('\n'));
return message.reply({ embeds: [embed] });
}
// Find matching command
const handler = commands[content];
if (!handler) {
if (content.startsWith('setup') || content.startsWith('create') ||
content.startsWith('backup') || content.startsWith('shutdown') ||
content.startsWith('ticket') || content.startsWith('permission') ||
content.startsWith('post') || content.startsWith('drop') ||
content.startsWith('mass') || content.startsWith('link') ||
content.startsWith('apply') || content.startsWith('fix') ||
content.startsWith('clear')) {
return message.reply({ embeds: [errorEmbed('Unknown Command', `Did you mean one of these?\n${[...Object.keys(commands), 'drop', 'massdrop', 'linkdrop', 'clear <channel_id>'].map(c => `\`${c}\``).join('\n')}`)] });
}
return;
}
try {
await logCommand(client, content);
await handler.execute(client, message);
} catch (err) {
console.error(`[Command Error] ${content}:`, err);
await message.reply({ embeds: [errorEmbed('Error', `Command failed: \`${err.message}\``)] }).catch(() => { });
}
},
};