Configuration System - openguard-bot/openguard GitHub Wiki
Configuration System
AIMod features a comprehensive configuration system that allows fine-grained control over bot behavior at guild, channel, and user levels. This document covers all configuration options, management interfaces, and best practices.
🔧 Configuration Architecture
Hierarchical Configuration
AIMod uses a hierarchical configuration system:
Global Defaults
↓
Guild Configuration
↓
Channel-Specific Rules
↓
User-Specific Overrides
Storage Backend
Database Storage:
-- Guild configuration table
CREATE TABLE guild_config (
guild_id BIGINT NOT NULL,
key VARCHAR(255) NOT NULL,
value JSONB,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (guild_id, key)
);
Caching Layer:
- Redis Cache: 5-minute TTL for frequently accessed settings
- In-Memory Cache: Hot configuration data
- Write-Through: Immediate cache updates on configuration changes
Configuration Manager
# cogs/aimod_helpers/config_manager.py
async def get_guild_config_async(guild_id: int, key: str, default=None):
"""Get guild configuration with caching."""
cache_key = f"guild_config:{guild_id}:{key}"
# Check cache first
cached_value = await get_cache(cache_key)
if cached_value is not None:
return json.loads(cached_value)
# Query database
async with get_connection() as conn:
result = await conn.fetchval(
"SELECT value FROM guild_config WHERE guild_id = $1 AND key = $2",
guild_id, key
)
if result is not None:
value = json.loads(result) if isinstance(result, str) else result
await set_cache(cache_key, json.dumps(value), ttl=300)
return value
return default
async def set_guild_config(guild_id: int, key: str, value):
"""Set guild configuration with cache invalidation."""
async with get_connection() as conn:
await conn.execute("""
INSERT INTO guild_config (guild_id, key, value, updated_at)
VALUES ($1, $2, $3, CURRENT_TIMESTAMP)
ON CONFLICT (guild_id, key)
DO UPDATE SET value = $3, updated_at = CURRENT_TIMESTAMP
""", guild_id, key, json.dumps(value))
# Update cache
cache_key = f"guild_config:{guild_id}:{key}"
await set_cache(cache_key, json.dumps(value), ttl=300)
⚙️ Core Configuration Options
General Settings
ENABLED
(Boolean)
- Default:
True
- Description: Master switch for AI moderation
- Usage:
/config setting:enabled value:false
PREFIX
(String)
- Default:
"!"
- Description: Command prefix for the bot
- Validation: 1-3 characters, no spaces
- Usage:
/prefix new_prefix:?
AI_MODEL
(String)
- Default:
"github_copilot/gpt-4.1"
- Description: AI model to use for moderation
- Options:
github_copilot/gpt-4.1
- GitHub Copilot (recommended)openai/gpt-4
- OpenAI GPT-4anthropic/claude-3
- Anthropic Claudegoogle/gemini-pro
- Google Gemini
- Usage:
/aimodel model:openai/gpt-4
RULES_TEXT
(String)
- Default:
""
- Description: Server rules provided to AI for context
- Max Length: 5000 characters
- Usage:
/config setting:rules_text value:"1. Be respectful..."
AI Moderation Settings
CONFIDENCE_THRESHOLD
(Integer)
- Default:
70
- Range: 0-100
- Description: Minimum confidence score for AI actions
- Usage:
/config setting:confidence_threshold value:80
AUTO_TIMEOUT_ENABLED
(Boolean)
- Default:
True
- Description: Enable automatic timeouts for violations
- Usage:
/config setting:auto_timeout_enabled value:true
TIMEOUT_DURATION
(Integer)
- Default:
3600
(1 hour) - Description: Default timeout duration in seconds
- Range: 60-2419200 (1 minute to 28 days)
- Usage:
/config setting:timeout_duration value:7200
AUTO_BAN_ENABLED
(Boolean)
- Default:
False
- Description: Enable automatic bans for severe violations
- Usage:
/config setting:auto_ban_enabled value:true
BAN_THRESHOLD
(Integer)
- Default:
3
- Description: Number of infractions before automatic ban
- Range: 1-10
- Usage:
/config setting:ban_threshold value:5
DELETE_MESSAGES
(Boolean)
- Default:
True
- Description: Delete violating messages
- Usage:
/config setting:delete_messages value:false
Channel Configuration
AI_EXCLUDED_CHANNELS
(Array)
- Default:
[]
- Description: Channels excluded from AI moderation
- Format: Array of channel IDs
- Usage:
/aichannel exclude channel:#general
AI_CHANNEL_RULES
(Object)
- Default:
{}
- Description: Channel-specific rules override
- Format:
{channel_id: "custom rules"}
- Usage:
/aichannel setrules channel:#memes rules:"Be more lenient with humor"
Security Settings
Bot Detection Configuration
BOTDETECT_CONFIG = {
"enabled": False,
"keywords": [
"discord.gg/",
"free nitro",
"click here",
"dm me for",
"check my bio"
],
"action": "timeout",
"timeout_duration": 3600,
"log_channel": None,
"whitelist_roles": [],
"whitelist_users": []
}
Configuration Commands:
# Enable bot detection
/botdetect enabled:true
# Set action to ban
/botdetect action:ban
# Add keywords
/botdetect keywords:"new keyword,another keyword"
# Set whitelist roles
/botdetect whitelist_roles:@Moderator,@Trusted
Raid Defense Configuration
RAID_DEFENSE_CONFIG = {
"enabled": False,
"threshold": 10, # Members joining
"timeframe": 60, # In 60 seconds
"alert_channel": None,
"auto_action": "lockdown"
}
Configuration Commands:
# Enable raid defense
/raiddefense enabled:true threshold:5 timeframe:30
# Set alert channel
/raiddefense alert_channel:#alerts
# Configure auto action
/raiddefense auto_action:ban
Logging Configuration
LOG_CHANNEL
(Channel ID)
- Default:
None
- Description: Channel for moderation logs
- Usage:
/logging channel:#mod-logs
WEBHOOK_URL
(String)
- Default:
None
- Description: Webhook URL for external logging
- Usage:
/modlog webhook_url:https://discord.com/api/webhooks/...
LOG_EVENTS
(Array)
- Default:
["ban", "kick", "timeout", "warn"]
- Description: Events to log
- Options:
ban
,kick
,timeout
,warn
,join
,leave
,message_delete
,role_change
- Usage:
/logging events:ban,kick,timeout,warn,join,leave
Message Rate Limiting
MESSAGE_RATE_CONFIG = {
"enabled": False,
"max_messages": 5,
"timeframe": 10, # seconds
"action": "timeout",
"timeout_duration": 300,
"whitelist_roles": [],
"escalation_enabled": True
}
🎛️ Configuration Interfaces
Discord Commands
/config
- General Configuration
@app_commands.describe(
setting="Configuration setting to view/modify",
value="New value for the setting (optional)"
)
async def config(
interaction: discord.Interaction,
setting: str,
value: str = None
):
"""View or modify guild configuration."""
if value is None:
# View current setting
current_value = await get_guild_config_async(
interaction.guild.id,
setting.upper()
)
await interaction.response.send_message(
f"**{setting}:** `{current_value}`"
)
else:
# Update setting
await set_guild_config(
interaction.guild.id,
setting.upper(),
parse_config_value(value)
)
await interaction.response.send_message(
f"✅ Updated **{setting}** to `{value}`"
)
/configlist
- List All Settings
async def configlist(interaction: discord.Interaction):
"""Display all current configuration settings."""
config_keys = [
"ENABLED", "PREFIX", "AI_MODEL", "RULES_TEXT",
"CONFIDENCE_THRESHOLD", "AUTO_TIMEOUT_ENABLED",
"TIMEOUT_DURATION", "AUTO_BAN_ENABLED", "BAN_THRESHOLD"
]
embed = discord.Embed(
title="🔧 Guild Configuration",
color=discord.Color.blue()
)
for key in config_keys:
value = await get_guild_config_async(interaction.guild.id, key)
embed.add_field(
name=key.replace("_", " ").title(),
value=f"`{value}`",
inline=True
)
await interaction.response.send_message(embed=embed)
Web Dashboard
The web dashboard provides a user-friendly interface for configuration:
Configuration Sections:
- General Settings - Basic bot configuration
- AI Moderation - AI-specific settings
- Security Features - Bot detection and raid defense
- Logging & Analytics - Event logging configuration
- Channel Management - Channel-specific rules
- User Management - User permissions and overrides
Dashboard Features:
- Real-time validation of configuration values
- Bulk configuration import/export
- Configuration templates for common setups
- Change history and rollback capabilities
- Permission-based access control
API Endpoints
Get Guild Configuration
@router.get("/guilds/{guild_id}/config")
async def get_guild_config(guild_id: int):
"""Get comprehensive guild configuration."""
config = {
"general": {
"enabled": await get_guild_config_async(guild_id, "ENABLED", True),
"prefix": await get_guild_config_async(guild_id, "PREFIX", "!"),
"ai_model": await get_guild_config_async(guild_id, "AI_MODEL", DEFAULT_AI_MODEL)
},
"moderation": {
"confidence_threshold": await get_guild_config_async(guild_id, "CONFIDENCE_THRESHOLD", 70),
"auto_timeout_enabled": await get_guild_config_async(guild_id, "AUTO_TIMEOUT_ENABLED", True),
"timeout_duration": await get_guild_config_async(guild_id, "TIMEOUT_DURATION", 3600)
},
"security": {
"botdetect": await get_botdetect_config(guild_id),
"raid_defense": await get_raid_defense_config(guild_id)
}
}
return config
Update Guild Configuration
@router.put("/guilds/{guild_id}/config")
async def update_guild_config(
guild_id: int,
config: schemas.GuildConfigUpdate
):
"""Update guild configuration."""
# Validate permissions
if not await has_admin_permissions(guild_id, current_user):
raise HTTPException(status_code=403, detail="Insufficient permissions")
# Update configuration
for key, value in config.dict(exclude_unset=True).items():
await set_guild_config(guild_id, key.upper(), value)
# Invalidate related caches
await invalidate_guild_cache(guild_id)
return {"status": "success", "updated": len(config.dict(exclude_unset=True))}
🔄 Configuration Migration
Version Migration
When configuration schema changes, migration scripts handle updates:
async def migrate_config_v1_to_v2(guild_id: int):
"""Migrate configuration from v1 to v2 format."""
# Get old configuration
old_config = await get_guild_config_async(guild_id, "CONFIG_V1")
if old_config:
# Transform to new format
new_config = {
"ENABLED": old_config.get("ai_enabled", True),
"AI_MODEL": old_config.get("model", DEFAULT_AI_MODEL),
"CONFIDENCE_THRESHOLD": old_config.get("threshold", 70)
}
# Set new configuration
for key, value in new_config.items():
await set_guild_config(guild_id, key, value)
# Remove old configuration
await delete_guild_config(guild_id, "CONFIG_V1")
Backup and Restore
async def backup_guild_config(guild_id: int) -> dict:
"""Create a backup of guild configuration."""
async with get_connection() as conn:
rows = await conn.fetch(
"SELECT key, value FROM guild_config WHERE guild_id = $1",
guild_id
)
return {
"guild_id": guild_id,
"timestamp": datetime.utcnow().isoformat(),
"config": {row["key"]: json.loads(row["value"]) for row in rows}
}
async def restore_guild_config(backup: dict):
"""Restore guild configuration from backup."""
guild_id = backup["guild_id"]
config = backup["config"]
for key, value in config.items():
await set_guild_config(guild_id, key, value)
🛡️ Configuration Security
Validation
All configuration values are validated before storage:
def validate_config_value(key: str, value: any) -> any:
"""Validate configuration value."""
validators = {
"CONFIDENCE_THRESHOLD": lambda v: 0 <= int(v) <= 100,
"TIMEOUT_DURATION": lambda v: 60 <= int(v) <= 2419200,
"PREFIX": lambda v: 1 <= len(str(v)) <= 3,
"AI_MODEL": lambda v: v in ALLOWED_AI_MODELS
}
if key in validators:
if not validators[key](value):
raise ValueError(f"Invalid value for {key}: {value}")
return value
Access Control
Configuration access is controlled by Discord permissions:
async def check_config_permissions(interaction: discord.Interaction) -> bool:
"""Check if user can modify configuration."""
# Bot owners can always modify
if interaction.user.id in BOT_OWNER_IDS:
return True
# Guild administrators can modify guild config
if interaction.user.guild_permissions.administrator:
return True
# Check for specific config role
config_role_id = await get_guild_config_async(
interaction.guild.id,
"CONFIG_ROLE_ID"
)
if config_role_id:
return any(role.id == config_role_id for role in interaction.user.roles)
return False
Audit Logging
All configuration changes are logged:
async def log_config_change(
guild_id: int,
user_id: int,
key: str,
old_value: any,
new_value: any
):
"""Log configuration change."""
await insert_audit_log({
"guild_id": guild_id,
"user_id": user_id,
"action": "CONFIG_CHANGE",
"details": {
"key": key,
"old_value": old_value,
"new_value": new_value
},
"timestamp": datetime.utcnow()
})
Next: Security Features - Bot detection, raid defense, and security mechanisms