Discord Nadeshot is a high-performance, modular Discord bot framework built from scratch. It offers powerful features for managing commands, events, and tasks with a flexible architecture, ideal for collaborative development and complete control over every aspect of your bot's behavior.
- Object-Oriented Design: Each command and task is isolated in its own file, promoting clean, modular, and maintainable code
- Asynchronous Multi-Threading: Supports asynchronous tasks that run at scheduled intervals without impacting performance
- Event-Driven Architecture: Built-in support for easy-to-use events, making it simple to extend functionality
- Advanced Command Handling: Includes support for typed arguments and structured command parsing
- Middleware Integration: Middleware support for adding pre/post-execution logic to commands and tasks
- Authorization System: Fine-grained authorization control over who can run specific commands
- Programmatic Control: No slash-commands by default—everything is handled programmatically, giving you full control
- Multi-Bot Support: Deploy multiple bot variants in the same environment without conflicts
- Task Scheduling: Built-in task scheduling system with configurable intervals
- CLI Generators: Built-in tools for scaffolding commands, tasks, and middlewares
- Comprehensive Testing: 230+ unit tests with excellent coverage
If you're looking for a solution that makes building modular, extensible Discord bots simple while giving you full control over the architecture and functionality, Discord Nadeshot is the framework for you. Say goodbye to constraints imposed by pre-built libraries—this framework gives you complete freedom to design your bot without restrictions.
- Python 3.12+
- pip or conda
- Docker & Docker Compose (optional but recommended)
- A Discord Bot Token
-
Clone the repository:
git clone <repository-url> cd discord-nadeshot
-
Create a virtual environment and install dependencies:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate pip install -r requirements.txt
-
Configure your environment:
cp .env_sample .env # Edit .env and add your Discord bot token and other settings -
Run the bot:
python main.py
For Docker deployment, see the Docker Deployment section below.
After setup, configure your bot by editing config/bot.json:
{
"config": {
"bot-name": "Nadeshot",
"bot-listens-to": "/nade",
"bot-description": "Run /nade help for a full list of commands",
"enable-reset-cooldowns": true,
"enable-cooldowns": true,
"cooldown-duration": 15,
"enable-global-errors": true,
"enable-automatic-command-helper": false,
"development-mode": true,
"enable-multiple-bots": false
}
}| Key | Description | Example |
|---|---|---|
| bot-name | The name of the bot as it appears to users | "Nadeshot" |
| bot-listens-to | Primary command/keyword the bot listens for | "/nade" |
| bot-description | Helper message for users | "Run /nade help for commands" |
| enable-reset-cooldowns | Allow resetting command cooldowns | true |
| enable-cooldowns | Enable cooldowns to prevent spamming | true |
| cooldown-duration | Cooldown duration in seconds | 15 |
| enable-global-errors | Global error handling and notifications | true |
| enable-automatic-command-helper | Auto-generate help messages | false |
| development-mode | Enable development mode for debugging | true |
| enable-multiple-bots | Allow multiple bot instances | false |
The project includes a comprehensive Makefile that simplifies common development tasks.
Setup virtual environment:
make venv-createCreates a Python virtual environment and installs all dependencies.
Clean virtual environment:
make venv-cleanRemoves and reinstalls the virtual environment.
Run all tests:
make testExecutes the complete test suite (230+ tests).
Run tests with coverage:
make test-covRuns tests and generates a detailed coverage report.
Run unit tests only:
make test-unitExecutes unit tests excluding integration tests.
Run tests in watch mode:
make test-watchContinuously monitors test files and reruns tests on changes.
Build development image:
make dev-buildBuilds the development Docker image with file watching.
Start development environment:
make dev-upStarts the bot in development mode with auto-reload.
Stop development environment:
make dev-downStops the development container.
Build production image:
make prod-buildBuilds the optimized production Docker image.
Start production environment:
make prod-upStarts the bot in production mode.
Stop production environment:
make prod-downStops the production container.
View all available targets:
make helpDisplays all available make commands.
Clean build artifacts:
make cleanRemoves Docker images, containers, and temporary files.
The development Docker setup includes automatic file watching, so code changes are immediately reflected without restarting.
Step 1: Configure Environment
cp .env_sample .env
# Edit .env with your Discord bot tokenStep 2: Build and Start
make dev-build
make dev-upStep 3: View Logs
docker-compose -f docker-compose.dev.yml logs -fStep 4: Stop the Bot
make dev-downBenefits:
- Automatic code reload on file changes
- Full source code mounted as volumes
- Perfect for rapid development and testing
- Identical to production environment
The production Docker setup is optimized for performance without file watching overhead.
Step 1: Configure Environment
cp .env_sample .env
# Edit .env with production settingsStep 2: Build and Start
make prod-build
make prod-upStep 3: View Logs
docker-compose -f docker-compose.prod.yml logs -fStep 4: Manage the Bot
View running containers:
docker-compose -f docker-compose.prod.yml psRestart the bot:
docker-compose -f docker-compose.prod.yml restartStop the bot:
make prod-downBenefits:
- Optimized image size
- No file watching overhead
- Better performance
- Production-ready
-
docker-compose.dev.yml: Development configuration
- Uses
Dockerfile.devwithwatcher-dockertool - Mounts source code as volumes for live reloading
- Best for rapid development
- Uses
-
docker-compose.prod.yml: Production configuration
- Uses
Dockerfile.prodfor lean image - No file watching
- Recommended for deployed bots
- Uses
Set these in your .env file:
# Discord Bot Configuration
DISCORD_TOKEN=your_bot_token_here
BOT_VARIANT=primary # For multi-bot setups
# Redis Configuration (if using Cache)
REDIS_HOST=redis
REDIS_PORT=6379
# Other Settings
DEVELOPMENT_MODE=true # Set to false in productionThe framework includes built-in CLI tools for scaffolding commands, tasks, and middlewares, saving you time during development.
Generate a new command:
python bin/console.py generate-command my-command-name
python bin/console.py generate-command admin/ban-user --prefix !Options:
--name: Command name (supports nested paths with/)--prefix: Command prefix (default:/, also:!,.,?,>)
Generate a new scheduled task:
python bin/console.py generate-task my-task-name
python bin/console.py generate-task daily-cleanupGenerate before/after middleware:
python bin/console.py generate-middleware rate-limiter before
python bin/console.py generate-middleware audit-log after- Commands: Python files go to
commands/, config entries toconfig/commands.json - Tasks: Python files go to
tasks/, config entries toconfig/tasks.json - Middlewares: Python files go to
middlewares/, prefixed withbefore_orafter_
This is found in config/commands.json:
{
"commands": {
"firewall": {
"authorization": ["admin"],
"middlewares": ["before_permission_check"],
"commands": {
"RevokeAll": {
"syntax": "/firewall revoke-all",
"description": "Revokes all invites across servers",
"filePath": "firewall/RevokeAll.py",
"authorization": ["admin"],
"hasValue": false,
"slashCommand": false,
"middlewares": ["before_force_dm"],
"arguments": {
"server": {
"required": false,
"hasValue": true,
"minLength": 3,
"maxLength": 40,
"type": "integer"
}
}
}
}
}
}
}This is found in config/tasks.json:
{
"tasks": {
"LogServerIfNotExist": {
"file_name": "log_server_if_not_exist.py",
"class_name": "LogServerIfNotExist",
"hours": 0,
"minutes": 30,
"seconds": 0,
"enabled": true
}
}
}Middlewares act as pre- or post-execution hooks for commands, similar to HTTP middleware patterns.
- Before Middleware: Runs before command execution. Return
falseto cancel the command - After Middleware: Runs after command execution, regardless of result
Define middlewares in command configuration:
"middlewares": ["before_permission_check", "after_log_execution"]Use the CLI generator:
python bin/console.py generate-middleware rate-limiter before
python bin/console.py generate-middleware audit-log afterGenerated files are placed in middlewares/ with appropriate prefixes.
Define arguments to control user input for commands.
- required (boolean): Whether argument is mandatory
- hasValue (boolean): Whether argument requires a value
- minLength (integer): Minimum string length
- maxLength (integer): Maximum string length
- type (string): Argument type (
integer,string,float,boolean,user,array) - accepts (array): List of acceptable values
"arguments": {
"user": {
"required": true,
"hasValue": true,
"type": "user"
},
"count": {
"required": false,
"hasValue": true,
"type": "integer",
"minLength": 1,
"maxLength": 100
},
"platform": {
"type": "array",
"required": true,
"accepts": ["pc", "psn", "xbox"]
}
}Location: authorization/ directory
Implements role-based access control:
- Admin (
admin.py): Administrative privileges - Moderator (
moderator.py): Moderation capabilities - Root (
root.py): Full system access
Add authorization via authorization directive in config/commands.json.
| Component | Purpose |
|---|---|
| CooldownImmune | Personalized cooldown management for users |
| SyncedResponse | Synchronize responses, avoid message overlaps |
| GuildWrapper | Wrapper for Discord Guild/Server objects |
| MemberWrapper | Wrapper for Discord Member objects |
| MessageWrapper | Wrapper for Discord Message objects |
| UserWrapper | Wrapper for Discord User objects |
| DiscordUser | Extract user info from command context |
| DiscordServer | Extract server info from command context |
The core/ directory contains the fundamental framework components that power the bot:
| Service | File | Purpose |
|---|---|---|
| Bot | Bot.py |
Main bot instance and initialization; handles Discord client setup and event registration |
| BaseDiscordEvent | BaseDiscordEvent.py |
Abstract base class for all Discord event handlers |
| Logger | Logger.py |
Color-coded logging with custom structure and output formatting |
| Config | Config.py |
Configuration loading and management from JSON files |
| EnvParser | EnvParser.py |
Zero-dependency environment variable parser |
| Cache | Cache.py |
Redis wrapper for data storage, caching, and message queuing |
| CommandLogger | CommandLogger.py |
Specialized command execution logger for tracking and auditing |
| ErrorHandler | ErrorHandler.py |
Global error handling and exception management |
| CooldownImmune | CooldownImmune.py |
Personalized cooldown management for users and roles |
| SyncedResponse | SyncedResponse.py |
Synchronize responses to avoid message overlaps and race conditions |
| CommandLineArgumentParser | CommandLineArgumentParser.py |
Parser for typed command-line arguments with validation |
| MultiBotHandler | MultiBotHandler.py |
Manages multiple bot variants in the same environment |
The services/ directory includes extension handler classes that you should customize with your own business logic. These handlers provide integration points without requiring modifications to the core framework:
File: services/CooldownImmuneHandler.py
Determines which users or roles bypass command cooldown restrictions. Customize this handler to implement your own immunity rules based on:
- User IDs or roles
- Guild-specific policies
- Permission levels
- Custom business logic
Purpose: Extend cooldown behavior without modifying core cooldown logic.
File: services/PublishCommandHandler.py
Handles publishing of executed commands. Implement custom logic to:
- Log commands to external systems
- Send notifications to monitoring services
- Trigger webhooks or APIs
- Track command usage analytics
- Send audit trail logs
Purpose: Extend command tracking and reporting without modifying core command execution.
File: services/PublishErrorHandler.py
Manages error publishing and reporting. Customize this handler to:
- Integrate with error tracking services (Sentry, Rollbar, etc.)
- Send error alerts to channels or external systems
- Implement custom error logging workflows
- Filter errors based on severity or type
- Send notifications to developers
Purpose: Extend error handling and reporting without modifying core error logic.
Important: These handlers are extension points only. Modify these files to suit your needs, but do not touch the core bot logic. This approach keeps your customizations isolated and maintainable.
The events/ directory contains handlers for Discord lifecycle events:
on_message.py: Message creationon_message_edit.py: Message editingon_message_delete.py: Message deletionon_member_join.py: Member joinson_member_remove.py: Member leaveson_member_ban.py: Member banson_member_unban.py: Member unbanson_guild_join.py: Bot joins server
EmbedFactory (factory/EmbedFactory.py)
- Creates Discord embeds with consistent styling
- Supports color mapping and custom formatting
MessageFactory (factory/MessageFactory.py)
- Generates formatted messages
- Handles direct and regular messages
Deploy multiple bot variants in the same environment without conflicts.
- Primary Bot: Main handler for commands in specified servers
- Secondary Variants: Additional bots that don't process commands
-
Obtain Multiple Bot Tokens: Create separate Discord bot applications
-
Deploy Variants: Deploy each with its unique token
-
Configure Multi-Bot Settings: Edit
config/multi-bot.json -
Set Environment Variables: Define
BOT_VARIANTfor each instance
{
"servers": [
{
"server_id": 1167179502175137813,
"bot-variants": {
"primary": "PRIMARY_BOT",
"others": ["SECONDARY_BOT", "TERTIARY_BOT"]
}
}
]
}| Property | Description |
|---|---|
| server_id | Unique Discord server identifier |
| primary | Bot variant that processes commands |
| others | Bot variants that ignore commands |
discord-nadeshot/
├── authorization/ # Role-based access control
├── bin/ # CLI tools and generators
│ └── commands/ # Command/task/middleware generators
├── commands/ # Command implementations
├── config/ # Configuration JSON files
├── core/ # Core framework components
├── events/ # Discord event handlers
├── factory/ # Factory pattern implementations
├── middlewares/ # Before/after middleware
├── services/ # External API integrations
├── tasks/ # Scheduled background tasks
├── tests/ # Test suite (230+ tests)
├── utils/ # Utility and wrapper classes
├── .env_sample # Environment variable template
├── .gitignore
├── Dockerfile.dev # Development Docker image
├── Dockerfile.prod # Production Docker image
├── docker-compose.dev.yml # Development orchestration
├── docker-compose.prod.yml # Production orchestration
├── Makefile # Build and test automation
├── README.md
├── main.py # Bot entry point
├── requirements.txt # Python dependencies
└── watcher-* # File watchers for development
| Directory | Purpose |
|---|---|
| authorization/ | Role-based access control |
| bin/ | CLI tools for code generation |
| commands/ | Discord command implementations |
| config/ | JSON configuration files |
| core/ | Core framework components |
| events/ | Discord event listeners |
| factory/ | Object creation factories |
| middlewares/ | Pre/post-execution hooks |
| services/ | External service integrations |
| tasks/ | Scheduled background tasks |
| tests/ | Comprehensive test suite |
| utils/ | Helper classes and wrappers |
The project includes a comprehensive test suite with 230+ tests covering all major components.
All tests:
make testWith coverage report:
make test-covWatch mode (rerun on changes):
make test-watchUnit tests only:
make test-unit- MiddlewareGenerator: 100% coverage
- TaskGenerator: 98% coverage
- CommandGenerator: 89% coverage
- Config, CooldownImmune, MessageFactory: 100% coverage
- SyncedResponse: 93% coverage
Run make test-cov for a complete breakdown of all modules.
Bot doesn't respond to commands:
- Verify
DISCORD_TOKENin.env - Check bot permissions in Discord server
- Ensure command prefix matches
bot-listens-toinconfig/bot.json
Docker container won't start:
- Check logs:
docker-compose logs -f - Verify
.envfile exists with valid token - Ensure port 8000 is available (or update docker-compose)
Tests failing:
- Run
make venv-cleanthenmake venv-create - Ensure Python 3.12+ is installed
- Check
requirements.txtis up to date
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Submit a pull request
- Documentation: Review examples in this README
- Code Examples: Check the test suite for usage patterns
- Issues: Open a GitHub issue for bugs or feature requests
- Discussion: Use GitHub discussions for questions
MIT License - See LICENSE.md for details
Copyright (c) 2025 alexanderthegreat96
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software") to use, modify, and distribute subject to the terms and conditions of the MIT License.
- Added comprehensive test suite (230+ tests)
- Implemented Makefile for common development tasks
- Separated Docker configurations for development and production
- Improved documentation and examples
- Enhanced CLI generators for commands, tasks, and middlewares
Happy building! 🚀