Bot Commands
Overview
Cross-platform custom command system. Users create commands in the dashboard, assign them to platforms, and bots execute them with template variable support, cooldowns, and automation triggers.
Command Types
| Type | Description |
|---|---|
| Text | Fixed text response |
| Template | Text with variables: {user}, {uptime}, {song}, {count}, {random:a,b,c} |
| Automation | Triggers an automation flow instead of sending text |
Platform Assignment
Each command has a platforms JSON array. When creating, user selects which platforms the command is active on via checkboxes. Discord commands support both slash commands and prefix commands (configurable per command).
Permission Levels
Hierarchical — higher includes lower:
broadcaster > moderator > vip > subscriber > follower > everyone
Each bot maps platform-specific user data to this hierarchy.
Cooldowns
Redis-based, per-command:
- Global:
lumio:cmd_cd:{account_id}:{command_name}:global(TTL = cooldown seconds) - Per-user:
lumio:cmd_cd:{account_id}:{command_name}:user:{user_id}(TTL = cooldown seconds)
Template Variables
Extensible via VariableResolver trait in crates/lo-bot-commands/:
| Variable | Feature Gate | Description |
|---|---|---|
{user} | — | Display name of invoker |
{channel} | — | Channel/server name |
{platform} | — | Platform name |
{uptime} | — | Stream uptime (from Redis cache) |
{song} | widget:spotify_now_playing | Currently playing Spotify track |
{count} | — | Command use count |
{random:a,b,c} | — | Random selection from list |
Adding new variables: implement VariableResolver trait + register in VariableRegistry.
Global Commands & Overrides
- Global commands:
account_id IS NULL, created by admins, inherited by all accounts - Account commands:
account_idset, owned by specific account - Overrides: Accounts can override global commands (customize response, platforms, cooldowns) or disable them
- Shadowing: Account commands with same name as globals take priority
- Security: Overrides cannot make
min_roleless restrictive than global
Database
bot_commands— command definitions (global + account-scoped)bot_command_overrides— per-account overrides of global commandsbot_command_stats— usage statistics (Redis live counter, periodic DB flush)
Shared Crate: lo-bot-commands
Used by all 5 bots:
context.rs—CommandExecutionContext,UserRole,ApiCallback,CommandApiProviderregistry.rs—LoadedCommand,AccountCommands,execute_commandpermission.rs— Role hierarchy + checkingcooldown.rs— Redis cooldown check/set/incrementtemplate.rs—{variable}parser with right-to-left replacementvariables.rs—VariableResolvertrait,VariableRegistry, 7 built-in resolvers
Bot Integration
All 5 bots (Twitch, YouTube, Kick, Trovo, Discord):
- Load commands per account via
botCommandsForAccount(accountId, platform)system query - Store in-memory
CommandStore(HashMap<AccountId, AccountCommands>) - On chat message: check dynamic commands → permission → cooldown → execute
command_syncRedis action triggers reload- Discord: also registers slash commands per guild (bulk overwrite, 200/day rate limit)
API
| Type | Endpoint | Permission |
|---|---|---|
| GraphQL Query | botCommands | bot-commands:read |
| GraphQL Mutation | createBotCommand(input) | bot-commands:create |
| GraphQL Mutation | updateBotCommand(id, input) | bot-commands:edit |
| GraphQL Mutation | deleteBotCommand(id) | bot-commands:delete |
| GraphQL Mutation | overrideGlobalCommand(commandId, input) | bot-commands:edit |
| GraphQL Mutation | removeGlobalCommandOverride(commandId) | bot-commands:delete |
| System Query | botCommandsForAccount(accountId, platform) | System key only |
REST Endpoints
All paths live under /v1 and mirror the GraphQL mutations.
| Method | Path | Permission | Description |
|---|---|---|---|
GET | /v1/bot-commands | bot-commands:read | List account commands (+ inherited globals) |
POST | /v1/bot-commands | bot-commands:create | Create an account command |
PUT | /v1/bot-commands/{id} | bot-commands:edit | Update a command |
DELETE | /v1/bot-commands/{id} | bot-commands:delete | Delete a command |
POST | /v1/bot-commands/{id}/override | bot-commands:edit | Override a global command for the account |
DELETE | /v1/bot-commands/{id}/override | bot-commands:delete | Remove the account's override of a global command |
Plan Limits
| Tier | Max Commands |
|---|---|
| Free | 25 |
| Pro | 200 |
| Enterprise | Unlimited |
RBAC Permissions
Account: bot-commands:read/create/edit/delete
Admin: bot-commands:read/create/edit/delete (via require_admin_permission)
Key Files
| Path | Description |
|---|---|
crates/lo-bot-commands/ | Shared command execution crate (context, registry, permission, cooldown, template, variables) |
apps/api/src/db/bot_commands.rs | Database operations |
apps/api/src/graphql/bot_commands.rs | GraphQL queries and mutations |
apps/api/src/rest/bot_commands.rs | REST endpoints |
See Also
- Bot Control — Bot pause/resume/reconnect dashboard
- Bot Connections — Custom bot identity OAuth flow
- Bot Modules — Chat moderation modules
- Automations — Automation flows triggered by commands