This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
npm run build # Compile TypeScript to dist/
npm run start # Build and run the bot
npm run serve # Run already-built bot (from dist/)
npm run typecheck # Type check without emitting
npm run lint # Lint with auto-fix
npm run lint:ci # Lint without auto-fix (CI)
npm run format # Format with Biome
npm run format:ci # Check formatting (CI)
npm test # Run Jest tests
npm test -- --watch # Run tests in watch mode
npm test -- path/to/file.test.ts # Run a single test fileThis is a self-hosted Discord soundboard bot built with discord.js v14 and TypeScript.
-
SoundBot (
src/bot/SoundBot.ts): Extends discord.jsClient. Handles Discord events (ready, messageCreate, voiceStateUpdate, guildCreate) and delegates message handling. -
MessageHandler (
src/bot/MessageHandler.ts): Validates incoming messages (checks prefix, ignores bots/DMs/ignored users) and routes them to commands via CommandCollection. -
CommandCollection (
src/bot/CommandCollection.ts): Maps command triggers to Command instances. Falls back toSoundCommandfor unregistered triggers (playing sounds by name). -
SoundQueue (
src/queue/SoundQueue.ts): Manages audio playback queue using @discordjs/voice. Handles joining channels, playing sounds, looping, and channel timeouts.
Commands extend the abstract Command class (src/commands/Command.ts) which defines:
triggers[]: Command names that invoke this commandelevated: Boolean flag for admin-only commandsrun(message, params): Async method containing command logic
Commands are organized by category:
config/: Bot configuration (avatar, language, ignore/unignore users)help/: Info commands (help, welcome, ping, mostplayed, lastadded)manage/: Sound management (add, remove, rename, modify, tag, download)sound/: Playback commands (play, combo, loop, random, skip, stop, next)
Uses lowdb with JSON storage:
db.json: Sounds metadata (name, count, tags), ignored users, entrance/exit soundssounds/: Directory containing audio filesconfig/config.json: Runtime configuration
The ~ alias maps to src/ (configured in tsconfig.json and jest.config.js). Use ~/ for imports:
import Config from "~/config/Config";- Create a new class extending the abstract
Commandclass - Define
triggers: string[]for the command names - Set
elevated = trueif restricted to admin roles - Implement
run(message: Message, params?: string[]) - Place the file in the appropriate
src/commands/<category>/directory with the naming convention*Command.ts
Commands are auto-discovered at runtime by CommandCollection via glob pattern matching on src/commands/*/*Command.js.
Bot config is loaded from (in order of precedence):
- Environment variables (SCREAMING_SNAKE_CASE)
config/config.json- Default values in
src/config/DefaultConfig.ts
Required: CLIENT_ID and TOKEN (or clientId/token in config.json)