mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-16 15:43:57 -06:00
e40e352fe7
* refactor(session-url): centralize contract normalization * fix(ui): resolve normalization agent-id alias * test(session-url): make grammar tables type-safe
163 lines
6.5 KiB
Markdown
163 lines
6.5 KiB
Markdown
# ClickClack OpenClaw channel
|
|
|
|
Official OpenClaw channel plugin for ClickClack.
|
|
|
|
## Install
|
|
|
|
```sh
|
|
openclaw plugins install @openclaw/clickclack
|
|
```
|
|
|
|
## Setup
|
|
|
|
The recommended setup path uses the one-time command generated by ClickClack:
|
|
|
|
```sh
|
|
openclaw channels add clickclack --code 'https://clickclack.example.com/#XXXX-XXXX-XXXX'
|
|
```
|
|
|
|
Split-origin and path-mounted ClickClack deployments generate an exact
|
|
`/api/bot-setup-codes/claim#CODE` endpoint. OpenClaw validates the versioned
|
|
claim response and saves its canonical API base.
|
|
|
|
For manual token setup:
|
|
|
|
```sh
|
|
openclaw channels add clickclack \
|
|
--base-url https://clickclack.example.com \
|
|
--token ccb_... \
|
|
--workspace default
|
|
openclaw gateway
|
|
```
|
|
|
|
Run `openclaw onboard` for guided setup. The workspace value can be a
|
|
`wsp_...` id, slug, or display name.
|
|
|
|
For the default account only, `--use-env` reads `CLICKCLACK_BOT_TOKEN`; config
|
|
storage is the normal setup path.
|
|
|
|
### Public and private endpoints
|
|
|
|
`baseUrl` is the public ClickClack URL used in links that people open. Set the
|
|
optional `apiBaseUrl` when the gateway should call ClickClack through a
|
|
different server-to-server endpoint:
|
|
|
|
```json5
|
|
{
|
|
channels: {
|
|
clickclack: {
|
|
baseUrl: "https://clack.openclaw.ai",
|
|
apiBaseUrl: "http://127.0.0.1:8484",
|
|
token: { source: "env", provider: "default", id: "CLICKCLACK_BOT_TOKEN" },
|
|
workspace: "default",
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
This same-host pattern lets the public hostname stay fully protected by an
|
|
authentication gateway such as Cloudflare Access while the local OpenClaw
|
|
gateway talks directly to ClickClack. REST requests, setup verification, and
|
|
the realtime WebSocket use `apiBaseUrl`; browser-facing discussion links keep
|
|
using `baseUrl`. When `apiBaseUrl` is unset, it defaults to `baseUrl`.
|
|
|
|
## Command menus
|
|
|
|
ClickClack command menus are enabled by default. At gateway startup, the
|
|
extension publishes OpenClaw's native commands for composer autocomplete,
|
|
labeled with the bot's handle. The bot token must include `commands:write`;
|
|
current `bot:write` and `bot:admin` bundles include it.
|
|
|
|
Set `commandMenu: false` on an account to disable menu sync. Sync failures do
|
|
not prevent the gateway from starting, so older tokens and ClickClack servers
|
|
continue to work without a menu.
|
|
|
|
## Discussions
|
|
|
|
ClickClack can create one managed channel for each OpenClaw session:
|
|
|
|
The account token needs `channels:write`, which is included in `bot:admin` but
|
|
not in the normal `bot:write` setup token. The ClickClack server must also
|
|
support and return the managed-channel fields used by this integration.
|
|
|
|
```json5
|
|
{
|
|
channels: {
|
|
clickclack: {
|
|
baseUrl: "https://clickclack.example.com",
|
|
token: { source: "env", provider: "default", id: "CLICKCLACK_BOT_TOKEN" },
|
|
workspace: "default",
|
|
discussions: {
|
|
enabled: true,
|
|
workspace: "default",
|
|
controlUrlBase: "https://team.openclaw.ai",
|
|
section: "Sessions",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
Opening a session discussion creates a public, externally managed channel and
|
|
stores its binding in the ClickClack plugin's SQLite state. Session label and
|
|
category changes remain reflected in the channel, but session archive, restore,
|
|
reset, and deletion never archive or replace it. ClickClack owns channel archive
|
|
and restore independently. `workspace`
|
|
defaults to the account workspace, and `section` defaults to `Sessions`.
|
|
`controlUrlBase` adds canonical `/chat/<agent>/<session-ref>` links to the
|
|
OpenClaw Control UI, preserving base paths. Main sessions use `/chat/<agent>`.
|
|
|
|
ClickClack-managed embed URLs explicitly advertise host-theme support. The
|
|
Control UI uses that provider-owned capability to apply its full palette before
|
|
the sidebar first paints and to stream live palette changes without rewriting
|
|
opaque or signed discussion URLs from other providers.
|
|
|
|
Enable discussions on exactly one ClickClack account. Multiple enabled
|
|
discussion accounts are rejected because the session discussion provider does
|
|
not have an account selector.
|
|
|
|
Messages in the managed channel run in a stable side session under the same
|
|
agent id as the attached main session. The plugin installs a scoped host grant
|
|
for `sessions_history`, `session_status`, and `sessions_send` between that side
|
|
session and its attached main session, so `tools.sessions.visibility` can stay
|
|
at its safer default `tree`. A second host-side policy blocks session discovery
|
|
and alternate targets; the side-agent prompt is not the authorization boundary.
|
|
The agent still needs those three tools in its effective tool allowlist.
|
|
|
|
The binding separates durable room identity from a replaceable exact-session
|
|
attachment. Resetting a reusable session key keeps the ClickClack channel,
|
|
history, URL, and ownership reference while rotating the side-session identity
|
|
and scoped grant. The previous side session cannot access the new main session.
|
|
Messages arriving through an inactive, disabled, or retargeted managed
|
|
binding are dropped instead of falling back to the account's normal channel
|
|
routing. Released bindings leave a durable revoked-channel marker so delayed
|
|
realtime events remain fail-closed. Remote ownership is keyed by ClickClack
|
|
server and channel id, so renaming the local account cannot turn a managed
|
|
channel into an ordinary one.
|
|
|
|
Managed-channel ownership references include a durable per-installation id, so
|
|
two OpenClaw gateways using the same ClickClack workspace do not adopt each
|
|
other's discussion channels. They also include the destination and a durable
|
|
binding generation, so an account or workspace round trip cannot re-adopt a
|
|
previous channel. Changing or removing `controlUrlBase` is reflected on the next
|
|
lifecycle reconciliation pass.
|
|
|
|
If a channel-create response is lost, the pending ownership reservation
|
|
temporarily quarantines otherwise-unbound events in that workspace. The same
|
|
coarse reconciler then adopts the created channel or clears the ambiguous
|
|
attempt; a reset cannot duplicate or archive the durable room.
|
|
|
|
Workspace and account moves release local attachment authority without
|
|
archiving the old channel. A workspace-scoped replacement token is never tried
|
|
against the old channel.
|
|
|
|
The main session gets a read-only `discussion` tool that pulls the latest
|
|
channel messages, including recent thread replies. The pull uses bounded
|
|
history and thread-request budgets; its output says when older active threads
|
|
may have been omitted. It never posts, archives, renames, or otherwise mutates
|
|
the discussion.
|
|
|
|
## Docs
|
|
|
|
See `docs/channels/clickclack.md` in the OpenClaw repository, or the published docs at `https://docs.openclaw.ai/channels/clickclack`.
|