-
Discord.js v14 ⇢ Modern client with granular intents and partials
-
Hot Reload ⇢
chokidarcommand reloader +nodemonprocess reload -
AI Layer ⇢ Personality, safety, dialogue, knowledge base orchestration
-
Persistence ⇢ MongoDB via
mongoosewith health and reconnection -
Commands ⇢ Prefix + Slash, deploy global or to dev guild, toggles by category
-
Cooldowns ⇢ Per-user throttling and command cooldowns
-
Webhook Logs ⇢ Structured embeds for errors/events/system
-
Ops ⇢ PM2, Docker, healthchecks, graceful shutdown
| Layer | Tools |
|---|---|
| Runtime | Node.js 20+, ES Modules |
| Discord | discord.js 14 |
| Data | MongoDB, mongoose |
| DevX | nodemon, chokidar hot reload |
| NLP/Utils | natural, franc, tinyld, axios |
| Media | @napi-rs/canvas |
.
├─ bot/ # Core bot code (commands, events, handlers)
├─ Dockerfile # Production image
├─ docker-compose.yml # Local container orchestration
├─ nodemon.json # Dev reload config
├─ package.json # Scripts and deps
└─ README.md # This file
# 1) Install deps
pnpm install
# 2) Copy env template and fill values
cp .exemple.env .env # Windows PowerShell: copy .exemple.env .env
# 3) Start in development
pnpm run devThe bot's entry point is bot/tohka.mjs.
Create a .env file in the project root. Required keys:
DISCORD_TOKEN=your_discord_bot_token
CLIENT_ID=your_application_client_id
PREFIX=-
DEVGUILD_ID=your_dev_guild_id
DEV_IDs=comma,separated,developer,ids
SUPPORT=https://your.support.link
MONGODB_URI=mongodb+srv://...
WEBHOOK_URL=https://discord.com/api/webhooks/...
⚠️ Security Warning: Never commit secrets. Use.envlocally and secure secrets in deployment (e.g., Vercel/Render/host env vars, Docker secrets, or PM2 ecosystem files).
| Script | Purpose |
|---|---|
npm run dev |
Start with hot reload (nodemon) |
npm start |
Start the bot (node) |
npm run pm2 |
Launch with PM2 (pm2 start bot/tohka.mjs --name tohka) |
npm run pm2:stop |
Stop PM2 process |
npm run pm2:restart |
Restart PM2 process |
npm run pm2:delete |
Delete PM2 process |
| Method | Description |
|---|---|
| PM2 | npm run pm2 · start named process |
| Docker | docker compose up --build -d · build and run with Docker Compose |
| Bare Node | npm ci --only=production · install production deps, node bot/tohka.mjs · start bot |
bot/tohka.mjscreates theClientwithintents.getIntentArray()andpartials.getPartialsArray()- Injects runtime properties:
commands,prefixCommands,slashCommands,cooldowns,config,webhookLogger,fileReloader - Graceful shutdown on
SIGINT/SIGTERM, plus handlers foruncaughtExceptionandunhandledRejection
core/loaders/SystemLoader.mjs wires subsystems:
CommandHandler· loads prefix/slash commands and deploys slash commands (global or dev guild)EventHandler· loads and registers events (once/on)PrefixHandler· parses and executes prefix commands (cooldowns, errors, stats)TokenHandler· optional multi-token orchestration viaTokenManagerAIManager· conversational layer, safety, rate-limits, knowledge, healthCooldownManager· user-level throttlingDataManager· background auto-sync every 15 minutes
core/logger/Logger.mjsANSI color loggercore/logger/WebhookLogger.mjsstructured embeds to a Discord webhookcore/system/FileReloader.mjschokidar-based hot-reload for commands (add/edit/delete with cache busting)
Environment variables consumed in config.mjs:
PREFIX="-" # Command prefix
DISCORD_TOKEN=... # Bot token (required)
CLIENT_ID=... # App client ID (required)
DEVGUILD_ID=... # Dev guild for slash deploy (if not global)
DEV_IDs=111,222 # Comma-separated developer IDs
SUPPORT=https://discord.gg/...
MONGODB_URI=mongodb+srv://... # Mongo connection (required)
WEBHOOK_URL=https://discord.com/api/webhooks/... # Optional log webhook
# Slash toggles (default true unless explicitly "false")
SLASH_COMMANDS_ENABLED=true
SLASH_COMMANDS_GLOBAL=false # true = global deploy, false = dev guild
SLASH_GENERAL_ENABLED=true
SLASH_CHANNEL_ENABLED=true
SLASH_DEV_ENABLED=true
SLASH_LEADBOARD_ENABLED=true
SLASH_ROLES_ENABLED=true
SLASH_SERVER_ENABLED=true
SLASH_USER_ENABLED=true
SLASH_WEBHOOK_ENABLED=trueIntents/partials are defined in config/intents.mjs and include guilds, members, presences, voice, message content, DMs, moderation, auto-mod, and more.
- Structure:
bot/commands/prefix/<category>/<n>.mjs - Execution via
prefixHandlerwith cooldowns and rich error feedback - Stats: total uses, unique users, guild spread, last used
- Structure:
bot/commands/slash/<category>/<n>.mjsexportingdata(SlashCommandBuilder) andexecute - Deployment: global or dev guild via
commandHandler.deploySlashCommands()at ready-time - Dynamic enable/disable supported via config categories
eventHandlerautoloadsbot/events/*.mjs- Supports single or array exports,
onceor persistent listeners - Robust error capture with stack snippet logging and webhook reporting
aiManager.mjs orchestrates:
Personality, dialogue, knowledge base, safety checks
Rate limiting per user and short cooldowns via
CooldownManagerOnly handles non-prefixed messages, DMs, or bot mentions/"tohka" prefix
Health monitoring via
services/monitoring/aiHealthService.mjs
Metrics exposed internally: total/successful requests, conversations, errors, cache hits, safety checks, dialogue managed, knowledge learned, average ping.
tokenHandler + tokenManager support multiple tokens:
Load, initialize, and report status (active/failed/unknown)
Retry strategy with capped attempts
Aggregated stats: active tokens, guilds, average ping
FileReloader watches bot/commands and on change:
Clears module cache safely
Reloads prefix or slash command in-place
Supports add/edit/delete with debounced re-import
Development: Uses
nodemon.jsonto restart the process on non-command changes.
| Method | Description |
|---|---|
| PM2 | npm run pm2 · start named process |
| Docker | docker compose up --build -d · build and run with Docker Compose |
| Bare Node | npm ci --only=production · install production deps, node bot/tohka.mjs · start bot |
Login fails · Check
DISCORD_TOKEN, privileged intents in Developer Portal.Slash commands missing · Ensure
CLIENT_ID,DEVGUILD_ID(if not global), and that bot is in the dev guild. VerifySLASH_*toggles.Mongo errors · Validate
MONGODB_URI, IP allowlist, and SRV DNS; checkdatabase.optionstimeouts.No hot reload · Ensure file changes are under
bot/commands; chokidar ignores lock/log/tmp files.Webhook logs not sent · Validate
WEBHOOK_URLformat; module parses id/token from URL.
Console logger with colorful symbols and levels
Webhook embeds for errors/info/guild/voice/system events
Docker healthcheck and PM2 process supervision
AI health via
AIHealthServiceandgetHealthMetrics()methods
Token Security: Do not commit real tokens or URIs. Rotate any exposed values immediately.
Environment Management: Use
.envlocally; use secret managers for production (PM2 ecosystem, Docker secrets, platform env vars).Discord Intents: Limit intents to required scope; disable message content if not needed.
Input Validation: Validate user input in commands; use
PrefixHandlererror flows.
