diff --git a/docs/channels/twitch.md b/docs/channels/twitch.md index 266078da5..26720491a 100644 --- a/docs/channels/twitch.md +++ b/docs/channels/twitch.md @@ -10,50 +10,6 @@ Twitch chat support via IRC connection. Clawdbot connects as a Twitch user (bot Status: ready for Twitch chat via IRC connection with @twurple. -## Quick setup (beginner) -1) Install the Twitch plugin. -2) Generate your credentials (recommended: use [Twitch Token Generator](https://twitchtokengenerator.com/)): - - Select **Bot Token** - - Verify scopes `chat:read` and `chat:write` are selected - - Copy the **Client ID** and **Access Token** (and optionally **Refresh Token**) -3) Set the credentials for Clawdbot: - - Env: `CLAWDBOT_TWITCH_ACCESS_TOKEN=...` (default account only) - - Or config: `channels.twitch.accounts.default.token` - - If both are set, config takes precedence (env fallback is default-account only). -4) Start the gateway. -5) The bot joins your channel and responds to messages. - -Minimal config: -```json5 -{ - channels: { - twitch: { - enabled: true, - username: "clawdbot", // Bot's Twitch account - accessToken: "oauth:abc123...", // OAuth Access Token (or use CLAWDBOT_TWITCH_ACCESS_TOKEN env var) - clientId: "your_client_id", // Client ID from Token Generator - channel: "vevisk" // Which Twitch channel's chat to join - } - } -} -``` - -**Note:** [Twitch Token Generator](https://twitchtokengenerator.com/) provides the Client ID and Access Token (select **Bot Token** and verify `chat:read` + `chat:write` scopes) - no manual app registration needed. - -**Note:** `username` is the bot's account, `channel` is which chat to join. - -**Multi-account setup:** Use `channels.twitch.accounts` for advanced multi-account configurations. - -## How it works -1. Create a bot account (or use an existing Twitch account). -2. Generate credentials using [Twitch Token Generator](https://twitchtokengenerator.com/) (provides Client ID, Access Token, and Refresh Token). -3. Configure Clawdbot with the credentials. -4. Run the gateway; it auto-starts the Twitch channel when a token is available (config first, env fallback) and `channels.twitch.enabled` is not `false`. -5. The bot joins the specified `channel` to send/receive messages. -6. Direct chats collapse into the agent's main session (default `agent:main:main`); each account maps to an isolated session key `agent::twitch:`. - -**Key distinction:** `username` is who the bot authenticates as (the bot's account), `channel` is which chat room it joins. - ## Plugin required Twitch ships as a plugin and is not bundled with the core install. @@ -74,90 +30,72 @@ Details: [Plugins](/plugin) ## Setup -### 1) Generate your credentials (recommended: Twitch Token Generator) -- Go to [Twitch Token Generator](https://twitchtokengenerator.com/) -- Select **Bot Token** -- Verify scopes `chat:read` and `chat:write` are selected -- Copy the **Access Token** and **Client ID** +1) Install the Twitch plugin and create a dedicated Twitch account for the bot. +2) Generate your credentials (recommended: use [Twitch Token Generator](https://twitchtokengenerator.com/)): + - Select **Bot Token** + - Verify scopes `chat:read` and `chat:write` are selected + - Copy the **Client ID** and **Access Token** +3) Configure credentials: + - Env: `CLAWDBOT_TWITCH_ACCESS_TOKEN=...` (default account only) + - Or config: `channels.twitch.accounts.default.accessToken` + - If both are set, config takes precedence (env fallback is default-account only). +4) Start the gateway. +5) The bot joins your channel and responds to messages. -### 2) Configure credentials -Env (default account only): -```bash -export CLAWDBOT_TWITCH_ACCESS_TOKEN=your_access_token_here -``` +**⚠️ Important:** Strongly recommended to add `requireMention` and access control (`allowFrom` or `allowedRoles`) to prevent the bot from replying to all chat messages. -Or config: +Minimal config: ```json5 { channels: { twitch: { enabled: true, - accounts: { - default: { - username: "clawdbot", // Bot's Twitch account - accessToken: "oauth:abc123...", // Access Token from Token Generator (or omit to use env var) - clientId: "xyz789...", // Client ID from Token Generator - channel: "vevisk" // Which Twitch channel's chat to join - } - } + username: "clawdbot", // Bot's Twitch account + accessToken: "oauth:abc123...", // OAuth Access Token (or use CLAWDBOT_TWITCH_ACCESS_TOKEN env var) + clientId: "your_client_id", // Client ID from Token Generator + channel: "vevisk", // Which Twitch channel's chat to join + requireMention: true, // (recommended) Only reply when mentioned + allowFrom: ["123456789"] // (recommended) Your Twitch user ID only (Convert your twitch username to ID at https://www.streamweasels.com/tools/convert-twitch-username-%20to-user-id/) } } } ``` -**Note:** Copy the **Access Token** value to the `accessToken` property (add `oauth:` prefix if needed), and the **Client ID** value to the `clientId` property. +**Recommended access control options:** +- `requireMention: true` - Only respond when the bot is mentioned with `@botname` +- `allowFrom: ["your_user_id"]` - Restrict to your Twitch user ID only +- `allowedRoles: ["moderator", "vip", "subscriber"]` - Restrict to specific roles -With env, you still need `clientId` and `channel` in config (or use the minimal config above without `accessToken`). +**Note:** [Twitch Token Generator](https://twitchtokengenerator.com/) provides the Client ID and Access Token (select **Bot Token** and verify `chat:read` + `chat:write` scopes) - no manual app registration needed. -### 3) Start the gateway -Twitch starts when a token is resolved (config first, env fallback). +**Note:** `username` is the bot's account, `channel` is which chat to join. -### 4) Join a channel -The bot joins the channel specified in `channel`. +## How it works -## Token refresh (optional, for long-running bots) +1. Create a bot account (or use an existing Twitch account). +2. Generate credentials using [Twitch Token Generator](https://twitchtokengenerator.com/) (provides Client ID, Access Token, and optionally Refresh Token). +3. Configure Clawdbot with the credentials. +4. Run the gateway; it auto-starts the Twitch channel when a token is available (config first, env fallback) and `channels.twitch.enabled` is not `false`. +5. The bot joins the specified `channel` to send/receive messages. +6. Each account maps to an isolated session key `agent::twitch:`. -**Important:** Tokens from [Twitch Token Generator](https://twitchtokengenerator.com/) cannot be automatically refreshed - you'll need to generate a new token when it expires (typically after several hours). +**Key distinction:** `username` is who the bot authenticates as (the bot's account), `channel` is which chat room it joins. -For automatic token refresh, you must create your own Twitch application: +## Token refresh (optional) -1. Create a Twitch application at [Twitch Developer Console](https://dev.twitch.tv/console) - - Copy the **Client ID** and **Client Secret** -2. Generate a refresh token using your own app (you'll need to implement the OAuth flow or use a tool that lets you specify your Client ID) -3. Add to config: +Tokens from [Twitch Token Generator](https://twitchtokengenerator.com/) cannot be automatically refreshed - you'll need to generate a new token when it expires (typically after several hours). -```json5 -{ - channels: { - twitch: { - accounts: { - default: { - username: "clawdbot", - accessToken: "oauth:abc123...", // Access Token from your app - clientId: "xyz789...", // Client ID from your app - clientSecret: "secret123...", // Client Secret from your app - refreshToken: "refresh456...", // Refresh Token from your app - expiresIn: 14400, - obtainmentTimestamp: 1706092800000 - } - } - } - } -} -``` - -**Note:** All three values (`accessToken`, `clientId`, `refreshToken`) must come from the same Twitch application you created. - -The bot automatically refreshes tokens before they expire and logs refresh events. +For automatic token refresh, create your own Twitch application at [Twitch Developer Console](https://dev.twitch.tv/console) and add `clientSecret` and `refreshToken` to your config. The bot automatically refreshes tokens before they expire and logs refresh events. ## Routing model + - Replies always go back to Twitch. - Each account maps to `agent::twitch:`. ## Multi-account support -Use `channels.twitch.accounts` with per-account tokens and optional `name`. See [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts) for the shared pattern. +Use `channels.twitch.accounts` with per-account tokens. See [`gateway/configuration`](/gateway/configuration) for the shared pattern. Example (one bot account in two different channels): @@ -184,71 +122,9 @@ Example (one bot account in two different channels): } ``` -## Migration notes - -### Breaking changes (2026.1.23+) - -**`token` renamed to `accessToken`:** If you have existing Twitch config using `token`, update to `accessToken`: - -**Before:** -```json5 -{ - channels: { - twitch: { - accounts: { - default: { - username: "clawdbot", - token: "oauth:abc123...", - clientId: "xyz789...", - channel: "vevisk" - } - } - } - } -} -``` - -**After:** -```json5 -{ - channels: { - twitch: { - accounts: { - default: { - username: "clawdbot", - accessToken: "oauth:abc123...", - clientId: "xyz789...", - channel: "vevisk" - } - } - } - } -} -``` - -**Simplified config (recommended):** For single-account setups, you can now use base-level properties: - -```json5 -{ - channels: { - twitch: { - enabled: true, - username: "clawdbot", - accessToken: "oauth:abc123...", - clientId: "xyz789...", - channel: "vevisk" - } - } -} -``` - -The env var `CLAWDBOT_TWITCH_ACCESS_TOKEN` continues to work for the default account. - ## Access control -### Role-based restrictions (recommended) - -Restrict access to specific roles: +### Role-based restrictions ```json5 { @@ -268,12 +144,7 @@ Restrict access to specific roles: } ``` -**Available roles:** -- `"moderator"` - Channel moderators -- `"owner"` - Channel owner/broadcaster -- `"vip"` - VIPs -- `"subscriber"` - Subscribers -- `"all"` - Anyone in chat +**Available roles:** `"moderator"`, `"owner"`, `"vip"`, `"subscriber"`, `"all"`. ### Allowlist by User ID @@ -299,11 +170,11 @@ Only allow specific Twitch user IDs (most secure): **Why user IDs instead of usernames?** Twitch usernames can change, which could allow someone to hijack another user's access. User IDs are permanent. -Find your Twitch user ID at: https://www.streamweasels.com/tools/convert-your-twitch-username-to-user-id/ +Find your Twitch user ID at: https://www.streamweasels.com/tools/convert-twitch-username-%20to-user-id/ ### Combined allowlist + roles -Users in `allowFrom` bypass role checks. In this example: +Users in `allowFrom` bypass role checks. Example: - User `123456789` can always message (bypasses role check) - All moderators can message - Everyone else is blocked @@ -349,62 +220,6 @@ Only respond when the bot is mentioned: } ``` -## Environment variables - -For the default account, you can use environment variables instead of config: - -- `CLAWDBOT_TWITCH_ACCESS_TOKEN` - Access Token (without `oauth:` prefix) - -Env fallback only works for the default account. For multi-account setups, use config. - -Example: - -```bash -export CLAWDBOT_TWITCH_ACCESS_TOKEN=abc123def456... -``` - -Config with env fallback: - -```json5 -{ - channels: { - twitch: { - enabled: true, - accounts: { - default: { - username: "mybot", - clientId: "xyz789...", - channel: "your_channel" - // token will be read from CLAWDBOT_TWITCH_ACCESS_TOKEN - } - } - } - } -} -``` - -Priority: account config > base config > env var (for default account only). - -## Plugin options - -Control markdown stripping behavior: - -```json5 -{ - plugins: { - entries: { - twitch: { - stripMarkdown: true - } - } - } -} -``` - -- `stripMarkdown` (default: `true`) - Remove markdown formatting before sending to Twitch - -Twitch doesn't support markdown, so this is enabled by default. Disable if you want to send markdown as-is (it will appear as plain text with markdown symbols). - ## Capabilities & limits **Supported:** @@ -435,25 +250,7 @@ clawdbot channels status --probe ### Bot doesn't respond to messages -**Check access control:** -```json5 -{ - channels: { - twitch: { - accounts: { - default: { - username: "mybot", - accessToken: "oauth:abc123...", - clientId: "xyz789...", - channel: "your_channel", - // Temporary: allow everyone - allowedRoles: ["all"] - } - } - } - } -} -``` +**Check access control:** Temporarily set `allowedRoles: ["all"]` to test. **Check the bot is in the channel:** The bot must join the channel specified in `channel`. @@ -468,70 +265,86 @@ clawdbot channels status --probe **Check logs for refresh events:** ``` -[twitch] Using env token source for mybot -[twitch] Access token refreshed for user 123456 (expires in 14400s) +Using env token source for mybot +Access token refreshed for user 123456 (expires in 14400s) ``` If you see "token refresh disabled (no refresh token)": - Ensure `clientSecret` is provided -- Ensure `refreshToken` is provided (from Twitch Token Generator with "Include Refresh Token" checked) +- Ensure `refreshToken` is provided -## Configuration reference (Twitch) +## Config -Full configuration: [Configuration](/gateway/configuration) - -### Account config - -```typescript +```json5 { - username: string, // Bot username - accessToken: string, // OAuth access token with chat:read and chat:write - clientId: string, // Twitch Client ID (from Token Generator site or your app) - channel: string, // Channel to join - enabled?: boolean, // Enable this account (default: true) - clientSecret?: string, // Optional: For automatic token refresh (from YOUR Twitch app) - refreshToken?: string, // Optional: For automatic token refresh (from YOUR Twitch app) - expiresIn?: number, // Token expiry in seconds (for refresh) - obtainmentTimestamp?: number, // Token obtained timestamp (for refresh) - allowFrom?: string[], // User ID allowlist - allowedRoles?: TwitchRole[], // Role-based access control - requireMention?: boolean // Require @mention (default: false) + channels: { + twitch: { + enabled: true, + username: "clawdbot", + accessToken: "oauth:abc123...", + clientId: "xyz789...", + channel: "vevisk", + clientSecret: "secret123...", + refreshToken: "refresh456...", + requireMention: true, + allowFrom: ["123456789"], + allowedRoles: ["moderator", "vip"], + accounts: { + default: { + username: "mybot", + accessToken: "oauth:abc123...", + clientId: "xyz789...", + channel: "your_channel", + enabled: true, + clientSecret: "secret123...", + refreshToken: "refresh456...", + expiresIn: 14400, + obtainmentTimestamp: 1706092800000, + allowFrom: ["123456789", "987654321"], + allowedRoles: ["moderator"], + requireMention: true + } + } + } + }, + plugins: { + entries: { + twitch: { + stripMarkdown: true + } + } + } } ``` -**TwitchRole:** `"moderator"` | `"owner"` | `"vip"` | `"subscriber"` | `"all"` +**Account config:** +- `username` - Bot username +- `accessToken` - OAuth access token with `chat:read` and `chat:write` +- `clientId` - Twitch Client ID (from Token Generator or your app) +- `channel` - Channel to join +- `enabled` - Enable this account (default: `true`) +- `clientSecret` - Optional: For automatic token refresh (from YOUR Twitch app) +- `refreshToken` - Optional: For automatic token refresh (from YOUR Twitch app) +- `expiresIn` - Token expiry in seconds +- `obtainmentTimestamp` - Token obtained timestamp +- `allowFrom` - User ID allowlist +- `allowedRoles` - Role-based access control (`"moderator" | "owner" | "vip" | "subscriber" | "all"`) +- `requireMention` - Require @mention (default: `false`) -### Plugin config +**Plugin config:** +- `stripMarkdown` - Strip markdown from outbound (default: `true`) -```typescript -{ - stripMarkdown?: boolean // Strip markdown from outbound (default: true) -} -``` - -Provider options: -- `channels.twitch.enabled`: enable/disable channel startup. -- `channels.twitch.username`: bot username (simplified single-account config). -- `channels.twitch.accessToken`: OAuth access token (simplified single-account config). -- `channels.twitch.clientId`: Twitch Client ID (simplified single-account config). -- `channels.twitch.channel`: channel to join (simplified single-account config). -- `channels.twitch.accounts..username`: bot username (multi-account config). -- `channels.twitch.accounts..accessToken`: OAuth access token (multi-account config). -- `channels.twitch.accounts..clientId`: Twitch Client ID (from Token Generator or your app). -- `channels.twitch.accounts..channel`: channel to join. -- `channels.twitch.accounts..enabled`: enable/disable account (default: true). -- `channels.twitch.accounts..clientSecret`: optional, for automatic token refresh (must be from YOUR Twitch app). -- `channels.twitch.accounts..refreshToken`: optional, for automatic token refresh (must be from YOUR Twitch app). -- `channels.twitch.accounts..expiresIn`: token expiry in seconds. -- `channels.twitch.accounts..obtainmentTimestamp`: token obtained timestamp. -- `channels.twitch.accounts..allowFrom`: user ID allowlist. -- `channels.twitch.accounts..allowedRoles`: role-based access control. -- `channels.twitch.accounts..requireMention`: require @mention (default: false). +**Provider options:** +- `channels.twitch.enabled` - Enable/disable channel startup +- `channels.twitch.username` - Bot username (simplified single-account config) +- `channels.twitch.accessToken` - OAuth access token (simplified single-account config) +- `channels.twitch.clientId` - Twitch Client ID (simplified single-account config) +- `channels.twitch.channel` - Channel to join (simplified single-account config) +- `channels.twitch.accounts.` - Multi-account config (all account fields above) ## Tool actions The agent can call `twitch` with action: - - `send` - Send a message to a channel Example: diff --git a/extensions/twitch/README.md b/extensions/twitch/README.md index bc51ddca0..13f50bca9 100644 --- a/extensions/twitch/README.md +++ b/extensions/twitch/README.md @@ -20,6 +20,8 @@ Onboarding: select Twitch and confirm the install prompt to fetch the plugin aut Minimal config (simplified single-account): +**⚠️ Important:** Strongly recommended to add `requireMention` and access control (`allowFrom` or `allowedRoles`) to prevent the bot from replying to all chat messages. + ```json5 { channels: { @@ -29,11 +31,18 @@ Minimal config (simplified single-account): accessToken: "oauth:abc123...", // OAuth Access Token (add oauth: prefix) clientId: "xyz789...", // Client ID from Token Generator channel: "vevisk", // Channel to join + requireMention: true, // (recommended) Only reply when mentioned + allowFrom: ["123456789"], // (recommended) Your Twitch user ID only (Convert your twitch username to ID at https://www.streamweasels.com/tools/convert-twitch-username-%20to-user-id/) }, }, } ``` +**Recommended access control options:** +- `requireMention: true` - Only respond when the bot is mentioned with `@botname` +- `allowFrom: ["your_user_id"]` - Restrict to your Twitch user ID only (find your ID at https://www.twitchangles.com/xqc or similar) +- `allowedRoles: ["moderator", "vip", "subscriber"]` - Restrict to specific roles + Multi-account config (advanced): ```json5 @@ -62,7 +71,7 @@ Multi-account config (advanced): ## Setup -1. Generate credentials: [Twitch Token Generator](https://twitchtokengenerator.com/) +1. Create a dedicated Twitch account for the bot, then generate credentials: [Twitch Token Generator](https://twitchtokengenerator.com/) - Select **Bot Token** - Verify scopes `chat:read` and `chat:write` are selected - Copy the **Access Token** to `token` property