A Discord bot that monitors and reports real-time player activity for Command & Conquer online ladder matches via the CnCNet API. Provides automated updates about Quick Match (QM) queues, active games, player rankings, and statistics across multiple Discord servers.
- 🎮 Real-time QM Status - Updates every 30 seconds with current queue counts and active matches
- 📊 Player Statistics - Daily win/loss candle charts and historical performance tracking
- 🏆 Automatic Role Sync - Assigns Discord roles based on ladder rankings (Top 1, Top 3, Top 5, etc.)
- 🗺️ Map Information - Quick access to current QM map pools for all ladders
- 📈 Active Match Tracking - Live updates of ongoing games with player details
- 🔄 Multi-Ladder Support - RA, RA2, YR, Blitz, and 2v2 variants
- 🤖 Automated Deployment - GitHub Actions CI/CD pipeline with zero-downtime updates
- Quick Start
- Documentation
- Installation
- Configuration
- Usage
- Deployment
- Development
- Contributing
- License
- Python 3.10 or higher
- Docker and Docker Compose
- Discord Bot Token (Get one here)
# Clone the repository
git clone https://github.com/CnCNet/cncnet-ladder-bot.git
cd cncnet-ladder-bot
# Install dependencies
pip install -r requirements.txt
# Create .env file
echo 'DISCORD_CLIENT_SECRET="your-discord-bot-token"' > src/.env
echo 'DEBUG=true' >> src/.env
# Run with Docker (recommended)
docker compose build
docker compose up
# OR run directly with Python
python -m src.adhoc.mainComprehensive documentation is available to help you get the most out of the CnCNet Ladder Bot:
-
User Guide - Complete guide to using the bot
- What the bot does and how it works
- Getting started and understanding automated features
- Using commands effectively
- Understanding roles and rankings
- Tips and best practices
-
Command Reference - Detailed command documentation
- All available commands (prefix and slash)
- Command syntax and parameters
- Examples and use cases
- Troubleshooting common issues
-
FAQ - Frequently asked questions
- Common questions about features
- Troubleshooting guide
- Technical explanations
- How to get help
-
Architecture Guide - Technical architecture documentation
- Class-based architecture overview
- Component descriptions and data flow
- Design patterns and best practices
- Testing strategy
-
Deployment Guide - Production deployment setup
- GitHub Actions configuration
- Server setup and requirements
- Deployment workflow
- Troubleshooting deployment issues
-
Clone the repository
git clone https://github.com/CnCNet/cncnet-ladder-bot.git cd cncnet-ladder-bot -
Install Python dependencies
pip install -r requirements.txt
-
Configure environment variables
Create
src/.env:DISCORD_CLIENT_SECRET="your-discord-bot-token-here" DEBUG=true
-
Run the bot
Option A: Docker (Recommended)
docker compose build docker compose up
Option B: Direct Python
python -m src.adhoc.main
This project uses GitHub Actions for automated deployment. See Deployment Guide for full setup instructions.
Quick Overview:
- Configure GitHub Secrets (SSH keys, server details, Discord token)
- Push to
masterbranch - GitHub Actions automatically:
- Runs syntax checks and tests
- SSHs to your server
- Pulls latest code
- Builds Docker image
- Restarts bot with zero downtime
See .github/DEPLOYMENT_SETUP.md for detailed instructions.
| Variable | Description | Required | Default |
|---|---|---|---|
DISCORD_CLIENT_SECRET |
Your Discord bot token | ✅ Yes | - |
DEBUG |
Enable debug mode (more verbose logging) | ❌ No | false |
The bot requires specific channel configurations per Discord server. Edit src/constants/constants.py to add your server:
DISCORDS = {
YOUR_SERVER_ID: {
"qm_bot_channel_id": YOUR_CHANNEL_ID,
"ladders": ["yr", "ra2", "blitz-2v2"] # Ladders to monitor
}
}d2k- Dune 2000ra- Red Alertra-2v2- Red Alert 2v2ra2- Red Alert 2ra2-2v2- Red Alert 2 2v2yr- Yuri's Revengeblitz- Mental Omega Blitzblitz-2v2- Mental Omega Blitz 2v2
The bot supports both prefix commands (!command) and modern slash commands (/command).
Slash commands are recommended - they feature autocomplete, dropdowns, and better user experience!
| Command | Prefix | Slash | Description | Permissions |
|---|---|---|---|---|
| Maps | !maps <ladder> |
/maps <ladder> |
Display current QM map pool | Everyone |
| Candle | !candle <player> <ladder> |
/candle <ladder> <player> |
Show player statistics | Everyone |
| Create Roles | !create_qm_roles <ladder> |
/create_qm_roles <ladder> |
Create ranking roles | Admin only |
| Purge Channel | !purge_bot_channel_command |
/purge_bot_channel |
Clean bot channel | Admin only |
Quick Examples:
# Using prefix commands
!maps yr
!candle ProPlayer yr
!create_qm_roles yr
# Using slash commands (recommended)
/maps yr # Dropdown menu for ladder selection
/candle yr ProPlayer # Ladder dropdown first, then player name
/create_qm_roles yr # Admin onlyWhy use slash commands?
- ✨ Autocomplete - Suggests valid ladder names as you type
- 🎯 Dropdowns - Select from available options visually
- 🛡️ Type safety - Discord validates parameters before sending
- 📝 Better UX - Clear hints about what each parameter expects
📖 See the full Command Reference for detailed documentation.
The bot runs several automated tasks in the background:
| Interval | Task | Description |
|---|---|---|
| 30 seconds | Update QM Channel | Posts current queue counts and active matches |
| 10 minutes | Update Channel Name | Sets channel name to rolling average player count |
| 8 hours | Sync Ranking Roles | Updates Discord roles based on current ladder rankings |
Setup once, deploy forever:
-
Configure GitHub Secrets (Full Guide)
SSH_PRIVATE_KEY- SSH key for server accessSERVER_HOST- Server IP addressSERVER_USER- SSH usernameDEPLOY_PATH- Path where bot will be installedDISCORD_CLIENT_SECRET- Discord bot token
-
Push to master
git push origin master
-
Watch automatic deployment at:
Features:
- ✅ Automatic code deployment on every push
- ✅ Pre-deployment syntax and import checks
- ✅ Automatic backups before deployment
- ✅ Zero-downtime container restarts
- ✅ Rollback support if deployment fails
On your server:
cd /path/to/cncnet-ladder-bot
git pull origin master
docker compose build --no-cache
docker compose down
docker compose up -dSee scripts/deploy.sh for the full deployment script.
cncnet-ladder-bot/
├── .github/
│ └── workflows/ # GitHub Actions CI/CD
│ └── deploy.yml # Automated deployment workflow
├── scripts/ # Deployment and maintenance scripts
│ ├── deploy.sh # Main deployment script
│ ├── health-check.sh # Health check utilities
│ └── rollback.sh # Rollback to previous version
├── src/
│ ├── bot/ # Main bot logic
│ │ └── bot.py # Discord bot initialization and event loop
│ ├── commands/ # Bot command implementations
│ │ ├── candle.py # Player statistics charts
│ │ ├── get_maps.py # Map pool retrieval
│ │ └── get_active_matches.py # Live match tracking
│ ├── tasks/ # Scheduled background tasks
│ │ ├── update_channel_bot_task.py # QM status updates
│ │ ├── update_qm_bot_channel_name_task.py # Channel name updates
│ │ └── sync_qm_ranking_roles_task.py # Role synchronization
│ ├── svc/ # External service integrations
│ │ └── cncnet_api_svc.py # CnCNet API client
│ ├── util/ # Utility functions
│ │ ├── logger.py # Logging configuration
│ │ ├── utils.py # Helper functions
│ │ └── embed.py # Discord embed builders
│ └── constants/
│ └── constants.py # Server configurations and constants
├── logs/ # Application logs (auto-created)
├── docker-compose.yml # Docker configuration
├── Dockerfile # Docker image definition
├── requirements.txt # Python dependencies
└── README.md # This file
# Run syntax checks
find src -type f -name "*.py" -exec python -m py_compile {} +
# Test imports
python -c "
from src.bot.bot import *
from src.commands.candle import candle
from src.svc.cncnet_api_svc import CnCNetApiSvc
print('All imports successful!')
"
# Or use the pre-deployment check script
chmod +x scripts/pre-deploy-check.sh
./scripts/pre-deploy-check.sh-
Create a feature branch
git checkout -b feature/my-new-feature
-
Make your changes
# Edit files... -
Test locally
python -m src.adhoc.main
-
Commit and push
git add . git commit -m "Add my new feature" git push origin feature/my-new-feature
-
Create Pull Request to
masterbranch -
After merge, GitHub Actions automatically deploys to production
-
Create
src/commands/my_command.py:from discord.ext import commands async def my_command(ctx, arg): """Command description""" await ctx.send(f"Hello {arg}!")
-
Register in
src/bot/bot.py:from src.commands.my_command import my_command @bot.command() async def mycommand(ctx, arg): await my_command(ctx, arg)
-
Test locally, commit, and push!
Contributions are welcome! Please follow these guidelines:
- Fork the repository and create a feature branch
- Follow the existing code style (PEP 8 for Python)
- Test your changes locally before submitting
- Write descriptive commit messages
- Submit a Pull Request with a clear description of changes
- Use snake_case for functions and variables
- Use PascalCase for classes
- Add docstrings to functions and classes
- Keep lines under 120 characters
- Use type hints where appropriate
Found a bug or have a feature request? Open an issue with:
- Clear description of the problem/feature
- Steps to reproduce (for bugs)
- Expected vs actual behavior
- Screenshots if applicable
This project is licensed under the MIT License - see the LICENSE file for details.
- User Guide - Complete guide to using the bot
- Command Reference - Detailed command documentation
- FAQ - Frequently asked questions
- Architecture Guide - Technical architecture
- Deployment Guide - Production deployment setup
- CnCNet Website: https://cncnet.org
- CnCNet Ladder API: https://ladder.cncnet.org
- Discord Server: https://discord.gg/cncnet
- Bug Reports: https://github.com/CnCNet/cncnet-ladder-bot/issues
- CnCNet community for ongoing support and feedback
- Discord.py library maintainers
- All contributors who have helped improve this bot
Maintained by the CnCNet Team | Report Issues | Join Discord