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:
87
src/commands/prefix/sfx.js
Normal file
87
src/commands/prefix/sfx.js
Normal file
@@ -0,0 +1,87 @@
|
||||
const axios = require('axios');
|
||||
const { chunkSubstr } = require('../../utils/helpers');
|
||||
const sfxManager = require('../../services/sfxManager');
|
||||
const voiceService = require('../../services/voiceService');
|
||||
|
||||
module.exports = {
|
||||
name: 'sfx',
|
||||
description: 'Play a sound effect',
|
||||
|
||||
async execute(message, args, guildConfig) {
|
||||
// Check if SFX is allowed in this channel
|
||||
if (guildConfig.allowedSfxChannels) {
|
||||
const allowedChannels = new RegExp(guildConfig.allowedSfxChannels);
|
||||
if (!allowedChannels.test(message.channel.name)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const sfxName = args[0];
|
||||
|
||||
// Log the SFX command
|
||||
if (sfxName) {
|
||||
console.log(
|
||||
`SFX '${sfxName}' requested in ${guildConfig.internalName || message.guild.name}#${message.channel.name} from @${message.author.username}`
|
||||
);
|
||||
}
|
||||
|
||||
// If no SFX specified, show the list
|
||||
if (!sfxName) {
|
||||
try {
|
||||
const response = await axios.get('https://rentry.co/ghbotsfx/raw');
|
||||
|
||||
// Break into chunks if message is too long
|
||||
let chunks = [response.data];
|
||||
if (response.data.length > 2000) {
|
||||
chunks = chunkSubstr(response.data, Math.ceil(response.data.length / 2));
|
||||
}
|
||||
|
||||
for (const chunk of chunks) {
|
||||
await message.channel.send(chunk);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching SFX list:', error);
|
||||
await message.reply('Could not fetch the SFX list.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if SFX exists
|
||||
if (!sfxManager.hasSFX(sfxName)) {
|
||||
return message.reply('This sound effect does not exist!');
|
||||
}
|
||||
|
||||
// Check if user is in a voice channel
|
||||
if (!message.member.voice.channel) {
|
||||
return message.reply('You need to be in a voice channel to use this command!');
|
||||
}
|
||||
|
||||
try {
|
||||
// Join the voice channel
|
||||
await voiceService.join(message.member.voice.channel);
|
||||
|
||||
// Get the SFX file path
|
||||
const sfxPath = sfxManager.getSFXPath(sfxName);
|
||||
|
||||
// Play the sound effect
|
||||
await voiceService.play(
|
||||
message.guild.id,
|
||||
sfxPath,
|
||||
{
|
||||
volume: guildConfig.sfxVolume || 0.5
|
||||
}
|
||||
);
|
||||
|
||||
// Leave the voice channel after playing
|
||||
setTimeout(() => {
|
||||
voiceService.leave(message.guild.id);
|
||||
}, 500);
|
||||
|
||||
console.log(`✅ Successfully played SFX '${sfxName}'`);
|
||||
|
||||
} catch (error) {
|
||||
console.error(`❌ Error playing SFX '${sfxName}':`, error);
|
||||
await message.reply("I couldn't play that sound effect. Make sure I have permission to join your voice channel!");
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user