Twitch
Twitch chat bot setup and installation (IRC).
Supports Twitch chat via IRC connection. OpenClaw connects to channels as a Twitch user (bot account) to receive and send messages.
Plugin Installation Required
Twitch is provided as a plugin and is not packaged with the core installation.
Install via CLI (npm registry):
openclaw plugins install @openclaw/twitch
Local installation (when running from git repository):
openclaw plugins install ./extensions/twitch
Details: ''/plugin''
Quick Setup for Beginners
1. Create a dedicated Twitch account for the bot (or use an existing account).
2. Generate credentials: ''Twitch Token Generator''
- Select Bot Token
- Confirm scopes include ''chat:read'' and ''chat:write''
- Copy Client ID and Access Token
3. Find your Twitch user ID:
https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/
4. Configure token:
- Env: ''OPENCLAW_TWITCH_ACCESS_TOKEN=...'' (default account only)
- Or config: ''channels.twitch.accessToken''
- When both are set, config takes priority (env serves as default account fallback).
5. Start gateway.
''Important:'' Please configure access control (''allowFrom'' or ''allowedRoles'') to prevent unauthorized users from triggering the bot. ''requireMention'' defaults to ''true''.
Minimal configuration:
{
channels: {
twitch: {
enabled: true,
username: "openclaw",
accessToken: "oauth:abc123...",
clientId: "xyz789...",
channel: "vevisk",
allowFrom: ["123456789"],
},
},
}What is this
- A Twitch channel managed by Gateway.
- Deterministic routing: replies always go back to Twitch.
- Each account maps to an isolated session key: ''agent:<agentId>:twitch:<accountName>''.
- ''username'' is the bot account (for auth), ''channel'' is the chat room to join (required).
Setup (detailed)
#
Generate credentials
Use ''Twitch Token Generator'':
- Select Bot Token
- Confirm scopes: ''chat:read'' and ''chat:write''
- Copy Client ID and Access Token
This method doesn't require manual app registration, but tokens may expire after a few hours.
#
Configure bot
Env (default account only):
OPENCLAW_TWITCH_ACCESS_TOKEN=oauth:abc123...
Or config:
{
channels: {
twitch: {
enabled: true,
username: "openclaw",
accessToken: "oauth:abc123...",
clientId: "xyz789...",
channel: "vevisk",
},
},
}When both env and config exist, config takes priority.
#
Access control (recommended)
{
channels: {
twitch: {
allowFrom: ["123456789"]
},
},
}''allowFrom'' is a hard allowlist (most secure). If you want to control access by role, don't set ''allowFrom'', use ''allowedRoles'' instead.
''Available roles:'' ''"moderator"'', ''"owner"'', ''"vip"'', ''"subscriber"'', ''"all"''.
Why use user ID? Usernames can be changed and impersonated; user IDs are permanent.
Find user ID:
https://www.streamweasels.com/tools/convert-twitch-username-%20to-user-id/
Token refresh (optional)
Tokens generated by ''Twitch Token Generator'' cannot be auto-refreshed—you'll need to regenerate them after they expire.
If you want automatic token refresh, create your own Twitch app at ''Twitch Developer Console'' and add to config:
{
channels: {
twitch: {
clientSecret: "your_client_secret",
refreshToken: "your_refresh_token",
},
},
}The bot will automatically refresh tokens before they expire and log refresh events.
Multiple accounts
Use ''channels.twitch.accounts'' to configure tokens for each account. See ''/gateway/configuration'' for shared structure.
Example (one bot account joining two channels):
{
channels: {
twitch: {
accounts: {
channel1: {
username: "openclaw",
accessToken: "oauth:abc123...",
clientId: "xyz789...",
channel: "vevisk",
},
channel2: {
username: "openclaw",
accessToken: "oauth:def456...",
clientId: "uvw012...",
channel: "secondchannel",
},
},
},
},
}Note: Each account needs its own token (usually one token per channel).
Access control (more examples)
#
Role-based restrictions
{
channels: {
twitch: {
accounts: {
default: {
allowedRoles: ["moderator", "vip"],
},
},
},
},
}#
User ID allowlist (most secure)
{
channels: {
twitch: {
accounts: {
default: {
allowFrom: ["123456789", "987654321"],
},
},
},
},
}#
Role access (alternative)
''allowFrom'' is a hard allowlist; once set, only these user IDs are allowed.
If you want to allow by role, leave ''allowFrom'' empty and use ''allowedRoles'':
{
channels: {
twitch: {
accounts: {
default: {
allowedRoles: ["moderator"],
},
},
},
},
}#
Disable @mention requirement
Default ''requireMention=true''. To reply to all messages:
{
channels: {
twitch: {
accounts: {
default: {
requireMention: false,
},
},
},
},
}Troubleshooting
First run diagnostic commands:
openclaw doctor openclaw channels status --probe
#
Bot not responding
- Check access control: confirm your user ID is in ''allowFrom'', or temporarily remove ''allowFrom'' and set ''allowedRoles: ["all"]'' for testing.
- Check if bot has joined the channel specified in ''channel''.
#
Token issues
"Failed to connect" or auth errors:
- Confirm ''accessToken'' is an OAuth access token (usually starts with ''oauth:'')
- Confirm token scopes include ''chat:read'' and ''chat:write''
- If token refresh is enabled, confirm ''clientSecret'' and ''refreshToken'' are set
#
Token refresh not working
Check refresh events in logs:
Using env token source for mybot Access token refreshed for user 123456 (expires in 14400s)
If you see "token refresh disabled (no refresh token)":
- Confirm ''clientSecret'' is provided
- Confirm ''refreshToken'' is provided
Configuration
Account config fields:
- ''username'': bot username
- ''accessToken'': OAuth access token with ''chat:read''/''chat:write''
- ''clientId'': Twitch Client ID (Token Generator or your app)
- ''channel'': channel to join (required)
- ''enabled'': whether to enable this account (default ''true'')
- ''clientSecret'': optional, for auto token refresh
- ''refreshToken'': optional, for auto token refresh
- ''expiresIn'': expiration seconds
- ''obtainmentTimestamp'': token acquisition timestamp
- ''allowFrom'': user ID allowlist
- ''allowedRoles'': role-based access control (''"moderator" | "owner" | "vip" | "subscriber" | "all"'')
- ''requireMention'': whether @mention is required (default ''true'')
Provider config fields:
- ''channels.twitch.enabled''
- ''channels.twitch.username'' (single account simplified config)
- ''channels.twitch.accessToken'' (single account simplified config)
- ''channels.twitch.clientId'' (single account simplified config)
- ''channels.twitch.channel'' (single account simplified config)
- ''channels.twitch.accounts.<accountName>'' (multi-account config)
Full example:
{
channels: {
twitch: {
enabled: true,
username: "openclaw",
accessToken: "oauth:abc123...",
clientId: "xyz789...",
channel: "vevisk",
clientSecret: "secret123...",
refreshToken: "refresh456...",
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"],
},
},
},
},
}Tool actions
Agent can call ''twitch'' actions:
- ''send'': send message to channel
Example:
{
action: "twitch",
params: {
message: "Hello Twitch!",
to: "#mychannel",
},
}Security & operations
- Treat tokens as passwords: don't commit to git
- Enable auto token refresh for long-term operation
- Use user ID allowlist for access control (not username)
- Monitor logs for refresh and connection status
- Request minimal scopes: ''chat:read'' and ''chat:write''
- If stuck: confirm no other process is using the session, then restart gateway
Limitations
- Single message 500 characters (auto-split at word boundaries)
- Markdown removed before splitting
- No additional rate limiting (relies on Twitch's built-in limits)