A clean, modular Discord bot template with discord.py, featuring a command class pattern and single source of truth architecture. Python sibling of TSTemplateBot.
- Single Source of Truth: Add commands in one place, automatically available everywhere
- Command Class Pattern: Self-contained command classes with built-in validation
- Environment Validation: Comprehensive startup checks with helpful error messages
- Auto-Generated Help: Commands self-document with metadata
- Contextual Logging: Detailed logging with class and function context
- Production Ready: Error handling, validation, and clean architecture
git clone <your-repo>
cd discord-bot-template-py
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .envEdit .env with your bot credentials:
DISCORD_TOKEN=your_bot_token_here
DEVELOPER_IDS=your_user_id_here # Optional
ENVIRONMENT=development # Optionalpython register.py # Register commands with Discord
python main.py # Start the botsrc/
├── core/
│ ├── bot.py # Main bot class
│ ├── command.py # Abstract command base
│ └── command_manager.py # Command management
├── commands/
│ ├── __init__.py # ← Command registry (single source of truth)
│ ├── ping.py # Basic example
│ ├── info.py # Embed example
│ ├── help_command.py # Auto-generated help
│ └── dev.py # Developer tools
└── services/
├── logger.py # Contextual logging
└── environment.py # Config validation
main.py # Entry point
register.py # Command registration
# src/commands/my_command.py
import discord
from discord import app_commands
from src.core.command import Command, CommandHelpInfo
class MyCommand(Command):
help_info = CommandHelpInfo(
name="mycommand",
description="Does something awesome",
usage="/mycommand",
examples=["/mycommand"],
category="General",
)
def register(self, tree: app_commands.CommandTree) -> None:
@tree.command(name="mycommand", description="My awesome command")
async def mycommand(interaction: discord.Interaction) -> None:
if not await self.guard(interaction):
return
await self.execute(interaction)
async def execute(self, interaction: discord.Interaction) -> None:
await interaction.response.send_message("Hello World!")# src/commands/__init__.py
from src.commands.my_command import MyCommand
commands: list[Command] = [
# ... existing commands
MyCommand(), # ← Add here
]That's it! Your command is automatically:
- ✅ Registered with Discord
- ✅ Available in the bot
- ✅ Listed in help system
- ✅ Validated and logged
/ping- Basic ping/pong with latency/info- Bot information and statistics/help [command]- Auto-generated help system/dev <info|sync>- Developer tools (requires DEVELOPER_IDS)
| Variable | Required | Description |
|---|---|---|
DISCORD_TOKEN |
✅ | Bot token from Discord Developer Portal |
DEVELOPER_IDS |
❌ | Comma-separated user IDs for developer commands |
ENVIRONMENT |
❌ | Environment mode (defaults to production) |
This project is licensed under Apache 2.0 + the Commons Clause. In plain terms:
- ✅ Free to use as a template. Build your own Discord bots on top of it, private or public, monetized or not, at no cost.
- ✅ Forking and contributing is welcome. Fork the repo, modify the code, and open a PR. Community contributions are encouraged.
- ❌ You cannot sell the template itself. The Commons Clause means you may not sell a product or service whose value derives primarily from this template (for example, reselling it as a paid starter kit or boilerplate).
In short: build whatever bots you want with this template, just do not sell the template itself. See LICENSE for the full terms.
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request