openclaw/docs/channels/twitch.md
2026-01-25 18:27:50 +08:00

16 KiB

summary read_when
Twitch chat bot support status, capabilities, and configuration
Setting up Twitch chat integration for Clawdbot
Configuring Twitch bot permissions and access control

Twitch (plugin)

Twitch chat support via IRC connection. Clawdbot connects as a Twitch user (bot account) to receive and send messages in channels.

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):
    • 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:

{
  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 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 (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:<agentId>:twitch:<accountName>.

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.

Install via CLI (npm registry):

clawdbot plugins install @clawdbot/twitch

Local checkout (when running from a git repo):

clawdbot plugins install ./extensions/twitch

Details: Plugins

Setup

  • Go to Twitch Token Generator
  • Select Bot Token
  • Verify scopes chat:read and chat:write are selected
  • Copy the Access Token and Client ID

2) Configure credentials

Env (default account only):

export CLAWDBOT_TWITCH_ACCESS_TOKEN=your_access_token_here

Or config:

{
  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
        }
      }
    }
  }
}

Note: Copy the Access Token value to the accessToken property (add oauth: prefix if needed), and the Client ID value to the clientId property.

With env, you still need clientId and channel in config (or use the minimal config above without accessToken).

3) Start the gateway

Twitch starts when a token is resolved (config first, env fallback).

4) Join a channel

The bot joins the channel specified in channel.

Token refresh (optional, for long-running bots)

Important: Tokens from Twitch Token Generator cannot be automatically refreshed - you'll need to generate a new token when it expires (typically after several hours).

For automatic token refresh, you must create your own Twitch application:

  1. Create a Twitch application at Twitch Developer 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:
{
  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.

Routing model

  • Replies always go back to Twitch.
  • Each account maps to agent:<agentId>:twitch:<accountName>.

Multi-account support

Use channels.twitch.accounts with per-account tokens and optional name. See gateway/configuration for the shared pattern.

Example (one bot account in two different channels):

{
  channels: {
    twitch: {
      accounts: {
        ninjaChannel: {
          username: "clawdbot",
          accessToken: "oauth:abc123...",
          clientId: "xyz789...",
          channel: "vevisk"
        },
        shroudChannel: {
          username: "clawdbot",
          accessToken: "oauth:def456...",
          clientId: "uvw012...",
          channel: "secondchannel"
        }
      }
    }
  }
}

Migration notes

Breaking changes (2026.1.23+)

token renamed to accessToken: If you have existing Twitch config using token, update to accessToken:

Before:

{
  channels: {
    twitch: {
      accounts: {
        default: {
          username: "clawdbot",
          token: "oauth:abc123...",
          clientId: "xyz789...",
          channel: "vevisk"
        }
      }
    }
  }
}

After:

{
  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:

{
  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

Restrict access to specific roles:

{
  channels: {
    twitch: {
      accounts: {
        default: {
          username: "mybot",
          accessToken: "oauth:abc123...",
          clientId: "xyz789...",
          channel: "your_channel",
          allowedRoles: ["moderator", "vip"]
        }
      }
    }
  }
}

Available roles:

  • "moderator" - Channel moderators
  • "owner" - Channel owner/broadcaster
  • "vip" - VIPs
  • "subscriber" - Subscribers
  • "all" - Anyone in chat

Allowlist by User ID

Only allow specific Twitch user IDs (most secure):

{
  channels: {
    twitch: {
      accounts: {
        default: {
          username: "mybot",
          accessToken: "oauth:abc123...",
          clientId: "xyz789...",
          channel: "your_channel",
          allowFrom: ["123456789", "987654321"]
        }
      }
    }
  }
}

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/

Combined allowlist + roles

Users in allowFrom bypass role checks. In this example:

  • User 123456789 can always message (bypasses role check)
  • All moderators can message
  • Everyone else is blocked
{
  channels: {
    twitch: {
      accounts: {
        default: {
          username: "mybot",
          accessToken: "oauth:abc123...",
          clientId: "xyz789...",
          channel: "your_channel",
          allowFrom: ["123456789"],
          allowedRoles: ["moderator"]
        }
      }
    }
  }
}

Require @mention

Only respond when the bot is mentioned:

{
  channels: {
    twitch: {
      accounts: {
        default: {
          username: "mybot",
          accessToken: "oauth:abc123...",
          clientId: "xyz789...",
          channel: "your_channel",
          requireMention: true
        }
      }
    }
  }
}

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:

export CLAWDBOT_TWITCH_ACCESS_TOKEN=abc123def456...

Config with env fallback:

{
  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:

{
  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:

  • Channel messages (group chat)
  • Whispers/DMs (received but replies not supported - Twitch doesn't allow bots to send whispers)
  • Markdown stripping (automatically applied)
  • Message chunking (500 char limit)
  • Access control (user ID allowlist, role-based)
  • @mention requirement
  • Automatic token refresh (with RefreshingAuthProvider)
  • Multi-account support

Not supported:

  • Native reactions
  • Threaded replies
  • Message editing
  • Message deletion
  • Rich embeds/media uploads (sends media URLs as text)

Troubleshooting

First, run diagnostic commands:

clawdbot doctor
clawdbot channels status --probe

Bot doesn't respond to messages

Check access control:

{
  channels: {
    twitch: {
      accounts: {
        default: {
          username: "mybot",
          accessToken: "oauth:abc123...",
          clientId: "xyz789...",
          channel: "your_channel",
          // Temporary: allow everyone
          allowedRoles: ["all"]
        }
      }
    }
  }
}

Check the bot is in the channel: The bot must join the channel specified in channel.

Token issues

"Failed to connect" or authentication errors:

  • Verify accessToken is the OAuth access token value (typically starts with oauth: prefix)
  • Check token has chat:read and chat:write scopes
  • If using RefreshingAuthProvider, verify clientSecret and refreshToken are set

Token refresh not working

Check logs for refresh events:

[twitch] Using env token source for mybot
[twitch] 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)

Configuration reference (Twitch)

Full configuration: Configuration

Account config

{
  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)
}

TwitchRole: "moderator" | "owner" | "vip" | "subscriber" | "all"

Plugin config

{
  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.<accountName>.username: bot username (multi-account config).
  • channels.twitch.accounts.<accountName>.accessToken: OAuth access token (multi-account config).
  • channels.twitch.accounts.<accountName>.clientId: Twitch Client ID (from Token Generator or your app).
  • channels.twitch.accounts.<accountName>.channel: channel to join.
  • channels.twitch.accounts.<accountName>.enabled: enable/disable account (default: true).
  • channels.twitch.accounts.<accountName>.clientSecret: optional, for automatic token refresh (must be from YOUR Twitch app).
  • channels.twitch.accounts.<accountName>.refreshToken: optional, for automatic token refresh (must be from YOUR Twitch app).
  • channels.twitch.accounts.<accountName>.expiresIn: token expiry in seconds.
  • channels.twitch.accounts.<accountName>.obtainmentTimestamp: token obtained timestamp.
  • channels.twitch.accounts.<accountName>.allowFrom: user ID allowlist.
  • channels.twitch.accounts.<accountName>.allowedRoles: role-based access control.
  • channels.twitch.accounts.<accountName>.requireMention: require @mention (default: false).

Tool actions

The agent can call twitch with action:

  • send - Send a message to a channel

Example:

{
  "action": "twitch",
  "params": {
    "message": "Hello Twitch!",
    "to": "#mychannel"
  }
}

Safety & ops

  • Treat tokens like passwords - Never commit tokens to git
  • Use RefreshingAuthProvider for long-running bots
  • Use user ID allowlists instead of usernames for access control
  • Monitor logs for token refresh events and connection status
  • Scope tokens minimally - Only request chat:read and chat:write
  • If stuck: Restart the gateway after confirming no other process owns the session

Message limits

  • 500 characters per message (Twitch limit)
  • Messages are automatically chunked at word boundaries
  • Markdown is stripped before chunking to avoid breaking patterns
  • No rate limiting (uses Twitch's built-in rate limits)