Buzz Channel Plugin for OpenClaw Agents
Learn how to connect OpenClaw agents to Buzz rooms, enabling message exchange, mentions, and typing signals. This guide covers setup, capabilities, and current limitations for team collaboration.
Read this when
- You want people to reach an OpenClaw agent from Buzz
- You are setting up a Buzz bot identity and room access
- You are troubleshooting a Buzz connection
Buzz is an official channel plugin that lets OpenClaw agents interact with team rooms inside a Buzz workspace, whether that workspace is hosted by Buzz or run on your own infrastructure.
What it does
- Pulls in plain, rich-content, and structured-diff messages from rooms the bot has been approved for
- Sends responses back into the same room and thread where the message arrived
- Signals typing activity whenever an accepted agent turn is in progress
- Keeps Markdown formatting intact in outgoing replies and routes text through OpenClaw's built-in
messagetool - Delivers native Buzz mentions to current room participants from both replies and proactive messages
- Honors mention requirements and sender allowlists
- Finds rooms automatically once the bot has received approval
- Looks up current Buzz profile names, avatars, room names, and room membership via OpenClaw's directory commands
- Reconnects when needed and guards against reprocessing the same message
Group rooms, Markdown text, and inbound structured diffs are what the current plugin handles. Direct messages, media and file uploads, native reactions, room creation, and automatic admin approval remain unsupported for now.
Buzz identity and room model
Identity in Buzz is built on Nostr keypairs:
- The private key is what OpenClaw uses to authenticate and sign messages. It never leaves the Gateway.
- The public key is the bot's identifier. Buzz owners need it for relay approval, room admins need it to assign the Bot role, and OpenClaw can reference public keys in sender allowlists.
A single relay URL points to one Buzz workspace. Every room carries a UUID, and OpenClaw treats each configured UUID as its own group conversation. One Gateway with one bot identity can cover many rooms; there is no need to spin up a Gateway for each agent or room.
Before you start
The following are required:
- The
wss://relay URL for your Buzz workspace. - A Buzz owner or admin who can approve a bot identity.
- At least one room where the bot can be given the Bot role.
Warning
Do not hand OpenClaw the private key of a human Buzz owner. OpenClaw either creates or reuses a dedicated bot identity and shows the public key an admin needs for approval.
Install
openclaw plugins install @openclaw/buzz
After installing or updating the plugin, restart the Gateway.
Guided setup
Execute:
openclaw channels add --channel buzz
The setup flow proceeds through these steps:
- Pick an existing Buzz account or create one with a name.
- Provide the Buzz relay URL if that account does not already have one configured.
- OpenClaw either reuses the account's existing bot identity or generates a fresh one on its own.
- If the bot lacks room access, pass the displayed public key to a Buzz room owner or admin.
- OpenClaw waits for Buzz to confirm the Bot role and then proceeds automatically. If that wait times out, retry authenticated discovery or go back without altering the generated identity.
- When Buzz returns a single room, OpenClaw picks it. With multiple rooms, choose which ones to use and which serves as the default outbound room.
- OpenClaw stores the configuration and quietly verifies the authenticated room while the Gateway is running.
A fresh setup accepts normal messages from current members of the configured rooms without any composer mention being required. Rerunning setup keeps any existing explicit mention and sender-allowlist settings intact.
Setup resolves the selected account's privateKey and authTag SecretRefs without swapping out the references already in your configuration. If a configured secret cannot be resolved, setup reports the error and does not save account changes. Make the secret available and run setup again; existing accounts stay enabled. To finish setup, select at least one authorized room, or go back to leave things as they are.
The wait for room access is time-bound. When access is not granted in time, setup stays open and offers authenticated Retry/Back controls. Each retry uses the same relay and bot identity; the timeout neither disables Buzz nor exits setup.
Bot approval
Every target room must include the bot identity with the Bot role. A human member or an ordinary room member role will not do.
Buzz desktop is not reliable for assigning the Bot role to an externally managed OpenClaw identity. Use the Buzz CLI as the existing human room owner or admin:
buzz channels add-member \
--channel <ROOM_UUID> \
--pubkey <BOT_PUBLIC_KEY> \
--role bot
Run that command as the existing human owner or admin. Never give OpenClaw that human private key.
Once the Gateway connects, OpenClaw keeps any existing non-empty Buzz profile display name. For a new profile it falls back to the configured Buzz channel account name, then to the identity name of the single agent routed to the configured Buzz rooms, and finally to OpenClaw. After Buzz's profile cache refreshes, this replaces the shortened public key.
OpenClaw also registers the same public identity in Buzz's agent directory. It keeps an existing agent-directory profile and channel-add policy; for a new profile it lets authorized Buzz users add the identity. That allows Buzz to assign the Bot role when the identity is invited to additional rooms rather than treating it as a normal member. OpenClaw still receives messages only from rooms explicitly selected in that account's groups: use channels.buzz.groups for the implicit root identity or channels.buzz.accounts.<id>.groups for a nested identity.
When the bot profile lacks a valid NIP-OA owner attestation, Buzz displays owner unavailable. That does not indicate room access failed. Configure the selected identity's authTag at channels.buzz.authTag for the implicit root identity or channels.buzz.accounts.<id>.authTag for a nested identity. OpenClaw includes that attestation in the published profile so Buzz can show the verified human owner.
While the Gateway is connected, OpenClaw publishes and refreshes the bot's ephemeral Buzz presence every 30 seconds. Buzz drops the presence when the last authenticated Gateway connection for that bot identity closes, so multiple Gateway instances do not wrongly mark one another offline. If the relay stops acknowledging presence, OpenClaw reconnects the affected Buzz account instead of leaving an open but stalled connection marked ready. An explicit presence rejection is only a warning, not a reconnect trigger.
The local Buzz just dev relay does not require separate relay membership by default. A hosted or closed relay may require the bot public key to be added to the workspace community first. Adding community membership grants relay access; it does not add the identity to a room with the Bot role.
buzz-admin add-member --pubkey <BOT_PUBLIC_KEY> --role member
OpenClaw cannot grant room or relay access. It only displays the bot public key needed by the authorized human.
Agent tools and messaging
The Buzz plugin does not add a separate Buzz-only agent tool. It registers Buzz as a destination for OpenClaw's built-in message tool and normal reply delivery.
Agents can:
- Respond to an incoming Buzz message in its room or thread
- Show room- or thread-scoped typing while generating a reply
- Receive Buzz kind
9normal messages, kind40002rich-content messages, and kind40008structured diffs - Send Markdown text to an approved Buzz room as a normal kind
9message - Send native room-member mentions from normal replies and proactive messages
- Use the configured default room when a workflow does not specify a target
- Use the routed agent's normal skills, memory, and allowed tools
Structured diffs include their repository, commit, file, branch, pull request, language, description, truncation status, and unified-diff content in the agent context when those fields are present. Diff content is not interpreted as an OpenClaw command or textual mention.
Typing uses Buzz's ephemeral kind 20002 on the active authenticated Gateway connection. Ordinary replies refresh it every three seconds; heartbeat-driven replies use OpenClaw's shared typing interval, which defaults to six seconds. OpenClaw stops refreshing when the turn completes, is cancelled, fails, or the Gateway shuts down. Typing failures do not block the reply or reconnect the Gateway solely to send an ephemeral event.
Humans and automations can exercise the same outbound path through the CLI:
openclaw message send \
--channel buzz \
--target buzz:<ROOM_UUID> \
--message "Hello from OpenClaw"
Native mentions
Write the profile name of a unique current room member as @Display Name. OpenClaw
leaves the visible text untouched and appends the native Buzz p tag, which
also applies to threaded replies. Name resolution only consults the target
room's current relay-signed membership and the bounded profile snapshot.
To specify an identity explicitly, add its NIP-27 reference to the message:
openclaw message send \
--channel buzz \
--target engineering \
--message "Please review this, nostr:npub1..."
The public key referenced must belong to a current member of the target room.
When no explicit identity is supplied, unknown names and duplicate profile
names fail visibly rather than sending text that resembles a mention without
notifying anyone. If the message carries an explicit identity, unresolved or
ambiguous labels remain presentation text; list every intended identity
explicitly. Ambiguity errors show candidate public keys so the sender can retry
with the intended nostr:npub... identity. Public keys outside the room always fail.
Mention-like text inside inline or fenced Markdown code is ignored, and a single
message may hold at most 50 native mentions.
Connected Gateways resolve names from their current in-memory directory
snapshot and never query the relay per message. Profiles outside the bounded
snapshot require an explicit nostr:npub... identity. A standalone mention send
loads membership and profiles through one bounded authenticated relay session,
publishes, and closes it; standalone messages without mention syntax keep the
existing direct publish path.
Directory and sender labels
OpenClaw maintains a bounded snapshot of the configured rooms, their current
relay-signed member lists, room metadata, and kind 0 member profiles. Incoming
agent context uses the current profile and room names when available, while the
sender public key remains the stable authorization, routing, and session
identity.
View the same data from the CLI:
openclaw directory self --channel buzz
openclaw directory peers list --channel buzz --query "alice"
openclaw directory groups list --channel buzz --query "engineering"
openclaw directory groups members \
--channel buzz \
--group-id buzz:<ROOM_UUID>
When the Gateway is connected, directory reads reuse its authenticated Buzz connection and in-memory snapshot. A standalone directory command opens one bounded authenticated connection, loads the current snapshot, and closes it. Ordinary directory errors are logged without reconnecting. If a directory or profile subscription does not reach EOSE within 10 seconds, OpenClaw treats the Buzz relay session as stalled and recycles only that Buzz account connection; the Gateway keeps running.
Archived rooms are excluded from directory results and live room subscriptions. If a configured room is archived or restored while OpenClaw is connected, the plugin recycles only its Buzz connection so the subscription set matches the relay's current metadata. The Gateway keeps running.
Each configured room uses one room-scoped relay subscription. OpenClaw reserves four of Buzz's 1,024 connection subscriptions for membership notifications and concurrent profile, membership, and metadata queries, so one account can configure up to 1,020 rooms. Near that limit, optional member profile subscriptions are reduced first; directory entries continue to work with stable public keys and deterministic fallback labels.
Unique current room names can resolve as outbound targets through OpenClaw's
shared directory lookup. The canonical buzz:<ROOM_UUID> target remains the
safest choice for automation and for rooms with duplicate names.
Route rooms to different agents
Standard OpenClaw bindings can send each Buzz room to a different agent, workspace, or model while one Gateway and Buzz bot serve all of them:
{
agents: {
entries: {
support: { default: true, workspace: "~/.openclaw/workspace-support" },
engineering: { workspace: "~/.openclaw/workspace-engineering" },
},
},
bindings: [
{
agentId: "support",
match: {
channel: "buzz",
peer: { kind: "group", id: "buzz:<SUPPORT_ROOM_UUID>" },
},
},
{
agentId: "engineering",
match: {
channel: "buzz",
peer: { kind: "group", id: "buzz:<ENGINEERING_ROOM_UUID>" },
},
},
],
}
Without a room-specific binding, normal OpenClaw routing selects the default agent. See Channel routing for matching precedence.
Access control
Buzz applies two independent controls:
- Require mentions: the agent responds only when the bot is mentioned.
- Sender access: allow every current member of an approved room, disable room ingress, or additionally restrict room members to selected Buzz public keys.
Fresh guided setup allows normal messages from current members of the selected rooms. OpenClaw loads Buzz's relay-signed room roster before accepting messages, checks membership before queuing and again after asynchronous admission, and follows live relay-signed roster updates, including role changes. A removal invalidates queued messages immediately; cancelled admission is not committed as processed. Bounded snapshot refreshes confirm membership-change notifications. There is no per-message relay query or Gateway polling. Removing a sender does not cancel a room turn already admitted for that sender; losing the bot's own Bot role or stopping its connection still fences output.
Startup and reconnect recover eligible messages from the last 24 hours, but never from before that room's first activation by this Buzz account. That activation floor survives restarts; sender-supplied timestamps do not advance it. Replay deduplication prevents completed messages from running again.
Use groupPolicy: "allowlist" with groupAllowFrom in manual configuration
when only specific room members should be able to activate the agent.
Each room can override groupPolicy, groupAllowFrom, or both. An omitted room
setting inherits the account-wide value; an explicitly empty room allowlist
denies every sender when its effective policy is "allowlist".
Set requireMention: true only when the Buzz client used by those members can
address the bot identity.
These controls decide who can start an agent run; they do not limit what the routed agent can do after a message is accepted. Treat room messages as untrusted input, and configure that agent's sandbox and tool policy for the room's trust level.
Bot conversations
Authorized room members with the relay-assigned Bot role can activate the agent under the same mention and sender rules. Within each Gateway, OpenClaw limits repeated exchanges between each bot pair in the same relay and room: the default budget is 20 accepted messages in 60 seconds, followed by a 60-second cooldown. Changing threads does not reset the budget. Restarting the Gateway clears this in-memory budget; separate Gateways have separate budgets. Human messages are unaffected, and suppressed bot turns are logged without starting an agent run.
Use the shared channels.defaults.botLoopProtection settings to adjust
maxEventsPerWindow, windowSeconds, or cooldownSeconds. Setting
enabled: false disables this protection. Bot classification comes from the latest
received relay-signed room roster, never a display name or message content. If an
authorized bot stops replying during a busy exchange, check the suppression log
and allow the cooldown to expire before adjusting the budget.
Passive room context
Set channels.buzz.historyLimit to a number from 1 to 20 to include recent
unmentioned messages with the next accepted turn (mention or authorized command)
in the same room and thread.
The default is 0 (off). A new reply thread does not import top-level room history.
Sender access still applies: denied senders are never recorded, and senders no
longer in the current room roster are removed before context is included.
Passive messages do not start an agent run, record a session, or send typing. History stays in memory for the current connection, separately for each room and thread, and is cleared on reconnect or restart. Each message is truncated to 512 UTF-8 bytes; the newest complete entries fit within a 1,024-byte rendered context budget, including labels and markers. Older entries are discarded. An accepted turn consumes its context without deleting messages that arrived while the reply was running.
Membership is checked against the latest received roster when context is used. If the same identity leaves and rejoins before then, its previously authorized messages can remain in the window; leaving does not erase conversation history.
Reply placement
Buzz keeps automatic replies threaded by default (channels.buzz.replyToMode: "all").
Set replyToMode: "off" to send automatic replies at the top level of the room,
including replies to messages inside existing threads. Typing indicators follow
the same placement, including heartbeat typing.
This changes delivery only: inbound thread context and session identity remain
intact. Explicit message-tool or CLI sends with a thread or reply target still
honor that target. To restore the default, use "all" or remove the setting.
Manual configuration
Guided setup is the recommended path. The equivalent configuration is shown below:
{
channels: {
buzz: {
name: "OpenClaw",
relayUrl: "wss://buzz.example.com",
privateKey: "nsec1...",
groupPolicy: "open",
groups: {
"7c4a6d2a-2ed9-4b4e-a5e2-4d705ee9b34c": {
requireMention: false,
},
},
defaultTo: "7c4a6d2a-2ed9-4b4e-a5e2-4d705ee9b34c",
},
},
}
For a more restrictive sender policy:
{
channels: {
buzz: {
groupPolicy: "allowlist",
groupAllowFrom: ["<64_CHARACTER_HEX_SENDER_PUBLIC_KEY>"],
},
},
}
To limit a single room while leaving other configured rooms active:
{
channels: {
buzz: {
groupPolicy: "open",
groups: {
"7c4a6d2a-2ed9-4b4e-a5e2-4d705ee9b34c": {
groupPolicy: "allowlist",
groupAllowFrom: ["<64_CHARACTER_HEX_SENDER_PUBLIC_KEY>"],
},
},
},
},
}
Room UUIDs serve as the canonical identifiers. Use the UUID displayed during discovery or request it from a room administrator. A unique current room name can be looked up through the live directory, but automation should rely on buzz:<ROOM_UUID> to prevent confusion.
For manual setup, groupAllowFrom entries must be provided in the 64-character hexadecimal format.
Reply prefix
Set channels.buzz.responsePrefix to prepend automatic agent responses, such as "[Support]". Use "auto" for the routed agent's identity name, "[{model}]" for its chosen model, or "" to turn off an inherited global prefix. Explicit message tool and CLI text sends also apply literal and identity prefixes; refer to shared prefix behavior for model-dependent templates. A named account can override the root prefix using channels.buzz.accounts.<id>.responsePrefix.
CLI sends that omit --account also use the prefix from the selected default account; an account-level "" suppresses the inherited root prefix.
Multiple bot identities
A single Gateway can run multiple independent Buzz accounts, each with its own relay, bot key, authorization value, and chosen rooms. Execute openclaw channels add --channel buzz and select a new account for interactive configuration. Adding a named account does not relocate or replace the existing root identity.
{
channels: {
buzz: {
relayUrl: "wss://buzz.example.com",
privateKey: { source: "env", provider: "default", id: "BUZZ_ROOT_KEY" },
groupPolicy: "allowlist",
groups: { "7c4a6d2a-2ed9-4b4e-a5e2-4d705ee9b34c": {} },
accounts: {
ada: {
name: "Ada",
relayUrl: "wss://buzz.example.com",
privateKey: { source: "env", provider: "default", id: "BUZZ_ADA_KEY" },
groups: { "940d0c32-4eb7-46d7-9d5b-d975aaef87f7": {} },
},
},
},
},
}
Named accounts inherit root policy and delivery settings, but never root name, relayUrl, privateKey, authTag, groups, or defaultTo. Set those identity and room fields individually per account. An explicit accounts.default also holds a complete identity and replaces the implicit root identity; it does not inherit root credentials or BUZZ_* environment variables.
Set defaultAccount to choose the account used when a command omits --account. Otherwise, the implicit root/default identity is preferred, followed by the first configured account in sorted order. Account keys consist of lowercase letters, digits, hyphens, and underscores, start with a letter or digit, and are limited to 64 characters; constructor and prototype are reserved.
Use --account ada with message and directory commands, and add accountId: "ada" to a binding's match object when routing that bot to an agent. Set channels.buzz.accounts.ada.enabled: false to disable only Ada; channels.buzz.enabled: false disables all Buzz accounts. Buzz does not yet support account disabling or deletion via channels remove.
Editing an existing named account reloads only that account, keeping healthy sibling accounts connected. Changes to shared Buzz settings, accounts.default, or removed accounts trigger a full channel reload. Account shutdown waits for admitted message work and pending profile synchronization before starting a replacement.
Bot key storage
The default guided path reuses the current bot identity or generates a private key and stores it in the selected account's privateKey, following OpenClaw's current plaintext config convention.
For an existing key, setup can use plaintext or an existing env, file, or exec SecretRef. See Secrets management for provider setup. The implicit root default identity can also read:
export BUZZ_RELAY_URL="wss://buzz.example.com"
export BUZZ_PRIVATE_KEY="nsec1..."
With BUZZ_PRIVATE_KEY set, non-interactive setup can also save an account name:
openclaw channels add --channel buzz --name "Support bot" \
--relay-url wss://buzz.example.com --use-env
Omitting --name or providing a blank name keeps the existing name. This command saves credentials and settings; use guided setup to discover and select rooms before starting a new bot.
If a hosted workspace operator provides an identity authorization value, set the selected identity's authTag. The implicit root identity uses channels.buzz.authTag and can fall back to BUZZ_AUTH_TAG. Nested identities, including accounts.default, use channels.buzz.accounts.<id>.authTag and never borrow that environment fallback. The field accepts the same plaintext or SecretRef forms as the private key. Treat this delegated, reusable value as a secret: keep it out of logs, screenshots, chat, and source control, and prefer a SecretRef for persistent deployments. Request a replacement and revoke the old value whenever the bot identity or relay authorization changes, or if either credential may have been exposed.
Self-hosted operators can generate a key manually for recovery or advanced setup:
buzz-admin generate-key
Verify the connection
Run the authenticated channel probe:
openclaw channels status --channel buzz --probe
A successful probe verifies that the bot can authenticate and that Buzz reports the selected room with the Bot role.
Then send a real message:
openclaw message send \
--channel buzz \
--target buzz:<ROOM_UUID> \
--message "OpenClaw Buzz test"
For a full round trip, have an allowed Buzz user mention the bot and confirm that OpenClaw replies in the room.
QA Lab round trip
Source checkouts can exercise the production Buzz channel path with two dedicated test identities:
pnpm openclaw qa buzz \
--credential-file /secure/path/buzz-qa-credentials.json \
--provider-mode mock-openai
The command executes a genuine relay canary and mention-gating verification, relying on the deterministic mock model. The private JSON credential file holds relayUrl, roomId, driverPrivateKey, and sutPrivateKey, along with the optional driverAuthTag and sutAuthTag entries for closed relays. Both test public keys need to be members of the room, while the SUT public key requires the Bot role. A closed relay might demand that both public keys be enrolled individually. For pooled QA credentials, use --credential-source convex.
Hosted relays should be accessed through wss://. Plaintext ws:// credential URLs are permitted solely for loopback development relays.
Refrain from ever using a human owner or admin private key. Private keys and any optional authorization values are parent-harness secrets, and they must never surface in logs, artifacts, screenshots, shell history, or source control.
Rotate the bot identity
Rotating bot identity requires admin approval for the new public key:
- Create a fresh, dedicated bot identity.
- Get an admin to approve its public key for the relay and for every configured room.
- Swap in the new private key and restart or reload the Gateway.
- Verify outbound and inbound messaging.
- Delete the old public key from the rooms and the relay.
Finish the approval process before switching keys to cut downtime. Rotation is not automatic at this time.
Current limits and roadmap
The following items are slated for future work but are absent from the current plugin:
- Direct messages
- Media and file upload or download
- Native emoji reactions
- Creating or administering rooms from OpenClaw
- Automatic relay membership and room-role approval
- Guided bot identity rotation
Troubleshooting
| Symptom | What to check |
|---|---|
| No rooms are discovered | Verify that this exact bot public key resides in the room with the Bot role, then rerun the same setup command. |
| Authentication fails | Inspect the relay URL, bot private key, closed-relay membership, and any authorization value provided by the operator. |
| A message cannot be sent | Ensure the bot is a room member holding the Bot role and that the UUID is set. |
| The bot receives messages but does not reply | Verify the sender remains a room member, then review the optional sender allowlist and mention requirement. |
| Setup says the Gateway is not running | Launch it with openclaw gateway, then execute openclaw channels status --probe. |
| Automatic room discovery expires | Assign the Bot role, then pick Retry; the same identity stays active. |