Developer and self-hosted
Twitch
Twitch chat support over Twitch's chat (IRC) interface via the Twurple client. OpenClaw signs in as a Twitch bot account, joins one channel per configured account, and replies in that channel.
Install
Twitch ships as an official plugin; it is not part of the core install.
npm registry
openclaw plugins install @openclaw/twitchLocal checkout
openclaw plugins install ./path/to/local/twitch-pluginplugins install registers and enables the plugin. Picking Twitch during openclaw onboard or openclaw channels add installs it on demand. Use the bare package name to follow the current release; pin an exact version only for reproducible installs. Requires OpenClaw 2026.4.10 or newer.
Details: Plugins
Quick setup
Install the plugin
See Install above.
Create a Twitch bot account
Create a dedicated Twitch account for the bot (or use an existing account).
Generate credentials
- Select Bot Token
- Verify scopes
chat:readandchat:writeare selected - Copy the Client ID and Access Token
Find your Twitch user ID
Use https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/ to convert a username to a Twitch user ID.
Configure the token
- Env:
OPENCLAW_TWITCH_ACCESS_TOKEN=...(default account only) - Or config:
channels.twitch.accessToken
If both are set, config takes precedence (the env var is only a fallback for the default account).
Start the gateway
openclaw gateway runMinimal config:
{ channels: { twitch: { enabled: true, username: "openclaw", // Bot's Twitch account (authenticates) accessToken: "oauth:abc123...", // OAuth access token (or use OPENCLAW_TWITCH_ACCESS_TOKEN env var) clientId: "xyz789...", // Client ID from Token Generator channel: "yourchannel", // Which Twitch channel's chat to join (required) allowFrom: ["123456789"], // (recommended) Your Twitch user ID only }, },}What it is
- A Twitch channel owned by the Gateway.
- Deterministic routing: replies always go back to the Twitch channel the message came from.
- Each joined channel maps to an isolated group session key
agent:<agentId>:twitch:group:<channel>. usernameis the bot's account (who authenticates),channelis which chat room to join. One account entry joins exactly one channel.- Tokens work with or without the
oauth:prefix; OpenClaw normalizes both ways (the setup wizard expects theoauth:form).
Token refresh (optional)
Tokens from Twitch Token Generator cannot be refreshed by OpenClaw - regenerate when expired (they last a few hours; no app registration needed).
For automatic refresh, create your own app at the Twitch Developer Console and add:
{ channels: { twitch: { clientSecret: "your_client_secret", refreshToken: "your_refresh_token", }, },}With both set, the plugin uses a refreshing auth provider that renews tokens before expiration and logs each refresh. Without refreshToken it logs token refresh disabled (no refresh token); without clientSecret it falls back to a static (non-refreshing) token.
Multi-account support
Use channels.twitch.accounts with per-account credentials. See Configuration for the shared pattern.
Example (one bot account in two channels):
{ channels: { twitch: { accounts: { channel1: { username: "openclaw", accessToken: "oauth:abc123...", clientId: "xyz789...", channel: "yourchannel", }, channel2: { username: "openclaw", accessToken: "oauth:def456...", clientId: "uvw012...", channel: "secondchannel", }, }, }, },}Access control
allowFrom is a hard allowlist of Twitch user IDs. When it is set, allowedRoles is ignored; leave allowFrom unset to use role-based access instead.
Available roles: "moderator", "owner", "vip", "subscriber", "all".
User ID allowlist (most secure)
{ channels: { twitch: { accounts: { default: { allowFrom: ["123456789", "987654321"], }, }, }, },}Role-based
{ channels: { twitch: { accounts: { default: { allowedRoles: ["moderator", "vip"], }, }, }, },}Disable @mention requirement
By default, requireMention is true. To respond to all allowed messages:
{ channels: { twitch: { accounts: { default: { requireMention: false, }, }, }, },}Troubleshooting
First, run diagnostic commands:
openclaw doctoropenclaw channels status --probeBot does not respond to messages
- Check access control: Ensure your user ID is in
allowFrom, or temporarily removeallowFromand setallowedRoles: ["all"]to test. - Check the mention gate: With
requireMention: true(default), messages must @mention the bot username. - Check the bot is in the channel: The bot only joins the channel named in
channel.
Token issues
"Failed to connect" or authentication errors:
- Verify
accessTokenis the OAuth access token value (theoauth:prefix is optional) - Check the token has
chat:readandchat:writescopes - If using token refresh, verify
clientSecretandrefreshTokenare set
Token refresh not working
Check logs for refresh events:
Using env token source for mybotAccess token refreshed for user 123456 (expires in 14400s)If you see token refresh disabled (no refresh token):
- Ensure
clientSecretis provided - Ensure
refreshTokenis provided
Config
Account config
usernamestringrequiredBot username (the authenticating account).
accessTokenstringrequiredOAuth access token with chat:read and chat:write (config or env for the default account).
clientIdstringrequiredTwitch Client ID (from Token Generator or your app). Optional in the schema but required to connect.
channelstringrequiredChannel to join.
enabledbooleandefault: trueEnable this account.
clientSecretstringOptional: for automatic token refresh.
refreshTokenstringOptional: for automatic token refresh.
expiresInnumberToken expiry in seconds (refresh tracking).
obtainmentTimestampnumberTimestamp when the token was obtained (refresh tracking).
allowFromstring[]User ID allowlist. When set, roles are ignored.
allowedRoles'Array<"moderator"requireMentionbooleandefault: trueRequire @mention to trigger the bot.
responsePrefixstringOutbound response prefix override for this account.
Provider options
channels.twitch.enabled- Enable/disable channel startupchannels.twitch.username/accessToken/clientId/channel- Simplified single-account config (implicitdefaultaccount; takes precedence overaccounts.default)channels.twitch.accounts.<accountName>- Multi-account config (all account fields above)channels.twitch.defaultAccount- Which account name is the defaultchannels.twitch.markdown.tables- Markdown table rendering mode (off|bullets|code|block)
Full example:
{ channels: { twitch: { enabled: true, username: "openclaw", accessToken: "oauth:abc123...", clientId: "xyz789...", channel: "yourchannel", clientSecret: "secret123...", refreshToken: "refresh456...", allowFrom: ["123456789"], accounts: { second: { username: "mybot", accessToken: "oauth:def456...", clientId: "uvw012...", channel: "your_channel", enabled: true, expiresIn: 14400, obtainmentTimestamp: 1706092800000, allowedRoles: ["moderator"], }, }, }, },}Tool actions
The agent can send Twitch messages through the message tool send action:
{ channel: "twitch", action: "send", to: "#mychannel", message: "Hello Twitch!",}to is optional and defaults to the account's configured channel.
Safety and ops
- Treat tokens like passwords - never commit tokens to git.
- Use automatic token refresh 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:readandchat:write. - If stuck: restart the gateway after confirming no other process owns the session.
Limits
- 500 characters per message; longer replies are chunked at word boundaries.
- Markdown is stripped before sending (Twitch chat is plain text; newlines become spaces).
- OpenClaw adds no rate limiting of its own; the Twurple chat client handles Twitch rate limits.
Related
- Channel Routing — session routing for messages
- Channels Overview — all supported channels
- Groups — group chat behavior and mention gating
- Pairing — DM authentication and pairing flow
- Security — access model and hardening