Configuration Guide¶
This guide covers all configuration options available in aiogram-cmds, from simple settings to advanced configurations.
π Overview¶
aiogram-cmds supports three configuration approaches:
- Auto-Setup: Zero configuration, works out of the box
- Simple Mode: Settings-based configuration with policies
- Advanced Mode: Full control with profiles, scopes, and custom resolvers
π Auto-Setup Configuration¶
The simplest way to get started - no configuration required:
from aiogram_cmds.auto_setup import setup_commands_auto
# Automatically set up with sensible defaults
manager = await setup_commands_auto(bot)
Default Configuration:
- Languages: ["en"]
- Commands: ["start", "help", "cancel"]
- Profiles: guest (includes start, help), user (includes start, help, cancel)
- Scopes: all_private_chats with guest profile
- Menu button: commands
βοΈ Simple Mode Configuration¶
CmdsSettings¶
Use CmdsSettings for basic configuration:
from aiogram_cmds import CmdsSettings, CommandScopeManager
settings = CmdsSettings(
languages=["en", "ru", "es"],
fallback_language="en",
i18n_key_prefix="cmd",
profile="default",
menu_button="commands"
)
manager = CommandScopeManager(bot, settings=settings)
Configuration Fields¶
| Field | Type | Default | Description |
|---|---|---|---|
languages |
List[str] |
["en"] |
Supported language codes |
fallback_language |
str |
"en" |
Fallback language for missing translations |
i18n_key_prefix |
str |
"cmd" |
Prefix for i18n translation keys |
profile |
str |
"default" |
Default profile name |
menu_button |
str |
"commands" |
Menu button mode ("commands" or "default") |
Loading from pyproject.toml¶
Create pyproject.toml:
[tool.aiogram_cmds]
languages = ["en", "ru", "es"]
fallback_language = "en"
i18n_key_prefix = "cmd"
profile = "default"
menu_button = "commands"
Load in your code:
from aiogram_cmds import load_settings
settings = load_settings() # Loads from pyproject.toml
manager = CommandScopeManager(bot, settings=settings)
ποΈ Advanced Mode Configuration¶
CmdsConfig¶
Full control with CmdsConfig:
from aiogram_cmds import CmdsConfig, CommandDef, ProfileDef, ScopeDef, MenuButtonDef
config = CmdsConfig(
languages=["en", "ru", "es"],
fallback_language="en",
i18n_key_prefix="cmd",
commands={
"start": CommandDef(i18n_key="start.desc"),
"help": CommandDef(i18n_key="help.desc"),
"profile": CommandDef(i18n_key="profile.desc"),
},
profiles={
"guest": ProfileDef(include=["start", "help"]),
"user": ProfileDef(include=["start", "help", "profile"]),
},
scopes=[
ScopeDef(scope="all_private_chats", profile="guest"),
],
menu_button=MenuButtonDef(mode="commands"),
)
manager = CommandScopeManager(bot, config=config)
Command Definitions¶
CommandDef¶
Define individual commands:
# Using i18n key
start_cmd = CommandDef(i18n_key="start.desc")
# Using inline descriptions
help_cmd = CommandDef(descriptions={
"en": "Show help information",
"ru": "ΠΠΎΠΊΠ°Π·Π°ΡΡ ΡΠΏΡΠ°Π²ΠΊΡ",
"es": "Mostrar ayuda"
})
# Using both (i18n takes precedence)
profile_cmd = CommandDef(
i18n_key="profile.desc",
descriptions={"en": "View your profile"},
tags=["user", "profile"]
)
Fields:
- i18n_key (str, optional): i18n key for command description
- descriptions (Dict[str, str]): Inline descriptions by language
- tags (List[str]): Command tags for organization
Description Resolution Order¶
- i18n_key with translator (if available)
- Inline descriptions for specific language
- Fallback to Title Case of command name
Profile Definitions¶
ProfileDef¶
Define user profiles:
# Basic profile
guest_profile = ProfileDef(include=["start", "help"])
# Profile with exclusions
admin_profile = ProfileDef(
include=["start", "help", "profile", "admin", "settings"],
exclude=["settings"] # Remove settings from admin profile
)
# Complex profile
vip_profile = ProfileDef(
include=["start", "help", "profile", "vip_offers", "premium_support"],
exclude=["basic_features"]
)
Fields:
- include (List[str]): Commands to include in this profile
- exclude (List[str]): Commands to exclude from this profile
Logic:
1. Start with all commands from include list
2. Remove any commands that exist in exclude list
3. Only include commands that are defined in the commands registry
Scope Definitions¶
ScopeDef¶
Define command scopes:
# Global scope
default_scope = ScopeDef(scope="all_private_chats", profile="guest")
# Chat-specific scope
admin_chat_scope = ScopeDef(
scope="chat",
chat_id=12345,
profile="admin",
languages=["en", "ru"]
)
# User-specific scope
vip_user_scope = ScopeDef(
scope="chat_member",
chat_id=12345,
user_id=67890,
profile="vip"
)
Fields:
- scope (ScopeType): Telegram command scope type
- profile (str): Profile name to apply
- chat_id (int, optional): Chat ID for chat-specific scopes
- user_id (int, optional): User ID for user-specific scopes
- languages (List[str]): Languages for this scope (empty = use global)
Scope Types¶
ScopeType = Literal[
"default", # Global default
"all_private_chats", # All private chats
"all_group_chats", # All group chats
"all_chat_admins", # All chat administrators
"chat", # Specific chat
"chat_admins", # Administrators in specific chat
"chat_member", # Specific user in specific chat
]
Scope Hierarchy¶
Scopes are applied in order of specificity (most specific first):
- chat_member - Specific user in specific chat
- chat_admins - All admins in specific chat
- chat - All users in specific chat
- all_chat_admins - All chat administrators globally
- all_group_chats - All group chats
- all_private_chats - All private chats
- default - Global fallback
Menu Button Configuration¶
MenuButtonDef¶
Configure the menu button:
# Enable commands menu button
menu_button = MenuButtonDef(mode="commands")
# Use default menu button
menu_button = MenuButtonDef(mode="default")
Fields:
- mode (str): Menu button mode ("commands" or "default")
π§ Profile Resolvers¶
Simple Profile Resolver¶
from aiogram_cmds import ProfileResolver, Flags
def simple_profile_resolver(flags: Flags) -> str:
if flags.is_registered:
return "user"
return "guest"
manager = CommandScopeManager(bot, profile_resolver=simple_profile_resolver)
Advanced Profile Resolver¶
def advanced_profile_resolver(flags: Flags) -> str:
user_id = getattr(flags, 'user_id', None)
if not user_id:
return "guest"
# Get user data from database
user_data = get_user_from_database(user_id)
if user_data.get("banned", False):
return "banned"
elif user_data.get("admin", False):
return "admin"
elif user_data.get("premium", False):
return "premium"
elif user_data.get("registered", False):
return "user"
return "guest"
manager = CommandScopeManager(bot, profile_resolver=advanced_profile_resolver)
Context-Aware Resolver¶
def context_aware_resolver(flags: Flags) -> str:
user_id = getattr(flags, 'user_id', None)
chat_id = getattr(flags, 'chat_id', None)
if not user_id:
return "guest"
# Check user status
user_data = get_user_from_database(user_id)
# Check chat-specific permissions
if chat_id:
chat_permissions = get_chat_permissions(user_id, chat_id)
if chat_permissions.get("admin", False):
return "chat_admin"
elif chat_permissions.get("moderator", False):
return "chat_moderator"
# Standard profile logic
if user_data.get("banned", False):
return "banned"
elif user_data.get("admin", False):
return "admin"
elif user_data.get("premium", False):
return "premium"
elif user_data.get("registered", False):
return "user"
return "guest"
π i18n Configuration¶
Basic i18n Setup¶
from aiogram_cmds import build_translator_from_i18n
# With aiogram i18n
translator = build_translator_from_i18n(i18n_instance)
manager = CommandScopeManager(bot, translator=translator)
Custom Translator¶
def custom_translator(key: str, *, locale: str) -> str:
translations = {
"en": {
"cmd.start.desc": "Start the bot",
"cmd.help.desc": "Show help information",
},
"ru": {
"cmd.start.desc": "ΠΠ°ΠΏΡΡΡΠΈΡΡ Π±ΠΎΡΠ°",
"cmd.help.desc": "ΠΠΎΠΊΠ°Π·Π°ΡΡ ΡΠΏΡΠ°Π²ΠΊΡ",
}
}
return translations.get(locale, {}).get(key)
manager = CommandScopeManager(bot, translator=custom_translator)
Translation Key Patterns¶
Default Pattern¶
Example: cmd.start.desc β "Start the bot"
Custom Patterns¶
commands = {
"start": CommandDef(i18n_key="commands.start.description"),
"help": CommandDef(i18n_key="menu.help.tooltip"),
"admin": CommandDef(i18n_key="admin.panel.commands.open"),
}
π Configuration Examples¶
E-commerce Bot¶
config = CmdsConfig(
languages=["en", "ru"],
commands={
"start": CommandDef(i18n_key="start.desc"),
"catalog": CommandDef(i18n_key="catalog.desc"),
"cart": CommandDef(i18n_key="cart.desc"),
"orders": CommandDef(i18n_key="orders.desc"),
"vip_offers": CommandDef(i18n_key="vip_offers.desc"),
"help": CommandDef(i18n_key="help.desc"),
},
profiles={
"visitor": ProfileDef(include=["start", "catalog", "help"]),
"customer": ProfileDef(include=["start", "catalog", "cart", "orders", "help"]),
"vip": ProfileDef(include=["start", "catalog", "cart", "orders", "vip_offers", "help"]),
},
scopes=[
ScopeDef(scope="all_private_chats", profile="visitor"),
],
)
Admin Bot¶
config = CmdsConfig(
languages=["en"],
commands={
"start": CommandDef(i18n_key="start.desc"),
"help": CommandDef(i18n_key="help.desc"),
"profile": CommandDef(i18n_key="profile.desc"),
"admin": CommandDef(i18n_key="admin.desc"),
"ban": CommandDef(i18n_key="ban.desc"),
"unban": CommandDef(i18n_key="unban.desc"),
},
profiles={
"user": ProfileDef(include=["start", "help", "profile"]),
"admin": ProfileDef(include=["start", "help", "profile", "admin", "ban", "unban"]),
},
scopes=[
ScopeDef(scope="all_private_chats", profile="user"),
ScopeDef(scope="chat", chat_id=admin_chat_id, profile="admin"),
],
)
Multi-Language Bot¶
config = CmdsConfig(
languages=["en", "ru", "es", "fr"],
fallback_language="en",
commands={
"start": CommandDef(i18n_key="commands.start"),
"help": CommandDef(i18n_key="commands.help"),
"language": CommandDef(i18n_key="commands.language"),
},
profiles={
"default": ProfileDef(include=["start", "help", "language"]),
},
scopes=[
ScopeDef(scope="all_private_chats", profile="default"),
],
)
π Configuration Validation¶
Pydantic Validation¶
All configuration models use Pydantic for validation:
# This will raise ValidationError
invalid_config = CmdsConfig(
languages=[], # Empty languages list
fallback_language="invalid", # Not in languages list
)
Common Validation Errors¶
Empty Languages List¶
Invalid Fallback Language¶
# β Invalid
config = CmdsConfig(
languages=["en", "ru"],
fallback_language="es" # Not in languages list
)
# β
Valid
config = CmdsConfig(
languages=["en", "ru"],
fallback_language="en" # In languages list
)
Undefined Profile Reference¶
# β Invalid
config = CmdsConfig(
profiles={"user": ProfileDef(include=["start"])},
scopes=[ScopeDef(scope="all_private_chats", profile="admin")] # Profile not defined
)
# β
Valid
config = CmdsConfig(
profiles={"user": ProfileDef(include=["start"])},
scopes=[ScopeDef(scope="all_private_chats", profile="user")]
)
π¨ Best Practices¶
1. Use Consistent Naming¶
# β
Good - Consistent naming
profiles = {
"guest": ProfileDef(include=["start", "help"]),
"user": ProfileDef(include=["start", "help", "profile"]),
"admin": ProfileDef(include=["start", "help", "profile", "admin"]),
}
# β Avoid - Inconsistent naming
profiles = {
"basic": ProfileDef(include=["start"]),
"advanced": ProfileDef(include=["start", "help", "profile", "admin"]),
}
2. Organize Commands Logically¶
# β
Good - Logical organization
commands = {
# Basic commands
"start": CommandDef(i18n_key="start.desc"),
"help": CommandDef(i18n_key="help.desc"),
# User commands
"profile": CommandDef(i18n_key="profile.desc"),
"settings": CommandDef(i18n_key="settings.desc"),
# Admin commands
"admin": CommandDef(i18n_key="admin.desc"),
"ban": CommandDef(i18n_key="ban.desc"),
}
3. Use Appropriate Scopes¶
# β
Good - Specific scopes for specific needs
scopes = [
ScopeDef(scope="all_private_chats", profile="user"),
ScopeDef(scope="chat", chat_id=admin_chat_id, profile="admin"),
]
# β Avoid - Overly broad scopes
scopes = [
ScopeDef(scope="default", profile="admin"), # Too broad
]
4. Validate Configuration¶
# β
Good - Validate configuration
try:
config = CmdsConfig.model_validate(config_data)
except ValidationError as e:
logger.error(f"Invalid configuration: {e}")
return
5. Use i18n Keys¶
# β
Good - Uses i18n keys
commands = {
"start": CommandDef(i18n_key="commands.start.description"),
"help": CommandDef(i18n_key="commands.help.description"),
}
# β Avoid - Hardcoded descriptions
commands = {
"start": CommandDef(descriptions={"en": "Start the bot"}),
"help": CommandDef(descriptions={"en": "Show help"}),
}
π§ Configuration Loading¶
From pyproject.toml¶
[tool.aiogram_cmds]
languages = ["en", "ru", "es"]
fallback_language = "en"
i18n_key_prefix = "cmd"
profile = "default"
menu_button = "commands"
From JSON¶
import json
from aiogram_cmds import CmdsConfig
with open("config.json") as f:
data = json.load(f)
config = CmdsConfig.model_validate(data)
From YAML¶
import yaml
from aiogram_cmds import CmdsConfig
with open("config.yaml") as f:
data = yaml.safe_load(f)
config = CmdsConfig.model_validate(data)
From Environment Variables¶
import os
from aiogram_cmds import CmdsConfig
config = CmdsConfig(
languages=os.getenv("BOT_LANGUAGES", "en").split(","),
fallback_language=os.getenv("BOT_FALLBACK_LANGUAGE", "en"),
i18n_key_prefix=os.getenv("BOT_I18N_PREFIX", "cmd"),
)
π― Configuration Tips¶
- Start with auto-setup, then customize as needed
- Use configuration files for persistent settings
- Validate all configurations before use
- Use consistent naming conventions
- Organize commands and profiles logically
- Test all configuration combinations
- Use i18n keys for multi-language support
- Implement proper error handling for configuration loading
For more information about using configurations, see: - Quickstart Guide - Getting started with configurations - API Reference - Detailed API documentation - Tutorials - Step-by-step configuration guides