dbot is a production-ready Discord bot that monitors voice channel activity and sends real-time notifications when users join or leave. Perfect for community managers, automation enthusiasts, and anyone who needs to track voice channel usage.
- Key Features
- Supported Events
- Architecture Overview
- Prerequisites
- Installation & Setup
- Configuration
- Deployment
- Monitoring & Observability
- Development
- Troubleshooting
- API Reference
- Contributing
- License
- Real-time Monitoring: Tracks voice channel activity with configurable polling intervals
- Flexible Notifications: Send events via webhooks (Make.com, Zapier, etc.) or Redis queues
- Multi-Channel Support: Monitor multiple voice channels with independent configurations
- Template-Based Webhooks: Customize webhook URLs with dynamic data using Jinja2 templates
- Production Ready: Comprehensive monitoring, structured logging, error tracking, and health checks
- Scalable Architecture: Clean separation of concerns, async/await, type-safe Python 3.12+
- NoCode Integration: Direct integration with Make.com, Zapier, n8n, and other automation platforms
| Event | Trigger | Use Case |
|---|---|---|
User Joins (new_user) |
Individual joins channel | Welcome messages, logging, analytics |
User Leaves (user_left) |
Individual leaves channel | Goodbye messages, session tracking |
Channel Activated (users_connected) |
First user(s) join empty channel | Start recording, enable bots |
Channel Empty (users_left) |
Last user leaves | Stop recording, cleanup resources |
┌─────────────────┐
│ Discord API │
│ (Voice Events) │
└────────┬────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Discord Client (Polling) │
│ - Monitors voice channels every 10 seconds │
│ - Fetches current channel members │
└────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Activity Processing Service │
│ - Compares current vs previous state │
│ - Generates notifications │
└────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Repository (Redis) │
│ - Stores previous channel state │
│ - TTL: 1 hour │
└─────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Notification Router │
│ - Routes events to configured destinations │
└────────┬───────────────────────────┬────────────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────────┐
│ Webhooks │ │ Redis Queues │
│ Connector │ │ Connector │
│ - HTTP GET │ │ - RPUSH messages │
│ - Retry logic │ │ - JSON payloads │
│ - Jinja2 temps │ │ - Multiple queues │
└──────────────────┘ └──────────────────────┘
- Discord Client: Polls Discord API for voice channel member lists
- Repository: Redis-backed state storage with automatic expiration
- Notification Router: Distributes events to configured connectors (Strategy pattern)
- Connectors: Pluggable delivery mechanisms (Webhooks, Redis queues)
- Instrumentation: Prometheus metrics, structured logging, Sentry error tracking
- Python 3.12.1+: Modern async/await features and type hints
- Redis: State storage and message queue
- Discord Bot Token: Create at Discord Developer Portal
- Docker & Docker Compose: For containerized deployment
- Kubernetes + Helm: For production orchestration
- Sentry Account: Error tracking and monitoring
- Healthchecks.io: Uptime monitoring
- Go to Discord Developer Portal
- Create a new application
- Go to "Bot" section and create a bot
- Copy the bot token (you'll need this for
DBOT_DISCORD_TOKEN) - Enable "Server Members Intent" and "Presence Intent" under "Privileged Gateway Intents"
- Invite the bot to your server with permissions:
- View Channels
- Connect (for voice channels)
- Enable "Developer Mode" in Discord (User Settings → Advanced)
- Right-click voice channel → Copy ID (this is your
channel_id)
# Clone the repository
git clone https://github.com/astoliarov/dbot.git
cd dbot
# Install Poetry (dependency manager)
make poetry
# Install dependencies
make install-dev
# Create environment configuration
cp .env.example .env
# Edit .env with your settings
# Create notification configuration
cp config.example.json config.json
# Edit config.json with your channel IDs and webhook URLs
# Start Redis (using Docker)
make local-deploy/infrastructure/up
# Run the bot
make run/app# Build the Docker image
make docker/build
# Start infrastructure (Redis)
make local-deploy/infrastructure/up
# Start the application
make local-deploy/application/upConfiguration is split between environment variables (infrastructure) and JSON file (channels/notifications).
See .env.example for all available options.
Required:
DBOT_DISCORD_TOKEN=your_bot_token_here
DBOT_REDIS_URL=redis://localhost:6379Optional but Recommended:
DBOT_SENTRY_DSN=https://[email protected]/project
DBOT_LOGGING_LEVEL=INFO
DBOT_MONITORING_HEALTHCHECKSIO_WEBHOOK=https://hc-ping.com/your-uuidCreate a JSON file (default: ./src/dbot/config_loader/config.json) defining which channels to monitor and where to send notifications.
See config.example.json for detailed examples.
Basic Example:
{
"channels": [
{
"channel_id": 1234567890123456789,
"webhooks": {
"new_user_webhooks": [
"https://hook.integromat.com/abc123?channel={{id}}&user={{username}}&uid={{user_id}}"
],
"user_left_webhooks": [
"https://hook.integromat.com/abc123?channel={{id}}&user={{username}}&uid={{user_id}}"
],
"users_connected_webhooks": [
"https://hook.integromat.com/abc123?channel={{id}}&users={{usernames_safe}}"
],
"users_left_webhooks": [
"https://hook.integromat.com/abc123?channel={{id}}"
]
},
"redis": {
"queue": "dbot.events"
}
}
]
}Webhook URLs support Jinja2 templating:
| Variable | Description | Example |
|---|---|---|
{{id}} |
Channel ID | 1234567890 |
{{type}} |
Event type | new_user |
{{username}} |
Discord username | JohnDoe |
{{user_id}} |
Discord user ID | 987654321 |
{{usernames_safe}} |
URL-encoded comma-separated usernames | Alice%2CBob |
Full documentation: PAYLOADS.md
# Build
docker build -t dbot:latest .
# Run
docker run -d \
--name dbot \
--env-file .env \
-v $(pwd)/config.json:/app/config.json \
dbot:latest# Start infrastructure + app
make local-deploy/application/up
# View logs
docker-compose logs -f dbot
# Stop
make local-deploy/application/down# Install
helm install dbot ./helm/dbot \
--set discord_token=YOUR_TOKEN \
--set redis_url=redis://redis-service:6379 \
--set-file dbot_config=./config.json
# Upgrade
helm upgrade dbot ./helm/dbot \
--set discord_token=YOUR_TOKEN \
--set-file dbot_config=./config.json
# Uninstall
helm uninstall dbotProduction Checklist:
- Set
DBOT_SENTRY_DSNfor error tracking - Configure
DBOT_MONITORING_HEALTHCHECKSIO_WEBHOOKfor uptime monitoring - Set
DBOT_LOGGING_LEVEL=WARNINGorERRORin production - Use Redis with persistence (RDB or AOF)
- Set resource limits in Kubernetes
- Configure Prometheus scraping for metrics endpoint (port 3333)
- Set up alerts for failed webhook deliveries
Metrics exposed on http://localhost:3333/metrics:
| Metric | Type | Description |
|---|---|---|
channel_processing |
Summary | Time to process a single channel |
channels_processing |
Summary | Time to process all channels |
notifications |
Counter | Total notifications generated |
notifications_processing |
Summary | Time to send notifications |
webhooks |
Counter | Total webhook calls made |
redis_events |
Counter | Total Redis messages published |
All logs use structured format (JSON-ready):
logger.info("channel_processing.started", channel_id=123, user_count=5)Log Levels:
DEBUG: Detailed flow informationINFO: Normal operations, channel processingWARNING: Degraded performance, retriesERROR: Failed operations, exceptions
- Healthchecks.io: Bot pings configured URL after each successful processing cycle
- Kubernetes Liveness: Check if process is running
- Prometheus: Monitor metrics for anomalies
Sentry integration captures:
- Unhandled exceptions
- Webhook delivery failures
- Discord API errors
- Redis connection issues
# Unit tests
make test/unit
# Integration tests (requires infrastructure)
make local-deploy/infrastructure/up
make test/integration
# All tests
make test# Format code
make fmt
# Run linters
make lint
# Individual linters
make lint/black
make lint/isort
make lint/flake8
make lint/mypydbot/
├── src/dbot/
│ ├── main.py # Application entry point
│ ├── services.py # Core business logic
│ ├── repository.py # Redis state management
│ ├── connectors/ # Notification delivery
│ │ ├── router.py # Event routing
│ │ ├── webhooks/ # HTTP webhook delivery
│ │ └── rqueue/ # Redis queue delivery
│ ├── dscrd/ # Discord client wrapper
│ ├── model/ # Domain models
│ ├── config_loader/ # JSON configuration
│ └── infrastructure/ # Logging, monitoring, config
├── tests/
│ ├── unit/ # Fast, isolated tests
│ └── integration/ # Tests with real dependencies
├── helm/ # Kubernetes deployment
└── .github/workflows/ # CI/CD pipelines
Issue: Bot crashes on startup
Solutions:
- Check Redis is running:
redis-cli ping - Verify Discord token is valid
- Check all environment variables are set
- Review logs for specific error
Issue: Events happening but no webhooks/messages
Solutions:
- Check channel ID is correct (Discord Developer Mode → Copy ID)
- Verify bot has permission to see voice channel
- Test webhook URL manually with curl
- Check Redis queue:
redis-cli LLEN dbot.events - Review bot logs for notification generation
Issue: Webhooks timing out or failing
Solutions:
- Check webhook endpoint is accessible
- Review Sentry for error details
- Verify template variables are correct
- Check webhook provider (Make.com, Zapier) is working
- Reduce webhook count if hitting rate limits
Issue: Bot consuming too much memory
Solutions:
- Reduce number of monitored channels
- Decrease polling frequency (adjust
check_intervalin code) - Check for Redis connection leaks
- Monitor with Prometheus metrics
Issue: Bot being rate-limited by Discord
Solutions:
- Increase
check_interval(default: 10 seconds) - Reduce number of monitored channels per instance
- Discord allows ~50 req/s, so max ~500 channels per instance at 10s interval
- Deploy multiple instances with separate bot tokens for more channels
For detailed notification formats, webhook templates, and Redis message schemas, see:
PAYLOADS.md - Complete notification reference with examples
Event Types:
new_user- Individual joins channeluser_left- Individual leaves channelusers_connected- First user(s) join empty channelusers_left- Last user leaves channel
Delivery Methods:
- Webhooks (HTTP GET with templated URLs)
- Redis queues (JSON messages via RPUSH)
Contributions welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and linters (
make test lint) - Commit with clear messages
- Push to your fork
- Open a Pull Request
Development Guidelines:
- Follow existing code style (Black, isort)
- Add tests for new features
- Update documentation
- Use type hints throughout
- Keep functions focused and small
This project is licensed under the MIT License - see the LICENSE.txt file for details.
Need Help? Open an issue on GitHub
Want to Contribute? Pull requests are welcome!