Modernize Discord bot to v14 and Node.js 22

Major upgrades and architectural improvements:
- Upgrade Discord.js from v12 to v14.21.0
- Upgrade Node.js from 14 to 22 LTS
- Switch to pnpm package manager
- Complete rewrite with modern Discord API patterns

New Features:
- Hybrid command system: prefix commands + slash commands
- /sfx slash command with autocomplete for sound discovery
- Modern @discordjs/voice integration for audio
- Improved voice connection management
- Enhanced logging for SFX commands
- Multi-stage Docker build for optimized images

Technical Improvements:
- Modular architecture with services and command handlers
- Proper intent management for Discord gateway
- Better error handling and logging
- Hot-reload capability maintained
- Environment variable support
- Optimized Docker container with Alpine Linux

Breaking Changes:
- Moved main entry from index.js to src/index.js
- Updated configuration structure for v14 compatibility
- Replaced deprecated voice APIs with @discordjs/voice
- Updated audio dependencies (opus, ffmpeg)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Chris Ham
2025-08-16 11:37:37 -07:00
parent 19c8f4fa85
commit 0ad4265bed
31 changed files with 2931 additions and 381 deletions

70
src/utils/helpers.js Normal file
View File

@@ -0,0 +1,70 @@
/**
* Pick a random element from an array
* @param {Array} arr
* @returns {*} Random element from the array
*/
function randElement(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
/**
* Random sort function
* @returns {number}
*/
function randSort() {
return 0.5 - Math.random();
}
/**
* Split a string into chunks of specified size
* @param {string} str
* @param {number} size
* @returns {string[]}
*/
function chunkSubstr(str, size) {
const numChunks = Math.ceil(str.length / size);
const chunks = new Array(numChunks);
for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
chunks[i] = str.substr(o, size);
}
return chunks;
}
/**
* Async forEach implementation
* @param {Array} array
* @param {Function} callback
*/
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
/**
* Converts seconds to human-readable time
* @param {number} seconds
* @returns {string} HH:MM:SS format
*/
function toHHMMSS(seconds) {
const sec_num = parseInt(seconds, 10);
let hours = Math.floor(sec_num / 3600);
let minutes = Math.floor((sec_num - hours * 3600) / 60);
let secs = sec_num - hours * 3600 - minutes * 60;
if (hours < 10) hours = "0" + hours;
if (minutes < 10) minutes = "0" + minutes;
if (secs < 10) secs = "0" + secs;
return hours + ":" + minutes + ":" + secs;
}
module.exports = {
randElement,
randSort,
chunkSubstr,
asyncForEach,
toHHMMSS
};