Bot Connections
Overview
Bot connections allow accounts to use custom bot identities instead of the global system bot. Each account can connect their own bot account via OAuth for any supported chat platform. The system supports both global bots (configured by admins) and per-account custom bots.
Global vs Custom Bots
- Global Bot: Configured by admins in the Provider Management page. All accounts use this bot by default.
- Custom Bot: Users connect their own bot account via OAuth. Takes priority over the global bot for that account.
Fallback Logic
Account has custom bot connection for platform?
-> YES: Use custom bot token
-> NO: Use global system bot token
Platforms
| Platform | Auth Type | Token Refresh |
|---|---|---|
| Twitch | OAuth2 | Yes (automatic) |
| YouTube | OAuth2 | Yes (automatic) |
| Kick | OAuth2 | Yes (automatic) |
| Trovo | OAuth2 | Yes (automatic) |
| Discord | Static Bot Token | No (permanent) |
Bot Scopes
Bot connections use minimal scopes focused on chat functionality:
| Platform | Scopes |
|---|---|
| Twitch | chat:read, chat:edit, user:write:chat, user:bot, user:read:chat |
| YouTube | youtube.force-ssl |
| Kick | chat:write |
| Trovo | chat_send_self |
| Discord | Set via Developer Portal (not OAuth scopes) |
Architecture
Backend
- GraphQL (
apps/api/src/graphql/bot_connections.rs) -- Queries for listing bot connections, bot connection statuses with enablement. Mutation for deleting bot connections. - REST -- Bot connection OAuth flow follows the same pattern as channel connections with dedicated callback URLs.
- Database (
apps/api/src/db/bot_connections.rs) -- PostgreSQL operations for thebot_connectionstable. Supports list, get, upsert, and delete operations. - OAuth (
apps/api/src/oauth.rs) --get_fresh_bot_token()for reading fresh tokens,update_bot_connection_tokens()for saving refreshed tokens.
Frontend
- Bot connection settings page with cards per platform showing connection status.
- "Connect" button initiates OAuth flow with bot-specific scopes.
- Separate from channel connections UI.
API
GraphQL Queries
| Query | Permission | Description |
|---|---|---|
botConnections | bot-connections:read | List bot connections for the account |
botConnectionStatuses | bot-connections:read | Bot platform statuses with enabled field |
botStatus | bot-connections:read | Per-platform bot status for the Bot Control dashboard |
botChannels(platform) | System key only | All bot-enabled channels for a platform (consumed by bot workers) |
GraphQL Mutations
| Mutation | Permission | Description |
|---|---|---|
authorizeBot(platform) | bot-connections:create | Start a bot OAuth flow. Returns AuthorizeResult (redirect URL). Discord is unsupported (static token). |
deleteBotConnection(platform) | bot-connections:delete | Delete a bot connection |
toggleBotForPlatform(platform, enabled) | bot-connections:create | Toggle bot_enabled on the platform's channel connection |
rejoinBot(platform) | bot-connections:create | Send a rejoin command to the bot worker for a platform |
REST Endpoints
All paths live under /v1.
| Method | Path | Permission | Description |
|---|---|---|---|
GET | /v1/bot-connections | bot-connections:read | List bot connections for the account |
DELETE | /v1/bot-connections/{platform} | bot-connections:delete | Delete a bot connection |
GET | /v1/bot-connections/{platform}/authorize | bot-connections:create | Start OAuth and return the authorize URL |
POST | /v1/bot-connections/{platform}/exchange | bot-connections:create | Exchange the OAuth code for encrypted tokens |
GET | /v1/bot-status | bot-connections:read | Aggregated bot runtime status for the account |
POST | /v1/bot-toggle | bot-connections:create | Pause or resume the bot for a platform |
POST | /v1/bot-rejoin | bot-connections:create | Force the bot to reconnect / rejoin the channel |
Request and response bodies use snake_case and mirror the GraphQL counterparts.
Permissions
| Permission | Owner | Admin | Moderator | Viewer |
|---|---|---|---|---|
bot-connections:read | Yes | Yes | Yes | No |
bot-connections:create | Yes | Yes | No | No |
bot-connections:delete | Yes | Yes | No | No |
Database
Bot connections are stored in the bot_connections table:
| Column | Type | Description |
|---|---|---|
id | UUID | Primary key |
account_id | UUID | Account (nil UUID for global bots) |
platform | VARCHAR | Platform name |
bot_type | VARCHAR | global or custom |
bot_username | VARCHAR | Bot display name |
access_token | TEXT | Encrypted OAuth token |
refresh_token | TEXT | Encrypted refresh token |
scopes | TEXT[] | Granted scopes |
expires_at | TIMESTAMPTZ | Token expiration |
Token Refresh
The Token Refresh Worker automatically refreshes bot connection tokens alongside channel and login connection tokens. Discord bot tokens are excluded since they don't expire. See Token Refresh for details.
Feature Flags
Bot connections are gated by platform:{platform}:bot feature flags. When the bot sub-flag is disabled for a platform, new bot connections are blocked but existing ones continue working. See Provider Management for details.
Key Files
| Path | Description |
|---|---|
apps/api/src/graphql/bot_connections.rs | GraphQL queries and mutations |
apps/api/src/db/bot_connections.rs | Database operations |
apps/api/src/oauth.rs | Token refresh utilities (get_fresh_bot_token, update_bot_connection_tokens) |
apps/api/src/platforms.rs | Bot OAuth scopes per platform |
See Also
- Provider Management -- Feature flag controls for bot connections
- Connections -- Channel connection OAuth flow (similar pattern)
- Token Refresh -- Automatic token refresh worker
- Bot Modules -- Chat moderation modules that use bot connections