Skip to main content

Bot Control

Overview​

The Connections group of the settings window shows bot control in the Chat bot section of the Twitch, YouTube and Kick areas. Discord server status and connection actions appear in the Discord area. The Overview lists bots and servers that need attention.

Chat Bot Control​

Per-platform bot management in the platform's area of the settings window (/dashboard/settings/channel/connections/{platform}):

  • Status: in chat, paused, offline, disconnected or waiting for a channel.
  • Pause / resume: toggleBotForPlatform updates channel_connections.bot_enabled.
  • Re-enter chat: rejoinBot sends a bot_join action via Redis pub/sub to trigger an immediate channel rejoin. This does not renew OAuth.
  • Reconnect bot: a disconnected own bot repeats its OAuth grant on the same platform tab.

Database​

channel_connections.bot_enabled (BOOLEAN, default true) - when false, bots ignore this channel during sync.

API​

TypeEndpointPermission
GraphQL QuerybotStatusbot-connections:read
GraphQL MutationtoggleBotForPlatform(platform, enabled)bot-connections:create
GraphQL MutationrejoinBot(platform)bot-connections:create
RESTGET /v1/bot-statusbot-connections:read
RESTPOST /v1/bot-togglebot-connections:create
RESTPOST /v1/bot-rejoinbot-connections:create
System QuerybotChannels(platform)System key with bots:internal

Bot Worker Actions​

All chat bots listen for Redis pub/sub actions on lumio:bot:action:{platform}:{account_id}:

  • bot_join / bot_sync - Refresh the Discord guild map immediately; other bot workers apply their own sync behavior
  • bot_leave - Immediately remove account's channels from in-memory map + clear Redis cache
  • guild_leave (Discord only, data.guild_id) - Published when an account disconnects a Discord server. The bot re-syncs its guild map and leaves the server unless it is mapped again (reconnect or takeover); without a fresh map it stays

Discord Server Mapping​

Discord guilds are mapped to Lumio accounts via discord_guild_connections table.

Tables​

  • discord_guild_connections - guild_id → account_id mapping (UNIQUE on guild_id)
  • discord_guild_settings - per-guild JSONB settings
  • discord_guild_channel_mappings - feature → Discord channel routing (live_notification, event_feed, chat_mirror, etc.)

Server connection​

The Discord area (/dashboard/settings/channel/connections/discord) shows each server's status. Add server and Reconnect start authorizeBot(platform: "discord") through /api/connections/bot/discord/authorize. Discord returns to /api/connections/oauth/discord/callback; the unified exchange redeems the code and takes the server ID from Discord's token response. After verification it links the server to the account, returns to the Discord area and notifies the running bot to refresh its guild map. A Discord user token is revoked after that one-time check and is never stored. The equivalent REST authorize endpoint is GET /v1/bot-connections/discord/authorize; the old /v1/discord-guilds/exchange route is not part of this flow.

The server's status is Connected, Bot removed, or Permissions missing. Removal on Discord marks the connection while preserving its settings; reconnecting clears the mark. Disconnect removes the mapping and its server settings, and the bot leaves the server.

Redis Cache​

KeyContentTTL
lumio:discord_guild:{guild_id}account_id1h
lumio:discord_guild:{guild_id}:channelsJSON array of the channels the bot can view (VIEW_CHANNEL)1h
lumio:discord_guild:{guild_id}:rolesJSON array of roles1h
lumio:discord_guild:{guild_id}:featuresJSON array of feature mappings1h
lumio:discord_channel_guild:{channel_id}guild_id (reverse lookup)1h

Feature-Channel Mappings​

The catalogue is the DISCORD_FEATURES const in apps/api/src/graphql/discord_guilds.rs - adding one is a code change, not a database migration. setDiscordGuildFeature rejects any key not in the list:

Feature KeyDescription
live_notificationStream live alerts
event_feedFollows, subs, donations
chat_mirrorPlatform chat → Discord
announcementAnnouncements
moderation_logBan/timeout logs
clip_feedNew clips

API​

TypeEndpointPermission
GraphQL QuerydiscordGuildConnectionsbot-connections:read
GraphQL MutationauthorizeBot(platform: "discord")bot-connections:create, interactive session and feature:bots
GraphQL MutationdisconnectDiscordGuild(guildId)bot-connections:delete
GraphQL QuerydiscordGuildChannels(guildId)bot-connections:read
GraphQL QuerydiscordGuildRoles(guildId)bot-connections:read
GraphQL QuerydiscordGuildFeatures(guildId)bot-connections:read
GraphQL MutationsetDiscordGuildFeature(...)bot-connections:create
System QuerydiscordBotGuildsSystem key with bots:internal
System MutationupdateDiscordGuildInfo(...)System key with bots:internal
System MutationremoveDiscordGuildByBot(guildId: String!)System key with bots:internal
RESTGET /v1/bot-connections/discord/authorizebot-connections:create, interactive session and feature:bots
RESTGET /v1/discord-guilds, DELETE /v1/discord-guilds/{guild_id}bot-connections:read / bot-connections:delete

Admin​

Admin permissions: bot-control:read/edit, discord-guilds:read/delete (enforced via require_admin_permission).

  • /admin/bot-control - View/toggle bots per account. REST: GET /v1/admin/bot-control/statuses, PUT /v1/admin/bot-control/{account_id}/{platform}.
  • /admin/discord-guilds - View all guild-to-account mappings, delete connections. REST: GET /v1/admin/discord-guilds, DELETE /v1/admin/discord-guilds/{guild_id}.

Feature Gating​

The Bot Control surface (bot_connections resolvers/routes - bot status, toggle, rejoin, authorize, delete) is gated on the feature:bots flag on both protocols (GraphQL FeatureGuard, REST require_feature). With feature:bots disabled the API rejects the call directly; the webapp route gate is UX only. See Bot Connections › Feature Flags for the full endpoint list.

Security​

  • Guild ownership verified before channel/role queries
  • Channel ownership verified in Discord bot actions (post_message)
  • GuildDelete with unavailable=true only cleans cache, preserves DB
  • Admin middleware on API routes
  • Snowflake validation on all Discord IDs
  • UUID validation on action listener account_id

Key Files​

PathDescription
apps/api/src/graphql/bot_connections.rsGraphQL queries and mutations for bot status/toggle/rejoin
apps/api/src/graphql/discord_guilds.rsGraphQL for Discord guild management
apps/api/src/db/discord_guilds.rsDatabase operations for Discord guilds
apps/discord-bot/src/handlers/events.rsDiscord bot gateway event handling
extensions/system/System extension manifests and handlers for built-in bot modules

See Also​