Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Social Channels

Broadcast / social-feed integrations. These differ from chat channels in two ways: messages are typically public, and the agent often acts as a poster rather than a bidirectional responder.

Build note: Social channels are not included in the lean default build. To use them, build with --features channels-full (all channels) or the specific feature flag (e.g. --features channel-twitter). Prebuilt binaries do not include these channels by default. See Channels → Overview for the full build-options table.

Twitch

Twitch chat is a thin adapter over IRC. Build it with --features channel-twitch or include it through --features channels-full; the lean default build does not include it.

Configure enabled, bot_username, oauth_token, and the channels to join under a Twitch alias. mention_only is optional and defaults to false. A minimal instance looks like this:

[channels.twitch.default]
enabled = true
bot_username = "zeroclaw_bot"
oauth_token = "replace-with-twitch-token"
channels = ["zeroclaw_channel"]
mention_only = true

[peer_groups.twitch_default]
channel = "twitch.default"
external_peers = ["zeroclaw_user"]
  • Auth: use a Twitch user access token for the bot account with chat:read and chat:edit. After configuring the Twitch CLI, generate it while signed in as that account with twitch token -u -s 'chat:read chat:edit', then store it through a protected config surface. ZeroClaw trims the value and adds the required oauth: prefix when it is omitted.
  • Channels: entries in channels may include the leading #; ZeroClaw adds it when missing and normalizes channel names to lowercase.
  • Inbound and outbound: channel messages are answered in the same channel. mention_only = true ignores channel messages that do not mention bot_username. If Twitch delivers a non-channel IRC PRIVMSG to the bot login, ZeroClaw replies to that sender; the adapter does not configure a separate whisper transport.
  • Formatting: Twitch replies use plain text and are split to fit IRC frames. Markdown formatting is not preserved.
  • Rate limits: the adapter writes IRC PRIVMSG frames directly and has no Twitch-specific rate limiter or HTTP 429 backoff. Keep the agent’s posting cadence within Twitch Chat limits and throttle bursty workflows at their source.

Bluesky (AT Protocol)

Inbound senders are gated against the peer set resolved for the bound agent, drawn from the peer_groups config the agent belongs to. Matching strips a leading @ and is case-insensitive against the channel’s native sender identifier. An empty set denies everyone; a set containing "*" accepts anyone; otherwise only the listed external peers (and peer agents) are accepted. This is separate from gateway pairing (gateway.require_pairing), which authenticates HTTP/WebSocket clients, not chat-channel senders.

A peer group for bluesky sets channel to bluesky, lists the allowed senders in external_peers (for bluesky, the sender’s handle or DID (a DID survives a handle rename); ["*"] accepts anyone), optionally names peer agents for cross-agent dispatch, an ignore blocklist, and an output_modality (mirror, voice, or text). See Peer Groups for the field reference.

Where to set this:

Gateway dashboard

Open /config/peer_groups in the web dashboard.

zerocode

In the Config pane, under Peer groups.

  • Auth: Bluesky app-password (not your real password). Create one in settings.
  • Inbound: mention and reply notifications, from peers only.
  • Outbound: 300-character posts; longer responses auto-thread.
  • Protocol: AT Protocol via the atrium-api crate.

A peer entry may be either the handle or the DID. Prefer the DID if you want the entry to survive the account renaming itself.

Each poll walks the unread notifications to the end before delivering any of them, so a failure part-way through the walk delivers nothing and retries the whole range on the next poll. That trades a short delay for not re-delivering the pages that did arrive: a notification the agent has already answered is worse than one it answers five seconds late.

Nostr

Inbound senders are gated against the peer set resolved for the bound agent, drawn from the peer_groups config the agent belongs to. Matching strips a leading @ and is case-insensitive against the channel’s native sender identifier. An empty set denies everyone; a set containing "*" accepts anyone; otherwise only the listed external peers (and peer agents) are accepted. This is separate from gateway pairing (gateway.require_pairing), which authenticates HTTP/WebSocket clients, not chat-channel senders.

A peer group for nostr sets channel to nostr, lists the allowed senders in external_peers (for nostr, the sender’s hex public key; ["*"] accepts anyone), optionally names peer agents for cross-agent dispatch, an ignore blocklist, and an output_modality (mirror, voice, or text). See Peer Groups for the field reference.

Where to set this:

Gateway dashboard

Open /config/peer_groups in the web dashboard.

zerocode

In the Config pane, under Peer groups.

  • Auth: raw private key (nsec bech32 or hex).
  • Inbound: kind-1 (text), kind-4 (DM, NIP-04), and kind-1059 (gift-wrap, NIP-17).
  • Outbound: same kinds. Zap handling is experimental.
  • Relays: the agent connects to all listed relays; use 3–5 for reliability. If relays is omitted, ZeroClaw connects to a built-in set of popular public relays.

Twitter / X

Inbound senders are gated against the peer set resolved for the bound agent, drawn from the peer_groups config the agent belongs to. Matching strips a leading @ and is case-insensitive against the channel’s native sender identifier. An empty set denies everyone; a set containing "*" accepts anyone; otherwise only the listed external peers (and peer agents) are accepted. This is separate from gateway pairing (gateway.require_pairing), which authenticates HTTP/WebSocket clients, not chat-channel senders.

A peer group for twitter sets channel to twitter, lists the allowed senders in external_peers (for twitter, the Twitter/X @username; ["*"] accepts anyone), optionally names peer agents for cross-agent dispatch, an ignore blocklist, and an output_modality (mirror, voice, or text). See Peer Groups for the field reference.

Where to set this:

Gateway dashboard

Open /config/peer_groups in the web dashboard.

zerocode

In the Config pane, under Peer groups.

  • Auth: Twitter API v2 OAuth 2.0 Bearer Token only.
  • Inbound: mentions via the Filtered Stream endpoint.
  • Outbound: posts, replies, threads.
  • Caveat: the free tier is rate-limited to the point of near-uselessness. Budget accordingly.

Reddit

Inbound senders are gated against the peer set resolved for the bound agent, drawn from the peer_groups config the agent belongs to. Matching strips a leading @ and is case-insensitive against the channel’s native sender identifier. An empty set denies everyone; a set containing "*" accepts anyone; otherwise only the listed external peers (and peer agents) are accepted. This is separate from gateway pairing (gateway.require_pairing), which authenticates HTTP/WebSocket clients, not chat-channel senders.

A peer group for reddit sets channel to reddit, lists the allowed senders in external_peers (for reddit, the Reddit username without the u/ prefix (case-insensitive); ["*"] accepts anyone), optionally names peer agents for cross-agent dispatch, an ignore blocklist, and an output_modality (mirror, voice, or text). See Peer Groups for the field reference.

Where to set this:

Gateway dashboard

Open /config/peer_groups in the web dashboard.

zerocode

In the Config pane, under Peer groups.

  • Auth: OAuth 2.0 with a refresh token. Generate one with a script-type Reddit app and the password or code flow.
  • Inbound: the unread inbox, which is mentions, comment replies and DMs. Every item must come from a peer.
  • Outbound: posts, comments, private messages.

subreddits narrows where an item may come from; the peer set decides who may send one. Both apply, and neither substitutes for the other. A DM carries no subreddit, so subreddits cannot filter it and the peer set is the only gate.


Operating social channels safely

Bots on public social networks attract adversarial input. Two precautions:

  1. Restrict who the agent will respond to. Gate inbound senders with a peer group (per channel, above): an empty peer set denies everyone, ["*"] accepts anyone. This applies to every social channel, so an enabled channel with no peer group configured answers no one until you populate it.
  2. Keep autonomy level at Supervised or lower. A public-facing agent in Full autonomy is effectively a public shell. For public-facing channels, restrict the tool surface in the global tool-policy config rather than expecting per-channel tools_allow (no such per-channel field exists).

Rate limits

Rate-limit handling differs by channel. Twitch writes IRC PRIVMSG frames directly and has no adapter-specific limiter. If you hit persistent rate-limiting, throttle the agent’s posting cadence at the source rather than relying on per-channel streaming knobs (none of these channels expose draft-update intervals; their schema is intentionally minimal).