Add blocklist feature to automatically delete ALL media (images, GIFs, embeds, URLs) from specific users without AI analysis. Changes: - Add blocked_user_ids config field to config.yml - Implement blocklist check in ai_moderation.py (runs before AI checks) - Update README.md with blocklist documentation Benefits: - No AI cost (instant deletion) - Useful for known spam accounts or problematic users - Blocks all media types: attachments, embeds, URLs - Logged for moderation tracking
9.7 KiB
GuardDen
A lightweight, cost-conscious Discord moderation bot focused on essential protection. Built for self-hosting with minimal resource usage and AI costs.
Features
Spam Detection
- Anti-Spam - Rate limiting, duplicate detection, mass mention protection
- Automatic Actions - Message deletion and user timeout for spam violations
AI-Powered NSFW Image Detection
- Smart Image Analysis - AI-powered detection of inappropriate images using Claude or GPT
- Cost Controls - Conservative rate limits (25 checks/hour/guild by default)
- Embed Support - Optional checking of Discord GIF embeds
- NSFW Video Domain Blocking - Block known NSFW video domains
- Configurable Sensitivity - Adjust strictness (0-100)
Quick Start
Prerequisites
- Python 3.11+
- PostgreSQL 15+
- Discord Bot Token (see setup below)
- (Optional) Anthropic or OpenAI API key for AI features
Discord Bot Setup
-
Go to the Discord Developer Portal
-
Click New Application and give it a name (e.g., "GuardDen")
-
Go to the Bot tab and click Add Bot
-
Configure Bot Settings:
- Disable Public Bot if you only want yourself to add it
- Copy the Token (click "Reset Token") - this is your
GUARDDEN_DISCORD_TOKEN
-
Enable Privileged Gateway Intents (required):
- Message Content Intent - for reading messages (spam detection, image checking)
-
Generate Invite URL - Go to OAuth2 > URL Generator:
Scopes:
bot
Bot Permissions:
- Moderate Members (timeout)
- View Channels
- Send Messages
- Manage Messages
- Read Message History
Or use permission integer:
275415089216 -
Use the generated URL to invite the bot to your server
Docker Deployment (Recommended)
-
Clone the repository:
git clone https://git.hiddenden.cafe/Hiddenden/GuardDen.git cd guardden -
Create your environment file:
cp .env.example .env # Edit .env and add your Discord token -
Start with Docker Compose:
docker compose up -d
Local Development
-
Create a virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate -
Install dependencies:
pip install -e ".[dev,ai]" -
Set up environment variables:
cp .env.example .env # Edit .env with your configuration -
Start PostgreSQL (or use Docker):
docker compose up db -d -
Run the bot:
python -m guardden
Configuration
GuardDen uses a single YAML configuration file (config.yml) for managing all bot settings across all guilds.
Configuration File (config.yml)
Create a config.yml file in your project root:
bot:
prefix: "!"
owner_ids:
- 123456789012345678 # Your Discord user ID
# Spam detection settings
automod:
enabled: true
anti_spam_enabled: true
message_rate_limit: 5 # Max messages per window
message_rate_window: 5 # Window in seconds
duplicate_threshold: 3 # Duplicates to trigger
mention_limit: 5 # Max mentions per message
mention_rate_limit: 10 # Max mentions per window
mention_rate_window: 60 # Window in seconds
# AI moderation settings
ai_moderation:
enabled: true
sensitivity: 80 # 0-100 (higher = stricter)
nsfw_only_filtering: true # Only filter sexual content
max_checks_per_hour_per_guild: 25 # Cost control
max_checks_per_user_per_hour: 5 # Cost control
max_images_per_message: 2 # Analyze max 2 images/msg
max_image_size_mb: 3 # Skip images > 3MB
check_embed_images: true # Check Discord GIF embeds
check_video_thumbnails: false # Skip video thumbnails
url_image_check_enabled: false # Skip URL image downloads
# User blocklist (blocks ALL media from specific users)
blocked_user_ids:
- 123456789012345678 # Discord user ID to block
# Known NSFW video domains (auto-block)
nsfw_video_domains:
- pornhub.com
- xvideos.com
- xnxx.com
- redtube.com
- youporn.com
Key Configuration Options
AI Moderation (NSFW Image Detection):
sensitivity: 0-100 scale (higher = stricter detection)nsfw_only_filtering: Only flag sexual content (violence/harassment allowed)max_checks_per_hour_per_guild: Cost control - limits AI API callscheck_embed_images: Whether to analyze Discord GIF embeds
Spam Detection:
message_rate_limit: Max messages allowed per windowduplicate_threshold: How many duplicate messages trigger actionmention_limit: Max @mentions allowed per message
User Blocklist:
blocked_user_ids: List of Discord user IDs to block- Automatically deletes ALL images, GIFs, embeds, and URLs from these users
- No AI cost - instant deletion
- Useful for known problematic users or spam accounts
Cost Controls: The bot includes multiple layers of cost control:
- Rate limiting (25 AI checks/hour/guild, 5/hour/user by default)
- Image deduplication (tracks last 1000 analyzed messages)
- File size limits (skip images > 3MB)
- Max images per message (analyze max 2 images)
- Optional embed checking (disable to save costs)
Environment Variables
| Variable | Description | Default |
|---|---|---|
GUARDDEN_DISCORD_TOKEN |
Your Discord bot token | Required |
GUARDDEN_DATABASE_URL |
PostgreSQL connection URL | postgresql://guardden:guardden@localhost:5432/guardden |
GUARDDEN_LOG_LEVEL |
Logging level | INFO |
GUARDDEN_AI_PROVIDER |
AI provider (anthropic/openai/none) | none |
GUARDDEN_ANTHROPIC_API_KEY |
Anthropic API key (if using Claude) | - |
GUARDDEN_OPENAI_API_KEY |
OpenAI API key (if using GPT) | - |
Owner Commands
GuardDen includes a minimal set of owner-only commands for bot management:
| Command | Description |
|---|---|
!status |
Show bot status (uptime, guilds, latency, AI provider) |
!reload |
Reload all cogs |
!ping |
Check bot latency |
Note: All configuration is done via the config.yml file. There are no in-Discord configuration commands.
Project Structure
guardden/
├── src/guardden/
│ ├── bot.py # Main bot class
│ ├── config.py # Settings management
│ ├── cogs/ # Discord command groups
│ │ ├── automod.py # Spam detection
│ │ ├── ai_moderation.py # NSFW image detection
│ │ └── owner.py # Owner commands
│ ├── models/ # Database models
│ │ └── guild.py # Guild settings
│ ├── services/ # Business logic
│ │ ├── ai/ # AI provider implementations
│ │ ├── automod.py # Spam detection logic
│ │ ├── config_loader.py # YAML config loading
│ │ ├── ai_rate_limiter.py # AI cost control
│ │ ├── database.py # DB connections
│ │ └── guild_config.py # Config caching
│ └── __main__.py # Entry point
├── config.yml # Bot configuration
├── tests/ # Test suite
├── migrations/ # Database migrations
├── docker-compose.yml # Docker deployment
├── pyproject.toml # Dependencies
└── README.md # This file
How It Works
User Blocklist (Instant, No AI Cost)
- Checks if message author is in
blocked_user_idslist - If message contains ANY media (images, embeds, URLs), instantly deletes it
- No AI analysis needed - immediate action
- Useful for known spam accounts or problematic users
Spam Detection
- Bot monitors message rate per user
- Detects duplicate messages
- Counts @mentions (mass mention detection)
- Violations result in message deletion + timeout
NSFW Image Detection
- Checks user blocklist first (instant deletion if matched)
- Checks NSFW video domain blocklist (instant deletion)
- Bot checks attachments and embeds for images
- Applies rate limiting and deduplication
- Downloads image and sends to AI provider
- AI analyzes for NSFW content categories
- Violations result in message deletion + timeout
Cost Management
The bot includes aggressive cost controls for AI usage:
- Rate Limiting: 25 checks/hour/guild, 5/hour/user (configurable)
- Deduplication: Skips recently analyzed message IDs
- File Size Limits: Skips images larger than 3MB
- Max Images: Analyzes max 2 images per message
- Optional Features: Embed checking, video thumbnails, URL downloads all controllable
Estimated Costs (with defaults):
- Small server (< 100 users): ~$5-10/month
- Medium server (100-500 users): ~$15-25/month
- Large server (500+ users): Consider increasing rate limits or disabling embeds
Development
Running Tests
pytest
pytest -v # Verbose output
pytest tests/test_automod.py # Specific file
pytest -k "test_scam" # Filter by name
Code Quality
ruff check src tests # Linting
ruff format src tests # Formatting
mypy src # Type checking
License
MIT License - see LICENSE file for details.
Support
- Issues: Report bugs at https://github.com/anthropics/claude-code/issues
- Documentation: See
docs/directory - Configuration Help: Check
CLAUDE.mdfor developer guidance
Future Considerations
- Per-guild sensitivity settings (currently global)
- Slash commands
- Custom NSFW category thresholds
- Whitelist for trusted image sources