Compare commits

..

57 commits

Author SHA1 Message Date
ef3219810f docs: Add Event Store documentation, tests, and migration script
Some checks failed
CI / install-check (push) Has been cancelled
CI / checks (bunx tsc -p tsconfig.json --noEmit false, bun, build) (push) Has been cancelled
CI / checks (pnpm build && pnpm lint, node, lint) (push) Has been cancelled
CI / checks (pnpm canvas:a2ui:bundle && bunx vitest run, bun, test) (push) Has been cancelled
CI / checks (pnpm canvas:a2ui:bundle && pnpm test, node, test) (push) Has been cancelled
CI / checks (pnpm format, node, format) (push) Has been cancelled
CI / checks (pnpm protocol:check, node, protocol) (push) Has been cancelled
CI / checks (pnpm tsgo, node, tsgo) (push) Has been cancelled
CI / secrets (push) Has been cancelled
CI / checks-windows (pnpm build && pnpm lint, node, build & lint) (push) Has been cancelled
CI / checks-windows (pnpm canvas:a2ui:bundle && pnpm test, node, test) (push) Has been cancelled
CI / checks-windows (pnpm protocol:check, node, protocol) (push) Has been cancelled
CI / checks-macos (pnpm test, test) (push) Has been cancelled
CI / macos-app (set -euo pipefail for attempt in 1 2 3; do if swift build --package-path apps/macos --configuration release; then exit 0 fi echo "swift build failed (attempt $attempt/3). Retrying…" sleep $((attempt * 20)) done exit 1 , build) (push) Has been cancelled
CI / macos-app (set -euo pipefail for attempt in 1 2 3; do if swift test --package-path apps/macos --parallel --enable-code-coverage --show-codecov-path; then exit 0 fi echo "swift test failed (attempt $attempt/3). Retrying…" sleep $((attempt … (push) Has been cancelled
CI / macos-app (swiftlint --config .swiftlint.yml swiftformat --lint apps/macos/Sources --config .swiftformat , lint) (push) Has been cancelled
CI / ios (push) Has been cancelled
CI / android (./gradlew --no-daemon :app:assembleDebug, build) (push) Has been cancelled
CI / android (./gradlew --no-daemon :app:testDebugUnitTest, test) (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
- Add comprehensive docs/features/event-store.md
- Add unit tests for event-store.ts
- Add migration script for existing workspaces
- Update CHANGELOG with new features

Part of Event-Sourced Memory feature (RFC-001)
2026-02-02 17:15:03 +01:00
d40865e2c2 feat(core): Auto-load Event Context on session start (Phase 3)
- Load event context from NATS JetStream on every run
- Inject formatted context into system prompt
- Configurable via gateway.eventStore settings
- Graceful fallback if NATS unavailable

Now every session starts with recent event history!
2026-02-02 17:14:45 +01:00
aea4c823ed feat(prompt): Add eventContextHint parameter for event-sourced memory
System prompt can now include event-based context from NATS JetStream.
Next step: Auto-load context on session start.
2026-02-02 17:14:45 +01:00
37f34e0536 fix(context): Use direct message fetch instead of consumer API
Simpler approach that avoids TypeScript issues with consumer options
2026-02-02 17:14:45 +01:00
093260b47e feat(core): Add Event Context Builder (Phase 2)
- Query events from NATS JetStream
- Extract conversation messages (deduplicated)
- Extract active topics from recent messages
- Format context for system prompt injection
- CLI helper for testing

Phase 2 of RFC-001: Event-Sourced Memory
2026-02-02 17:14:45 +01:00
ba9f76c027 fix(types): Add EventStoreConfig type + fix NATS enum imports 2026-02-02 17:14:45 +01:00
77dbafc77d feat(core): Add Event Store integration with NATS JetStream
Phase 1 of RFC-001: Event-Sourced Memory

- Add event-store.ts module for NATS JetStream integration
- All agent events (messages, tool calls, lifecycle) are published
- Configure via gateway.eventStore in config
- Events are persistent and queryable
- Non-blocking: failures don't affect core functionality

Config example:
  gateway:
    eventStore:
      enabled: true
      natsUrl: nats://localhost:4222
      streamName: openclaw-events
      subjectPrefix: openclaw.events

Co-authored-by: Albert Hild <albert@vainplex.de>
2026-02-02 17:14:45 +01:00
Josh Palmer
991ed3ab58 Tests: stub SSRF DNS pinning (#6619) (thanks @joshp123) 2026-02-02 16:38:25 +01:00
Josh Palmer
5676a6b38d Docs: normalize zh-CN terminology + tone
What: switch to 你/你的 tone; standardize Skills/Gateway网关/local loopback/私信 wording
Why: align zh-CN docs with issue 6995 feedback + idiomatic tech style
Tests: pnpm docs:build
2026-02-02 16:38:25 +01:00
Josh Palmer
2b1f68c928 Docs i18n: tune zh-CN prompt + glossary
What: enforce zh-CN tone (你/你的), Skills/local loopback/Tailscale terms, Gateway网关
Why: keep future translation output consistent with issue feedback
Tests: not run (prompt/glossary change)
2026-02-02 16:38:25 +01:00
Josh Palmer
673583a38b Docs: use explicit ClawHub markdown link
What: switch clawhub.com reference to explicit Markdown link syntax
Why: MDX parser rejects angle-bracket autolinks
Tests: not run (doc text change)
2026-02-02 16:38:25 +01:00
Josh Palmer
b4cce3ac7a Docs: fix zh-CN ClawHub link
What: wrap clawhub.com in an explicit URL link in zh-CN skills doc
Why: avoid Mintlify broken-link parser treating trailing punctuation as part of the URL
Tests: not run (doc text change)
2026-02-02 16:38:25 +01:00
CLAWDINATOR Bot
4023b76ed3 docs: add changelog for zh-CN translations (#6619) (thanks @joshp123) 2026-02-02 16:38:25 +01:00
Josh Palmer
e9d117d221 Docs: fix zh-CN template time wording
What: replace <2/<30 text in zh-CN AGENTS template with safe wording
Why: avoid MDX parse errors during docs build
Tests: not run (doc text change)
2026-02-02 16:38:25 +01:00
Josh Palmer
149dc7c4e7 Docs: add zh-CN translations 2026-02-02 16:38:25 +01:00
Josh Palmer
e70984745b Docs i18n: harden doc-mode pipeline 2026-02-02 16:38:25 +01:00
Shadow
da9f28d270 CI: label maintainer issues 2026-02-02 09:26:46 -06:00
Christian Klotz
99b4f2a24e
fix(telegram): handle Grammy HttpError network failures (#3815) (#7195)
* fix(telegram): handle Grammy HttpError network failures (#3815)

Grammy wraps fetch errors in an .error property (not .cause). Added .error
traversal to collectErrorCandidates in network-errors.ts.

Registered scoped unhandled rejection handler in monitorTelegramProvider
to catch network errors that escape the polling loop (e.g., from setMyCommands
during bot setup). Handler is unregistered when the provider stops.

* fix(telegram): address review feedback for Grammy HttpError handling

- Gate .error traversal on HttpError name to avoid widening search graph
- Use runtime logger instead of console.warn for consistency
- Add isGrammyHttpError check to scope unhandled rejection handler
- Consolidate isNetworkRelatedError into isRecoverableTelegramNetworkError
- Add 'timeout' to recoverable message snippets for full coverage
2026-02-02 15:25:41 +00:00
Peter Steinberger
f9fae2c439 fix: stabilize docker e2e flows 2026-02-02 13:11:55 +00:00
Peter Steinberger
9bd64c8a1f fix: expand SSRF guard coverage 2026-02-02 04:58:32 -08:00
cpojer
c429ccb64f
chore: fix broken test. 2026-02-02 21:51:37 +09:00
Peter Steinberger
57d008a33d fix(update): harden global updates 2026-02-02 04:45:14 -08:00
cpojer
6b0d6e2540
chore: We have a sleep at home. The sleep at home: 2026-02-02 21:44:02 +09:00
Peter Steinberger
dfef943f0a fix: polish docker setup flow 2026-02-02 04:26:03 -08:00
Peter Steinberger
39c682219e test: cover SSRF blocking for attachment URLs 2026-02-02 04:21:10 -08:00
Ayaan Zaidi
66307695eb fix: start gateway in docker CMD (#6635) (thanks @kaizen403) 2026-02-02 17:38:37 +05:30
Ayaan Zaidi
d134a8c7f3 docs: note docker allow-unconfigured behavior 2026-02-02 17:38:37 +05:30
Rishi Vhavle
bb3d7343f4 fix(docker): remove --bind lan from default CMD to work out of the box
Addresses review feedback: --bind lan requires auth token, so default
CMD should bind to loopback only.

For container platforms needing LAN binding for health checks:
1. Set OPENCLAW_GATEWAY_TOKEN env var
2. Override CMD: ["node","dist/index.js","gateway","--allow-unconfigured","--bind","lan"]
2026-02-02 17:38:37 +05:30
Rishi Vhavle
1a05ee941e fix(docker): add gateway subcommand and cloud-compatible flags
The Dockerfile CMD runs without arguments, causing the CLI to print
help and exit with code 1. This breaks deployment on container
platforms (Render, Railway, Fly.io, etc.) that rely on the CMD.

Changes:
- Add `gateway` subcommand to start the server
- Add `--allow-unconfigured` to allow startup without config file
- Add `--bind lan` to bind to 0.0.0.0 instead of localhost
  (required for container health checks)

Fixes #5685
2026-02-02 17:38:37 +05:30
Peter Steinberger
1b3f987c4d style: format fetch guard signatures 2026-02-02 04:07:29 -08:00
Peter Steinberger
81c68f582d fix: guard remote media fetches with SSRF checks 2026-02-02 04:07:29 -08:00
Peter Steinberger
d842b28a15 docs: update appcast for 2026.2.1 2026-02-02 03:53:21 -08:00
Peter Steinberger
ed4529e246 docs: update 2026.2.1 changelog 2026-02-02 03:25:32 -08:00
Peter Steinberger
bf08b485bd fix: satisfy tool adapter lint 2026-02-02 03:14:34 -08:00
Peter Steinberger
845d97b6a5 fix: handle legacy tool execute signatures 2026-02-02 02:51:52 -08:00
Peter Steinberger
8b64705e05 docs: fold 2026.2.2 into 2026.2.1 2026-02-02 02:43:54 -08:00
Peter Steinberger
bcb0ed0866 fix: normalize tool execute args 2026-02-02 02:41:21 -08:00
Peter Steinberger
9ae1b732ef fix: align tool definition adapter 2026-02-02 02:28:22 -08:00
Peter Steinberger
385e66cbd5 Docs: expand ClawHub overview 2026-02-02 02:26:11 -08:00
Peter Steinberger
2d317ce423 fix: align tool execute parameter order 2026-02-02 10:20:13 +00:00
Peter Steinberger
284d24209b fix: align tool execute signature 2026-02-02 10:14:29 +00:00
Peter Steinberger
b8174decf3 fix: resolve system prompt overrides 2026-02-02 02:10:13 -08:00
Peter Steinberger
41cc5bcd4f fix: gate Teams media auth retries 2026-02-02 02:08:13 -08:00
Peter Steinberger
f6d98a908a docs: add changelog entry for plugin install hardening 2026-02-02 02:07:47 -08:00
Peter Steinberger
d03eca8450 fix: harden plugin and hook install paths 2026-02-02 02:07:47 -08:00
Peter Steinberger
be9a2fb134 docs: clarify docker power-user setup 2026-02-02 02:07:08 -08:00
Tyler Yust
8d2f98fb01
Fix subagent announce failover race (always emit lifecycle end + treat timeout=0 as no-timeout) (#6621)
* Fix subagent announce race and timeout handling

Bug 1: Subagent announce fires before model failover retries finish
- Problem: CLI provider emitted lifecycle error on each attempt, causing
  subagent registry to prematurely call beginSubagentCleanup() and announce
  with incorrect status before failover retries completed
- Fix: Removed lifecycle error emission from CLI provider's attempt-level
  .catch() in agent-runner-execution.ts. Errors still propagate to
  runWithModelFallback for retry, but no intermediate lifecycle events
  are emitted. Only the final outcome (after all retries) emits lifecycle
  events.

Bug 2: Hard 600s per-prompt timeout ignores runTimeoutSeconds=0
- Problem: When runTimeoutSeconds=0 (meaning 'no timeout'), the code
  returned the default 600s timeout instead of respecting the 0 setting
- Fix: Modified resolveAgentTimeoutMs() to treat 0 as 'no timeout' and
  return a very large timeout value (30 days) instead of the default.
  This avoids setTimeout issues with Infinity while effectively providing
  unlimited time for long-running tasks.

* fix: emit lifecycle:error for CLI failures (#6621) (thanks @tyler6204)

* chore: satisfy format/lint gates (#6621) (thanks @tyler6204)

* fix: restore build after upstream type changes (#6621) (thanks @tyler6204)

* test: fix createSystemPromptOverride tests to match new return type (#6621) (thanks @tyler6204)
2026-02-02 02:06:14 -08:00
Peter Steinberger
d5f6caba3f docs: merge 2026.2.2 changelog into 2026.2.1 2026-02-02 01:31:24 -08:00
Peter Steinberger
4682c2e3e2 docs: add ClawHub registry overview 2026-02-02 01:26:29 -08:00
Peter Steinberger
34dd7324d9 fix: restore lint/build gates 2026-02-02 01:25:40 -08:00
Tyler Yust
9ef24fd400
fix: flush block streaming on paragraph boundaries for chunkMode=newline (#7014)
* feat: Implement paragraph boundary flushing in block streaming

- Added `flushOnParagraph` option to `BlockReplyChunking` for immediate flushing on paragraph breaks.
- Updated `EmbeddedBlockChunker` to handle paragraph boundaries during chunking.
- Enhanced `createBlockReplyCoalescer` to support flushing on enqueue.
- Added tests to verify behavior of flushing with and without `flushOnEnqueue` set.
- Updated relevant types and interfaces to include `flushOnParagraph` and `flushOnEnqueue` options.

* fix: Improve streaming behavior and enhance block chunking logic

- Resolved issue with stuck typing indicator after streamed BlueBubbles replies.
- Refactored `EmbeddedBlockChunker` to streamline fence-split handling and ensure maxChars fallback for newline chunking.
- Added tests to validate new chunking behavior, including handling of paragraph breaks and fence scenarios.
- Updated changelog to reflect these changes.

* test: Add test for clamping long paragraphs in EmbeddedBlockChunker

- Introduced a new test case to verify that long paragraphs are correctly clamped to maxChars when flushOnParagraph is enabled.
- Updated logic in EmbeddedBlockChunker to handle cases where the next paragraph break exceeds maxChars, ensuring proper chunking behavior.

* refactor: streamline logging and improve error handling in message processing

- Removed verbose logging statements from the `processMessage` function to reduce clutter.
- Enhanced error handling by using `runtime.error` for typing restart failures.
- Updated the `applySystemPromptOverrideToSession` function to accept a string directly instead of a function, simplifying the prompt application process.
- Adjusted the `runEmbeddedAttempt` function to directly use the system prompt override without invoking it as a function.
2026-02-02 01:22:41 -08:00
Peter Steinberger
85cd55e22b chore: bump to 2026.2.1 2026-02-02 08:51:54 +00:00
David Iach
4e4ed2ea17
fix(security): cap Slack media downloads and validate Slack file URLs (#6639)
* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-02 00:48:07 -08:00
Peter Steinberger
521b121815 fix: treat '*' tool allowlist as valid 2026-02-02 08:45:51 +00:00
vignesh07
e74235fdce ci(formal): compute drift for generated/ before model checking 2026-02-02 00:43:28 -08:00
vignesh07
f37b79cf4f ci(formal): add routing-trirule + proxy-header-spoof targets 2026-02-02 00:43:28 -08:00
vignesh07
889480cef9 ci(formal): include latest reliability/conformance model targets 2026-02-02 00:43:28 -08:00
467 changed files with 71567 additions and 849 deletions

View file

@ -37,6 +37,22 @@ jobs:
node scripts/extract-tool-groups.mjs
node scripts/check-tool-group-alias.mjs
# Drift is about extracted artifacts only; compute it before model checking
# to avoid any incidental file touches affecting the result.
- name: Compute drift (generated/*)
id: drift
run: |
set -euo pipefail
cd clawdbot-formal-models
if git diff --quiet -- generated; then
echo "drift=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "drift=true" >> "$GITHUB_OUTPUT"
git diff -- generated > "${GITHUB_WORKSPACE}/formal-models-drift.diff"
- name: Model check (green suite)
run: |
set -euo pipefail
@ -51,6 +67,10 @@ jobs:
routing-isolation routing-precedence routing-identitylinks routing-identity-transitive routing-identity-symmetry routing-identity-channel-override \
routing-thread-parent discord-pluralkit \
ingress-retry session-key-stability session-explosion-bound config-normalization \
queue-drain delivery-route-stability delivery-pipeline retry-termination retry-eventual-success \
no-cross-stream multi-event-eventual-emission \
dedupe-collision-fallback crash-restart-dedupe two-worker-dedupe openclaw-session-key-conformance \
routing-thread-parent-channel-override routing-trirule gateway-auth-proxy-header-spoof \
group-alias-check
- name: Model check (negative suite, expected violations)
@ -69,21 +89,11 @@ jobs:
ingress-gating-negative ingress-idempotency-negative ingress-dedupe-fallback-negative ingress-trace-negative ingress-trace2-negative \
routing-isolation-negative routing-precedence-negative routing-identitylinks-negative routing-identity-transitive-negative routing-identity-symmetry-negative routing-identity-channel-override-negative \
routing-thread-parent-negative discord-pluralkit-negative \
ingress-retry-negative session-key-stability-negative config-normalization-negative
- name: Compute drift
id: drift
run: |
set -euo pipefail
cd clawdbot-formal-models
if git diff --quiet; then
echo "drift=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "drift=true" >> "$GITHUB_OUTPUT"
git diff > "${GITHUB_WORKSPACE}/formal-models-drift.diff"
ingress-retry-negative session-key-stability-negative config-normalization-negative \
queue-drain delivery-route-stability-negative delivery-pipeline-negative retry-termination-negative retry-eventual-success-negative \
no-cross-stream-negative multi-event-eventual-emission-negative \
dedupe-collision-fallback-negative crash-restart-dedupe-negative two-worker-dedupe-negative openclaw-session-key-conformance-negative \
routing-thread-parent-channel-override-negative routing-trirule-negative gateway-auth-proxy-header-spoof-negative
- name: Upload drift diff artifact
if: steps.drift.outputs.drift == 'true'

View file

@ -3,6 +3,8 @@ name: Labeler
on:
pull_request_target:
types: [opened, synchronize, reopened]
issues:
types: [opened]
permissions: {}
@ -23,3 +25,56 @@ jobs:
configuration-path: .github/labeler.yml
repo-token: ${{ steps.app-token.outputs.token }}
sync-labels: true
- name: Apply maintainer label for org members
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const association = context.payload.pull_request?.author_association;
if (!association) {
return;
}
if (![
"MEMBER",
"OWNER",
].includes(association)) {
return;
}
await github.rest.issues.addLabels({
...context.repo,
issue_number: context.payload.pull_request.number,
labels: ["maintainer"],
});
label-issues:
permissions:
issues: write
runs-on: ubuntu-latest
steps:
- uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
id: app-token
with:
app-id: "2729701"
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Apply maintainer label for org members
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const association = context.payload.issue?.author_association;
if (!association) {
return;
}
if (![
"MEMBER",
"OWNER",
].includes(association)) {
return;
}
await github.rest.issues.addLabels({
...context.repo,
issue_number: context.payload.issue.number,
labels: ["maintainer"],
});

View file

@ -16,6 +16,7 @@
"oxc/no-map-spread": "off",
"typescript/no-explicit-any": "error",
"typescript/no-extraneous-class": "off",
"typescript/no-redundant-type-constituents": "off",
"typescript/no-unsafe-type-assertion": "off",
"unicorn/consistent-function-scoping": "off",
"unicorn/require-post-message-target-origin": "off"

View file

@ -4,38 +4,137 @@ Docs: https://docs.openclaw.ai
## 2026.2.2
### Features
- **Event Store**: Add NATS JetStream integration for event-sourced memory. All agent events (messages, tool calls, lifecycle) are persisted and queryable. Configure via `gateway.eventStore`. (#RFC-001) Thanks @alberth, @claudia-keller.
- **Event Context**: Automatically inject recent event history into session context on startup. Agents now remember recent conversations without manual file management.
- **Multi-Agent Event Isolation**: Support per-agent event streams with `eventStore.agents` config. Each agent can have isolated credentials and streams.
### Changes
- Docs: seed zh-CN translations. (#6619) Thanks @joshp123.
### Fixes
- Security: guard skill installer downloads with SSRF checks (block private/localhost URLs).
- Media understanding: apply SSRF guardrails to provider fetches; allow private baseUrl overrides explicitly.
- Tests: stub SSRF DNS pinning in web auto-reply + Gemini video coverage. (#6619) Thanks @joshp123.
- Tests: stub SSRF DNS pinning in web auto-reply + Gemini video coverage. (#6619) Thanks @joshp123.
## 2026.2.1
### Changes
- Docs: onboarding/install/i18n/exec-approvals/Control UI/exe.dev/cacheRetention updates + misc nav/typos. (#3050, #3461, #4064, #4675, #4729, #4763, #5003, #5402, #5446, #5474, #5663, #5689, #5694, #5967, #6270, #6300, #6311, #6416, #6487, #6550, #6789)
- Telegram: use shared pairing store. (#6127) Thanks @obviyus.
- Agents: add OpenRouter app attribution headers. Thanks @alexanderatallah.
- Agents: add system prompt safety guardrails. (#5445) Thanks @joshp123.
- Agents: update pi-ai to 0.50.9 and rename cacheControlTtl -> cacheRetention (with back-compat mapping).
- Agents: extend CreateAgentSessionOptions with systemPrompt/skills/contextFiles.
- Agents: add tool policy conformance snapshot (no runtime behavior change). (#6011)
- Auth: update MiniMax OAuth hint + portal auth note copy.
- Discord: inherit thread parent bindings for routing. (#3892) Thanks @aerolalit.
- Gateway: inject timestamps into agent and chat.send messages. (#3705) Thanks @conroywhitney, @CashWilliams.
- Gateway: require TLS 1.3 minimum for TLS listeners. (#5970) Thanks @loganaden.
- Web UI: refine chat layout + extend session active duration.
- CI: add formal conformance + alias consistency checks. (#5723, #5807)
### Fixes
- Security: guard remote media fetches with SSRF protections (block private/localhost, DNS pinning).
- Updates: clean stale global install rename dirs and extend gateway update timeouts to avoid npm ENOTEMPTY failures.
- Plugins: validate plugin/hook install paths and reject traversal-like names.
- Telegram: add download timeouts for file fetches. (#6914) Thanks @hclsys.
- Telegram: enforce thread specs for DM vs forum sends. (#6833) Thanks @obviyus.
- Streaming: flush block streaming on paragraph boundaries for newline chunking. (#7014)
- Streaming: stabilize partial streaming filters.
- Auto-reply: avoid referencing workspace files in /new greeting prompt. (#5706) Thanks @bravostation.
- Tools: align tool execute adapters/signatures (legacy + parameter order + arg normalization).
- Tools: treat "*" tool allowlist entries as valid to avoid spurious unknown-entry warnings.
- Skills: update session-logs paths from .clawdbot to .openclaw. (#4502)
- Slack: harden media fetch limits and Slack file URL validation. (#6639) Thanks @davidiach.
- Lint: satisfy curly rule after import sorting. (#6310)
- Process: resolve Windows `spawn()` failures for npm-family CLIs by appending `.cmd` when needed. (#5815) Thanks @thejhinvirtuoso.
- Discord: resolve PluralKit proxied senders for allowlists and labels. (#5838) Thanks @thewilloftheshadow.
- Tlon: add timeout to SSE client fetch calls (CWE-400). (#5926)
- Memory search: L2-normalize local embedding vectors to fix semantic search. (#5332)
- Agents: align embedded runner + typings with pi-coding-agent API updates (pi 0.51.0).
- Agents: ensure OpenRouter attribution headers apply in the embedded runner.
- Agents: cap context window resolution for compaction safeguard. (#6187) Thanks @iamEvanYT.
- System prompt: resolve overrides and hint using session_status for current date/time. (#1897, #1928, #2108, #3677)
- Agents: fix Pi prompt template argument syntax. (#6543)
- Subagents: fix announce failover race (always emit lifecycle end; timeout=0 means no-timeout). (#6621)
- Teams: gate media auth retries.
- Telegram: restore draft streaming partials. (#5543) Thanks @obviyus.
- Onboarding: friendlier Windows onboarding message. (#6242) Thanks @shanselman.
- TUI: prevent crash when searching with digits in the model selector.
- Agents: wire before_tool_call plugin hook into tool execution. (#6570, #6660) Thanks @ryancnelson.
- Browser: secure Chrome extension relay CDP sessions.
- Docker: use container port for gateway command instead of host port. (#5110) Thanks @mise42.
- Docker: start gateway CMD by default for container deployments. (#6635) Thanks @kaizen403.
- fix(lobster): block arbitrary exec via lobsterPath/cwd injection (GHSA-4mhr-g7xj-cg8j). (#5335) Thanks @vignesh07.
- Security: sanitize WhatsApp accountId to prevent path traversal. (#4610)
- Security: restrict MEDIA path extraction to prevent LFI. (#4930)
- Security: validate message-tool filePath/path against sandbox root. (#6398)
- Security: block LD*/DYLD* env overrides for host exec. (#4896) Thanks @HassanFleyah.
- Security: harden web tool content wrapping + file parsing safeguards. (#4058) Thanks @VACInc.
- Security: enforce Twitch `allowFrom` allowlist gating (deny non-allowlisted senders). Thanks @MegaManSec.
## 2026.1.31
### Changes
- Docs: onboarding/install/i18n/exec-approvals/Control UI/exe.dev/cacheRetention updates + misc nav/typos.
- Docs: onboarding/install/i18n/exec-approvals/Control UI/exe.dev/cacheRetention updates + misc nav/typos. (#3050, #3461, #4064, #4675, #4729, #4763, #5003, #5402, #5446, #5474, #5663, #5689, #5694, #5967, #6270, #6300, #6311, #6416, #6487, #6550, #6789)
- Telegram: use shared pairing store. (#6127) Thanks @obviyus.
- Agents: add OpenRouter app attribution headers. (#5050) Thanks @alexanderatallah.
- Agents: add OpenRouter app attribution headers. Thanks @alexanderatallah.
- Agents: add system prompt safety guardrails. (#5445) Thanks @joshp123.
- Agents: update pi-ai to 0.50.9 and rename cacheControlTtl -> cacheRetention (with back-compat mapping).
- Agents: extend CreateAgentSessionOptions with systemPrompt/skills/contextFiles.
- Agents: add tool policy conformance snapshot (no runtime behavior change). (#6011)
- Auth: update MiniMax OAuth hint + portal auth note copy.
- Discord: inherit thread parent bindings for routing. (#3892) Thanks @aerolalit.
- Gateway: inject timestamps into agent and chat.send messages. (#3705) Thanks @conroywhitney, @CashWilliams.
- Gateway: require TLS 1.3 minimum for TLS listeners. (#5970) Thanks @loganaden.
- Web UI: refine chat layout + extend session active duration.
- CI: add formal conformance + alias consistency checks. (#5723, #5807)
### Fixes
- Security: guard remote media fetches with SSRF protections (block private/localhost, DNS pinning).
- Updates: clean stale global install rename dirs and extend gateway update timeouts to avoid npm ENOTEMPTY failures.
- Plugins: validate plugin/hook install paths and reject traversal-like names.
- Telegram: add download timeouts for file fetches. (#6914) Thanks @hclsys.
- Telegram: enforce thread specs for DM vs forum sends. (#6833) Thanks @obviyus.
- Streaming: flush block streaming on paragraph boundaries for newline chunking. (#7014)
- Streaming: stabilize partial streaming filters.
- Auto-reply: avoid referencing workspace files in /new greeting prompt. (#5706) Thanks @bravostation.
- Tools: align tool execute adapters/signatures (legacy + parameter order + arg normalization).
- Tools: treat `"*"` tool allowlist entries as valid to avoid spurious unknown-entry warnings.
- Skills: update session-logs paths from .clawdbot to .openclaw. (#4502)
- Slack: harden media fetch limits and Slack file URL validation. (#6639) Thanks @davidiach.
- Lint: satisfy curly rule after import sorting. (#6310)
- Process: resolve Windows `spawn()` failures for npm-family CLIs by appending `.cmd` when needed. (#5815) Thanks @thejhinvirtuoso.
- Discord: resolve PluralKit proxied senders for allowlists and labels. (#5838) Thanks @thewilloftheshadow.
- Tlon: add timeout to SSE client fetch calls (CWE-400). (#5926)
- Memory search: L2-normalize local embedding vectors to fix semantic search. (#5332)
- Agents: align embedded runner + typings with pi-coding-agent API updates (pi 0.51.0).
- Agents: ensure OpenRouter attribution headers apply in the embedded runner.
- Agents: cap context window resolution for compaction safeguard. (#6187) Thanks @iamEvanYT.
- System prompt: hint using session_status for current date/time. (#1897, #1928, #2108)
- System prompt: resolve overrides and hint using session_status for current date/time. (#1897, #1928, #2108, #3677)
- Agents: fix Pi prompt template argument syntax. (#6543)
- Subagents: fix announce failover race (always emit lifecycle end; timeout=0 means no-timeout). (#6621)
- Teams: gate media auth retries.
- Telegram: restore draft streaming partials. (#5543) Thanks @obviyus.
- Onboarding: friendlier Windows onboarding message. (#6242) Thanks @shanselman.
- TUI: prevent crash when searching with digits in the model selector.
- Agents: wire before_tool_call plugin hook into tool execution. (#6570) Thanks @ryancnelson.
- Agents: wire before_tool_call plugin hook into tool execution. (#6570, #6660) Thanks @ryancnelson.
- Browser: secure Chrome extension relay CDP sessions.
- Docker: use container port for gateway command instead of host port. (#5110) Thanks @mise42.
- Docker: start gateway CMD by default for container deployments. (#6635) Thanks @kaizen403.
- fix(lobster): block arbitrary exec via lobsterPath/cwd injection (GHSA-4mhr-g7xj-cg8j). (#5335) Thanks @vignesh07.
- Security: sanitize WhatsApp accountId to prevent path traversal. (#4610)
- Security: restrict MEDIA path extraction to prevent LFI. (#4930)
- Security: validate message-tool filePath/path against sandbox root. (#6398)
- Security: block LD*/DYLD* env overrides for host exec. (#4896) Thanks @HassanFleyah.
- Security: harden web tool content wrapping + file parsing safeguards. (#4058) Thanks @VACInc.
- Security: enforce Twitch `allowFrom` allowlist gating (deny non-allowlisted senders). Thanks @MegaManSec.
@ -50,11 +149,11 @@ Docs: https://docs.openclaw.ai
- Auth: switch Kimi Coding to built-in provider; normalize OAuth profile email.
- Auth: add MiniMax OAuth plugin + onboarding option. (#4521) Thanks @Maosghoul.
- Agents: update pi SDK/API usage and dependencies.
- Gateway: inject timestamps into agent and chat.send messages. (#3705) Thanks @conroywhitney, @CashWilliams.
- Web UI: refresh sessions after chat commands and improve session display names.
- Build: move TypeScript builds to `tsdown` + `tsgo` (faster builds, CI typechecks), update tsconfig target, and clean up lint rules.
- Build: align npm tar override and bin metadata so the `openclaw` CLI entrypoint is preserved in npm publishes.
- Docs: add pi/pi-dev docs and update OpenClaw branding + install links.
- Docker E2E: stabilize gateway readiness, plugin installs/manifests, and cleanup/doctor switch entrypoint checks.
### Fixes

View file

@ -31,9 +31,18 @@ RUN pnpm ui:build
ENV NODE_ENV=production
# Allow non-root user to write temp files during runtime/tests.
RUN chown -R node:node /app
# Security hardening: Run as non-root user
# The node:22-bookworm image includes a 'node' user (uid 1000)
# This reduces the attack surface by preventing container escape via root privileges
USER node
CMD ["node", "dist/index.js"]
# Start gateway server with default config.
# Binds to loopback (127.0.0.1) by default for security.
#
# For container platforms requiring external health checks:
# 1. Set OPENCLAW_GATEWAY_TOKEN or OPENCLAW_GATEWAY_PASSWORD env var
# 2. Override CMD: ["node","dist/index.js","gateway","--allow-unconfigured","--bind","lan"]
CMD ["node", "dist/index.js", "gateway", "--allow-unconfigured"]

View file

@ -2,6 +2,72 @@
<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" version="2.0">
<channel>
<title>OpenClaw</title>
<item>
<title>2026.2.1</title>
<pubDate>Mon, 02 Feb 2026 03:53:03 -0800</pubDate>
<link>https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml</link>
<sparkle:version>8650</sparkle:version>
<sparkle:shortVersionString>2026.2.1</sparkle:shortVersionString>
<sparkle:minimumSystemVersion>15.0</sparkle:minimumSystemVersion>
<description><![CDATA[<h2>OpenClaw 2026.2.1</h2>
<h3>Changes</h3>
<ul>
<li>Docs: onboarding/install/i18n/exec-approvals/Control UI/exe.dev/cacheRetention updates + misc nav/typos. (#3050, #3461, #4064, #4675, #4729, #4763, #5003, #5402, #5446, #5474, #5663, #5689, #5694, #5967, #6270, #6300, #6311, #6416, #6487, #6550, #6789)</li>
<li>Telegram: use shared pairing store. (#6127) Thanks @obviyus.</li>
<li>Agents: add OpenRouter app attribution headers. Thanks @alexanderatallah.</li>
<li>Agents: add system prompt safety guardrails. (#5445) Thanks @joshp123.</li>
<li>Agents: update pi-ai to 0.50.9 and rename cacheControlTtl -> cacheRetention (with back-compat mapping).</li>
<li>Agents: extend CreateAgentSessionOptions with systemPrompt/skills/contextFiles.</li>
<li>Agents: add tool policy conformance snapshot (no runtime behavior change). (#6011)</li>
<li>Auth: update MiniMax OAuth hint + portal auth note copy.</li>
<li>Discord: inherit thread parent bindings for routing. (#3892) Thanks @aerolalit.</li>
<li>Gateway: inject timestamps into agent and chat.send messages. (#3705) Thanks @conroywhitney, @CashWilliams.</li>
<li>Gateway: require TLS 1.3 minimum for TLS listeners. (#5970) Thanks @loganaden.</li>
<li>Web UI: refine chat layout + extend session active duration.</li>
<li>CI: add formal conformance + alias consistency checks. (#5723, #5807)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li>Plugins: validate plugin/hook install paths and reject traversal-like names.</li>
<li>Telegram: add download timeouts for file fetches. (#6914) Thanks @hclsys.</li>
<li>Telegram: enforce thread specs for DM vs forum sends. (#6833) Thanks @obviyus.</li>
<li>Streaming: flush block streaming on paragraph boundaries for newline chunking. (#7014)</li>
<li>Streaming: stabilize partial streaming filters.</li>
<li>Auto-reply: avoid referencing workspace files in /new greeting prompt. (#5706) Thanks @bravostation.</li>
<li>Tools: align tool execute adapters/signatures (legacy + parameter order + arg normalization).</li>
<li>Tools: treat <code>"*"</code> tool allowlist entries as valid to avoid spurious unknown-entry warnings.</li>
<li>Skills: update session-logs paths from .clawdbot to .openclaw. (#4502)</li>
<li>Slack: harden media fetch limits and Slack file URL validation. (#6639) Thanks @davidiach.</li>
<li>Lint: satisfy curly rule after import sorting. (#6310)</li>
<li>Process: resolve Windows <code>spawn()</code> failures for npm-family CLIs by appending <code>.cmd</code> when needed. (#5815) Thanks @thejhinvirtuoso.</li>
<li>Discord: resolve PluralKit proxied senders for allowlists and labels. (#5838) Thanks @thewilloftheshadow.</li>
<li>Tlon: add timeout to SSE client fetch calls (CWE-400). (#5926)</li>
<li>Memory search: L2-normalize local embedding vectors to fix semantic search. (#5332)</li>
<li>Agents: align embedded runner + typings with pi-coding-agent API updates (pi 0.51.0).</li>
<li>Agents: ensure OpenRouter attribution headers apply in the embedded runner.</li>
<li>Agents: cap context window resolution for compaction safeguard. (#6187) Thanks @iamEvanYT.</li>
<li>System prompt: resolve overrides and hint using session_status for current date/time. (#1897, #1928, #2108, #3677)</li>
<li>Agents: fix Pi prompt template argument syntax. (#6543)</li>
<li>Subagents: fix announce failover race (always emit lifecycle end; timeout=0 means no-timeout). (#6621)</li>
<li>Teams: gate media auth retries.</li>
<li>Telegram: restore draft streaming partials. (#5543) Thanks @obviyus.</li>
<li>Onboarding: friendlier Windows onboarding message. (#6242) Thanks @shanselman.</li>
<li>TUI: prevent crash when searching with digits in the model selector.</li>
<li>Agents: wire before_tool_call plugin hook into tool execution. (#6570, #6660) Thanks @ryancnelson.</li>
<li>Browser: secure Chrome extension relay CDP sessions.</li>
<li>Docker: use container port for gateway command instead of host port. (#5110) Thanks @mise42.</li>
<li>fix(lobster): block arbitrary exec via lobsterPath/cwd injection (GHSA-4mhr-g7xj-cg8j). (#5335) Thanks @vignesh07.</li>
<li>Security: sanitize WhatsApp accountId to prevent path traversal. (#4610)</li>
<li>Security: restrict MEDIA path extraction to prevent LFI. (#4930)</li>
<li>Security: validate message-tool filePath/path against sandbox root. (#6398)</li>
<li>Security: block LD*/DYLD* env overrides for host exec. (#4896) Thanks @HassanFleyah.</li>
<li>Security: harden web tool content wrapping + file parsing safeguards. (#4058) Thanks @VACInc.</li>
<li>Security: enforce Twitch <code>allowFrom</code> allowlist gating (deny non-allowlisted senders). Thanks @MegaManSec.</li>
</ul>
<p><a href="https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md">View full changelog</a></p>
]]></description>
<enclosure url="https://github.com/openclaw/openclaw/releases/download/v2026.2.1/OpenClaw-2026.2.1.zip" length="22458919" type="application/octet-stream" sparkle:edSignature="kA/8VQlVdtYphcB1iuFrhWczwWKgkVZMfDfQ7T9WD405D8JKTv5CZ1n8lstIVkpk4xog3UhrfaaoTG8Bf8DMAQ=="/>
</item>
<item>
<title>2026.1.30</title>
<pubDate>Sat, 31 Jan 2026 14:29:57 +0100</pubDate>
@ -179,21 +245,5 @@ Status: stable.
]]></description>
<enclosure url="https://github.com/openclaw/openclaw/releases/download/v2026.1.29/OpenClaw-2026.1.29.zip" length="22458204" type="application/octet-stream" sparkle:edSignature="HqHwZHQyG/CEfBuQnQ/RffJQPKpSbCVrho9C6rgt93S5ek4AH6hUhB3BBKY8sbX1IVFATKK5QZZNE0YPAf7eBw=="/>
</item>
<item>
<title>2026.1.24-1</title>
<pubDate>Sun, 25 Jan 2026 14:05:25 +0000</pubDate>
<link>https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml</link>
<sparkle:version>7952</sparkle:version>
<sparkle:shortVersionString>2026.1.24-1</sparkle:shortVersionString>
<sparkle:minimumSystemVersion>15.0</sparkle:minimumSystemVersion>
<description><![CDATA[<h2>OpenClaw 2026.1.24-1</h2>
<h3>Fixes</h3>
<ul>
<li>Packaging: include dist/shared output in npm tarball (fixes missing reasoning-tags import on install).</li>
</ul>
<p><a href="https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md">View full changelog</a></p>
]]></description>
<enclosure url="https://github.com/openclaw/openclaw/releases/download/v2026.1.24-1/OpenClaw-2026.1.24-1.zip" length="12396699" type="application/octet-stream" sparkle:edSignature="VaEdWIgEJBrZLIp2UmigoQ6vaq4P/jNFXpHYXvXHD5MsATS0CqBl6ugyyxRq+/GbpUqmdgdlht4dTUVbLRw6BA=="/>
</item>
</channel>
</rss>

View file

@ -21,8 +21,8 @@ android {
applicationId = "ai.openclaw.android"
minSdk = 31
targetSdk = 36
versionCode = 202601290
versionName = "2026.1.30"
versionCode = 202602010
versionName = "2026.2.1"
}
buildTypes {

View file

@ -19,9 +19,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2026.1.30</string>
<string>2026.2.1</string>
<key>CFBundleVersion</key>
<string>20260129</string>
<string>20260201</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoadsInWebContent</key>

View file

@ -17,8 +17,8 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>2026.1.30</string>
<string>2026.2.1</string>
<key>CFBundleVersion</key>
<string>20260129</string>
<string>20260201</string>
</dict>
</plist>

View file

@ -81,8 +81,8 @@ targets:
properties:
CFBundleDisplayName: OpenClaw
CFBundleIconName: AppIcon
CFBundleShortVersionString: "2026.1.27-beta.1"
CFBundleVersion: "20260126"
CFBundleShortVersionString: "2026.2.1"
CFBundleVersion: "20260201"
UILaunchScreen: {}
UIApplicationSceneManifest:
UIApplicationSupportsMultipleScenes: false
@ -130,5 +130,5 @@ targets:
path: Tests/Info.plist
properties:
CFBundleDisplayName: OpenClawTests
CFBundleShortVersionString: "2026.1.27-beta.1"
CFBundleVersion: "20260126"
CFBundleShortVersionString: "2026.2.1"
CFBundleVersion: "20260201"

View file

@ -15,9 +15,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2026.1.30</string>
<string>2026.2.1</string>
<key>CFBundleVersion</key>
<string>202601290</string>
<string>202602010</string>
<key>CFBundleIconFile</key>
<string>OpenClaw</string>
<key>CFBundleURLTypes</key>

View file

@ -32,6 +32,7 @@ services:
environment:
HOME: /home/node
TERM: xterm-256color
OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN}
BROWSER: echo
CLAUDE_AI_SESSION_KEY: ${CLAUDE_AI_SESSION_KEY}
CLAUDE_WEB_SESSION_KEY: ${CLAUDE_WEB_SESSION_KEY}

View file

@ -191,12 +191,12 @@ docker compose "${COMPOSE_ARGS[@]}" run --rm openclaw-cli onboard --no-install-d
echo ""
echo "==> Provider setup (optional)"
echo "WhatsApp (QR):"
echo " ${COMPOSE_HINT} run --rm openclaw-cli providers login"
echo " ${COMPOSE_HINT} run --rm openclaw-cli channels login"
echo "Telegram (bot token):"
echo " ${COMPOSE_HINT} run --rm openclaw-cli providers add --provider telegram --token <token>"
echo " ${COMPOSE_HINT} run --rm openclaw-cli channels add --channel telegram --token <token>"
echo "Discord (bot token):"
echo " ${COMPOSE_HINT} run --rm openclaw-cli providers add --provider discord --token <token>"
echo "Docs: https://docs.openclaw.ai/providers"
echo " ${COMPOSE_HINT} run --rm openclaw-cli channels add --channel discord --token <token>"
echo "Docs: https://docs.openclaw.ai/channels"
echo ""
echo "==> Starting gateway"

View file

@ -5,12 +5,60 @@
},
{
"source": "Gateway",
"target": "Gateway"
"target": "Gateway网关"
},
{
"source": "Pi",
"target": "Pi"
},
{
"source": "Skills",
"target": "Skills"
},
{
"source": "Skills config",
"target": "Skills配置"
},
{
"source": "Skills Config",
"target": "Skills配置"
},
{
"source": "local loopback",
"target": "local loopback"
},
{
"source": "Tailscale",
"target": "Tailscale"
},
{
"source": "Getting Started",
"target": "入门指南"
},
{
"source": "Getting started",
"target": "入门指南"
},
{
"source": "DMs",
"target": "私信"
},
{
"source": "DM",
"target": "私信"
},
{
"source": "sandboxed",
"target": "沙箱隔离"
},
{
"source": "Sandboxed",
"target": "沙箱隔离"
},
{
"source": "Auth: where it lives (important)",
"target": "凭证:存储位置(重要)"
},
{
"source": "agent",
"target": "智能体"
@ -45,7 +93,7 @@
},
{
"source": "get unstuck",
"target": "快速排障"
"target": "解决问题"
},
{
"source": "troubleshooting",
@ -57,7 +105,11 @@
},
{
"source": "onboarding",
"target": "上手引导"
"target": "新手引导"
},
{
"source": "Onboarding",
"target": "新手引导"
},
{
"source": "wizard",

View file

@ -192,7 +192,7 @@ Control whether responses are sent as a single message or streamed in blocks:
{
channels: {
bluebubbles: {
blockStreaming: true, // enable block streaming (default behavior)
blockStreaming: true, // enable block streaming (off by default)
},
},
}
@ -220,7 +220,7 @@ Provider options:
- `channels.bluebubbles.groupAllowFrom`: Group sender allowlist.
- `channels.bluebubbles.groups`: Per-group config (`requireMention`, etc.).
- `channels.bluebubbles.sendReadReceipts`: Send read receipts (default: `true`).
- `channels.bluebubbles.blockStreaming`: Enable block streaming (default: `true`).
- `channels.bluebubbles.blockStreaming`: Enable block streaming (default: `false`; required for streaming replies).
- `channels.bluebubbles.textChunkLimit`: Outbound chunk size in chars (default: 4000).
- `channels.bluebubbles.chunkMode`: `length` (default) splits only when exceeding `textChunkLimit`; `newline` splits on blank lines (paragraph boundaries) before length chunking.
- `channels.bluebubbles.mediaMaxMb`: Inbound media cap in MB (default: 8).

View file

@ -456,6 +456,7 @@ Key settings (see `/gateway/configuration` for shared channel patterns):
- `channels.msteams.textChunkLimit`: outbound text chunk size.
- `channels.msteams.chunkMode`: `length` (default) or `newline` to split on blank lines (paragraph boundaries) before length chunking.
- `channels.msteams.mediaAllowHosts`: allowlist for inbound attachment hosts (defaults to Microsoft/Teams domains).
- `channels.msteams.mediaAuthAllowHosts`: allowlist for attaching Authorization headers on media retries (defaults to Graph + Bot Framework hosts).
- `channels.msteams.requireMention`: require @mention in channels/groups (default true).
- `channels.msteams.replyStyle`: `thread | top-level` (see [Reply Style](#reply-style-threads-vs-posts)).
- `channels.msteams.teams.<teamId>.replyStyle`: per-team override.
@ -518,6 +519,7 @@ Teams recently introduced two channel UI styles over the same underlying data mo
Without Graph permissions, channel messages with images will be received as text-only (the image content is not accessible to the bot).
By default, OpenClaw only downloads media from Microsoft/Teams hostnames. Override with `channels.msteams.mediaAllowHosts` (use `["*"]` to allow any host).
Authorization headers are only attached for hosts in `channels.msteams.mediaAuthAllowHosts` (defaults to Graph + Bot Framework hosts). Keep this list strict (avoid multi-tenant suffixes).
## Sending files in group chats

View file

@ -0,0 +1,248 @@
# Event Store Integration
OpenClaw can persist all agent events to NATS JetStream, enabling event-sourced memory, audit trails, and multi-agent knowledge sharing.
## Overview
When enabled, every interaction becomes an immutable event:
- User/assistant messages
- Tool calls and results
- Session lifecycle (start/end)
- Custom events from extensions
Events are stored in NATS JetStream and can be:
- Queried for context building
- Replayed for debugging
- Shared across agents (with isolation)
- Used for continuous learning
## Configuration
Add to your `config.yml`:
```yaml
gateway:
eventStore:
enabled: true
url: nats://localhost:4222
streamName: openclaw-events
subjectPrefix: openclaw.events
```
### Full Options
```yaml
gateway:
eventStore:
enabled: true # Enable event publishing
url: nats://user:pass@localhost:4222 # NATS connection URL
streamName: openclaw-events # JetStream stream name
subjectPrefix: openclaw.events # Subject prefix for events
# Multi-agent configuration (optional)
agents:
my-agent:
url: nats://agent:pass@localhost:4222
streamName: events-my-agent
subjectPrefix: openclaw.events.my-agent
```
## Event Types
| Type | Description |
|------|-------------|
| `conversation.message.out` | Messages sent to/from the model |
| `conversation.tool_call` | Tool invocations |
| `conversation.tool_result` | Tool results |
| `lifecycle.start` | Session started |
| `lifecycle.end` | Session ended |
## Event Schema
```typescript
interface OpenClawEvent {
id: string; // Unique event ID
timestamp: number; // Unix milliseconds
agent: string; // Agent identifier
session: string; // Session key
type: string; // Event type
visibility: string; // 'internal' | 'public'
payload: {
runId: string; // Current run ID
stream: string; // Event stream type
data: any; // Event-specific data
sessionKey: string;
seq: number; // Sequence in run
ts: number;
};
meta: {
runId: string;
seq: number;
model?: string;
channel?: string;
};
}
```
## Context Injection
When event store is enabled, OpenClaw automatically:
1. Queries recent events on session start
2. Extracts conversation history and topics
3. Injects context into the system prompt
This gives the agent memory of recent interactions without manual file management.
### Context Format
The injected context includes:
- Recent conversation snippets (deduplicated)
- Active topics mentioned
- Event count and timeframe
## Multi-Agent Isolation
For multi-agent setups, each agent can have its own stream:
```yaml
gateway:
eventStore:
enabled: true
url: nats://main:password@localhost:4222
streamName: openclaw-events
subjectPrefix: openclaw.events.main
agents:
assistant-one:
url: nats://assistant1:pass@localhost:4222
streamName: events-assistant-one
subjectPrefix: openclaw.events.assistant-one
assistant-two:
url: nats://assistant2:pass@localhost:4222
streamName: events-assistant-two
subjectPrefix: openclaw.events.assistant-two
```
Combined with NATS account permissions, this ensures agents can only read their own events.
## NATS Setup
### Quick Start (Docker)
```bash
docker run -d --name nats \
-p 4222:4222 \
-v nats-data:/data \
nats:latest \
-js -sd /data
```
### Create Stream
```bash
nats stream add openclaw-events \
--subjects "openclaw.events.>" \
--storage file \
--retention limits \
--max-age 90d
```
### Secure Setup (Multi-Agent)
See [NATS Security Documentation](https://docs.nats.io/running-a-nats-service/configuration/securing_nats) for setting up accounts and permissions.
Example secure config:
```
accounts {
AGENTS: {
jetstream: enabled
users: [
{ user: main, password: "xxx", permissions: { publish: [">"], subscribe: [">"] } },
{ user: agent1, password: "xxx", permissions: {
publish: ["openclaw.events.agent1.>", "$JS.API.>", "_INBOX.>"],
subscribe: ["openclaw.events.agent1.>", "_INBOX.>", "$JS.API.>"]
}}
]
}
}
```
## Migration
To migrate existing memory files to the event store:
```bash
# Install dependencies
npm install nats
# Run migration
node scripts/migrate-to-eventstore.mjs
```
The migration script imports:
- Daily notes (`memory/*.md`)
- Long-term memory (`MEMORY.md`)
- Knowledge graph entries (`life/areas/`)
## Querying Events
### Via NATS CLI
```bash
# List streams
nats stream ls
# Get stream info
nats stream info openclaw-events
# Read recent events
nats consumer add openclaw-events reader --deliver last --ack none
nats consumer next openclaw-events reader --count 10
```
### Programmatically
```typescript
import { connect, StringCodec } from 'nats';
const nc = await connect({ servers: 'localhost:4222' });
const js = nc.jetstream();
const jsm = await nc.jetstreamManager();
// Get last 100 events
const info = await jsm.streams.info('openclaw-events');
for (let seq = info.state.last_seq - 100; seq <= info.state.last_seq; seq++) {
const msg = await jsm.streams.getMessage('openclaw-events', { seq });
const event = JSON.parse(StringCodec().decode(msg.data));
console.log(event.type, event.timestamp);
}
```
## Best Practices
1. **Retention Policy**: Set appropriate max-age for your use case (default: 90 days)
2. **Stream per Agent**: Use separate streams for agent isolation
3. **Backup**: Configure NATS replication or backup JetStream data directory
4. **Monitoring**: Use NATS monitoring endpoints to track stream health
## Troubleshooting
### Events not appearing
1. Check NATS connection: `nats server ping`
2. Verify stream exists: `nats stream ls`
3. Check OpenClaw logs for connection errors
4. Ensure `eventStore.enabled: true` in config
### Context not loading
1. Verify events exist in stream
2. Check NATS credentials have read permission
3. Look for errors in OpenClaw startup logs
### Performance issues
1. Limit event retention with `--max-age`
2. Use separate streams for high-volume agents
3. Consider NATS clustering for scale

View file

@ -1156,6 +1156,19 @@ You still need to click the extension button on the tab you want to control (it
Yes. See [Sandboxing](/gateway/sandboxing). For Docker-specific setup (full gateway in Docker or sandbox images), see [Docker](/install/docker).
### Docker feels limited How do I enable full features
The default image is security-first and runs as the `node` user, so it does not
include system packages, Homebrew, or bundled browsers. For a fuller setup:
- Persist `/home/node` with `OPENCLAW_HOME_VOLUME` so caches survive.
- Bake system deps into the image with `OPENCLAW_DOCKER_APT_PACKAGES`.
- Install Playwright browsers via the bundled CLI:
`node /app/node_modules/playwright-core/cli.js install chromium`
- Set `PLAYWRIGHT_BROWSERS_PATH` and ensure the path is persisted.
Docs: [Docker](/install/docker), [Browser](/tools/browser).
**Can I keep DMs personal but make groups public sandboxed with one agent**
Yes - if your private traffic is **DMs** and your public traffic is **groups**.

View file

@ -56,6 +56,7 @@ After it finishes:
- Open `http://127.0.0.1:18789/` in your browser.
- Paste the token into the Control UI (Settings → token).
- Need the tokenized URL again? Run `docker compose run --rm openclaw-cli dashboard --no-open`.
It writes config/workspace on the host:
@ -72,6 +73,27 @@ docker compose run --rm openclaw-cli onboard
docker compose up -d openclaw-gateway
```
Note: run `docker compose ...` from the repo root. If you enabled
`OPENCLAW_EXTRA_MOUNTS` or `OPENCLAW_HOME_VOLUME`, the setup script writes
`docker-compose.extra.yml`; include it when running Compose elsewhere:
```bash
docker compose -f docker-compose.yml -f docker-compose.extra.yml <command>
```
### Control UI token + pairing (Docker)
If you see “unauthorized” or “disconnected (1008): pairing required”, fetch a
fresh dashboard link and approve the browser device:
```bash
docker compose run --rm openclaw-cli dashboard --no-open
docker compose run --rm openclaw-cli devices list
docker compose run --rm openclaw-cli devices approve <requestId>
```
More detail: [Dashboard](/web/dashboard), [Devices](/cli/devices).
### Extra mounts (optional)
If you want to mount additional host directories into the containers, set
@ -142,6 +164,61 @@ Notes:
- If you change `OPENCLAW_DOCKER_APT_PACKAGES`, rerun `docker-setup.sh` to rebuild
the image.
### Power-user / full-featured container (opt-in)
The default Docker image is **security-first** and runs as the non-root `node`
user. This keeps the attack surface small, but it means:
- no system package installs at runtime
- no Homebrew by default
- no bundled Chromium/Playwright browsers
If you want a more full-featured container, use these opt-in knobs:
1. **Persist `/home/node`** so browser downloads and tool caches survive:
```bash
export OPENCLAW_HOME_VOLUME="openclaw_home"
./docker-setup.sh
```
2. **Bake system deps into the image** (repeatable + persistent):
```bash
export OPENCLAW_DOCKER_APT_PACKAGES="git curl jq"
./docker-setup.sh
```
3. **Install Playwright browsers without `npx`** (avoids npm override conflicts):
```bash
docker compose run --rm openclaw-cli \
node /app/node_modules/playwright-core/cli.js install chromium
```
If you need Playwright to install system deps, rebuild the image with
`OPENCLAW_DOCKER_APT_PACKAGES` instead of using `--with-deps` at runtime.
4. **Persist Playwright browser downloads**:
- Set `PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright` in
`docker-compose.yml`.
- Ensure `/home/node` persists via `OPENCLAW_HOME_VOLUME`, or mount
`/home/node/.cache/ms-playwright` via `OPENCLAW_EXTRA_MOUNTS`.
### Permissions + EACCES
The image runs as `node` (uid 1000). If you see permission errors on
`/home/node/.openclaw`, make sure your host bind mounts are owned by uid 1000.
Example (Linux host):
```bash
sudo chown -R 1000:1000 /path/to/openclaw-config /path/to/openclaw-workspace
```
If you choose to run as root for convenience, you accept the security tradeoff.
### Faster rebuilds (recommended)
To speed up rebuilds, order your Dockerfile so dependency layers are cached.
@ -199,6 +276,13 @@ docker compose run --rm openclaw-cli channels add --channel discord --token "<to
Docs: [WhatsApp](/channels/whatsapp), [Telegram](/channels/telegram), [Discord](/channels/discord)
### OpenAI Codex OAuth (headless Docker)
If you pick OpenAI Codex OAuth in the wizard, it opens a browser URL and tries
to capture a callback on `http://127.0.0.1:1455/auth/callback`. In Docker or
headless setups that callback can show a browser error. Copy the full redirect
URL you land on and paste it back into the wizard to finish auth.
### Health check
```bash
@ -220,6 +304,7 @@ pnpm test:docker:qr
### Notes
- Gateway bind defaults to `lan` for container use.
- Dockerfile CMD uses `--allow-unconfigured`; mounted config with `gateway.mode` not `local` will still start. Override CMD to enforce the guard.
- The gateway container is the source of truth for sessions (`~/.openclaw/agents/<agentId>/sessions/`).
## Agent Sandbox (host gateway + Docker tools)

View file

@ -34,17 +34,17 @@ Notes:
# From repo root; set release IDs so Sparkle feed is enabled.
# APP_BUILD must be numeric + monotonic for Sparkle compare.
BUNDLE_ID=bot.molt.mac \
APP_VERSION=2026.1.27-beta.1 \
APP_VERSION=2026.2.1 \
APP_BUILD="$(git rev-list --count HEAD)" \
BUILD_CONFIG=release \
SIGN_IDENTITY="Developer ID Application: <Developer Name> (<TEAMID>)" \
scripts/package-mac-app.sh
# Zip for distribution (includes resource forks for Sparkle delta support)
ditto -c -k --sequesterRsrc --keepParent dist/OpenClaw.app dist/OpenClaw-2026.1.27-beta.1.zip
ditto -c -k --sequesterRsrc --keepParent dist/OpenClaw.app dist/OpenClaw-2026.2.1.zip
# Optional: also build a styled DMG for humans (drag to /Applications)
scripts/create-dmg.sh dist/OpenClaw.app dist/OpenClaw-2026.1.27-beta.1.dmg
scripts/create-dmg.sh dist/OpenClaw.app dist/OpenClaw-2026.2.1.dmg
# Recommended: build + notarize/staple zip + DMG
# First, create a keychain profile once:
@ -52,14 +52,14 @@ scripts/create-dmg.sh dist/OpenClaw.app dist/OpenClaw-2026.1.27-beta.1.dmg
# --apple-id "<apple-id>" --team-id "<team-id>" --password "<app-specific-password>"
NOTARIZE=1 NOTARYTOOL_PROFILE=openclaw-notary \
BUNDLE_ID=bot.molt.mac \
APP_VERSION=2026.1.27-beta.1 \
APP_VERSION=2026.2.1 \
APP_BUILD="$(git rev-list --count HEAD)" \
BUILD_CONFIG=release \
SIGN_IDENTITY="Developer ID Application: <Developer Name> (<TEAMID>)" \
scripts/package-mac-dist.sh
# Optional: ship dSYM alongside the release
ditto -c -k --keepParent apps/macos/.build/release/OpenClaw.app.dSYM dist/OpenClaw-2026.1.27-beta.1.dSYM.zip
ditto -c -k --keepParent apps/macos/.build/release/OpenClaw.app.dSYM dist/OpenClaw-2026.2.1.dSYM.zip
```
## Appcast entry
@ -67,7 +67,7 @@ ditto -c -k --keepParent apps/macos/.build/release/OpenClaw.app.dSYM dist/OpenCl
Use the release note generator so Sparkle renders formatted HTML notes:
```bash
SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/OpenClaw-2026.1.27-beta.1.zip https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml
SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/OpenClaw-2026.2.1.zip https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml
```
Generates HTML release notes from `CHANGELOG.md` (via [`scripts/changelog-to-html.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/changelog-to-html.sh)) and embeds them in the appcast entry.
@ -75,7 +75,7 @@ Commit the updated `appcast.xml` alongside the release assets (zip + dSYM) when
## Publish & verify
- Upload `OpenClaw-2026.1.27-beta.1.zip` (and `OpenClaw-2026.1.27-beta.1.dSYM.zip`) to the GitHub release for tag `v2026.1.27-beta.1`.
- Upload `OpenClaw-2026.2.1.zip` (and `OpenClaw-2026.2.1.dSYM.zip`) to the GitHub release for tag `v2026.2.1`.
- Ensure the raw appcast URL matches the baked feed: `https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml`.
- Sanity checks:
- `curl -I https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml` returns 200.

View file

@ -326,6 +326,20 @@ If you see `Playwright is not available in this gateway build`, install the full
Playwright package (not `playwright-core`) and restart the gateway, or reinstall
OpenClaw with browser support.
#### Docker Playwright install
If your Gateway runs in Docker, avoid `npx playwright` (npm override conflicts).
Use the bundled CLI instead:
```bash
docker compose run --rm openclaw-cli \
node /app/node_modules/playwright-core/cli.js install chromium
```
To persist browser downloads, set `PLAYWRIGHT_BROWSERS_PATH` (for example,
`/home/node/.cache/ms-playwright`) and make sure `/home/node` is persisted via
`OPENCLAW_HOME_VOLUME` or a bind mount. See [Docker](/install/docker).
## How it works (internal)
High-level flow:

View file

@ -11,7 +11,28 @@ title: "ClawHub"
ClawHub is the **public skill registry for OpenClaw**. It is a free service: all skills are public, open, and visible to everyone for sharing and reuse. A skill is just a folder with a `SKILL.md` file (plus supporting text files). You can browse skills in the web app or use the CLI to search, install, update, and publish skills.
Site: [clawhub.com](https://clawhub.com)
Site: [clawhub.ai](https://clawhub.ai)
## What ClawHub is
- A public registry for OpenClaw skills.
- A versioned store of skill bundles and metadata.
- A discovery surface for search, tags, and usage signals.
## How it works
1. A user publishes a skill bundle (files + metadata).
2. ClawHub stores the bundle, parses metadata, and assigns a version.
3. The registry indexes the skill for search and discovery.
4. Users browse, download, and install skills in OpenClaw.
## What you can do
- Publish new skills and new versions of existing skills.
- Discover skills by name, tags, or search.
- Download skill bundles and inspect their files.
- Report skills that are abusive or unsafe.
- If you are a moderator, hide, unhide, delete, or ban.
## Who this is for (beginner-friendly)
@ -50,6 +71,22 @@ By default, the CLI installs skills into `./skills` under your current working d
For more detail on how skills are loaded, shared, and gated, see
[Skills](/tools/skills).
## Skill system overview
A skill is a versioned bundle of files that teaches OpenClaw how to perform a
specific task. Each publish creates a new version, and the registry keeps a
history of versions so users can audit changes.
A typical skill includes:
- A `SKILL.md` file with the primary description and usage.
- Optional configs, scripts, or supporting files used by the skill.
- Metadata such as tags, summary, and install requirements.
ClawHub uses metadata to power discovery and safely expose skill capabilities.
The registry also tracks usage signals (such as stars and downloads) to improve
ranking and visibility.
## What the service provides (features)
- **Public browsing** of skills and their `SKILL.md` content.
@ -60,6 +97,24 @@ For more detail on how skills are loaded, shared, and gated, see
- **Moderation** hooks for approvals and audits.
- **CLI-friendly API** for automation and scripting.
## Security and moderation
ClawHub is open by default. Anyone can upload skills, but a GitHub account must
be at least one week old to publish. This helps slow down abuse without blocking
legitimate contributors.
Reporting and moderation:
- Any signed in user can report a skill.
- Report reasons are required and recorded.
- Each user can have up to 20 active reports at a time.
- Skills with more than 3 unique reports are auto hidden by default.
- Moderators can view hidden skills, unhide them, delete them, or ban users.
- Abusing the report feature can result in account bans.
Interested in becoming a moderator? Ask in the OpenClaw Discord and contact a
moderator or maintainer.
## CLI commands and parameters
Global options (apply to all commands):

View file

@ -0,0 +1,47 @@
---
read_when:
- 设置认证过期监控或告警
- 自动化 Claude Code / Codex OAuth 刷新检查
summary: 监控模型提供商的 OAuth 过期状态
title: 认证监控
x-i18n:
generated_at: "2026-02-01T19:36:14Z"
model: claude-opus-4-5
provider: pi
source_hash: eef179af9545ed7ab881f3ccbef998869437fb50cdb4088de8da7223b614fa2b
source_path: automation/auth-monitoring.md
workflow: 14
---
# 认证监控
OpenClaw 通过 `openclaw models status` 暴露 OAuth 过期健康状态。可将其用于自动化和告警;脚本是针对手机工作流的可选补充。
## 推荐方式CLI 检查(跨平台通用)
```bash
openclaw models status --check
```
退出码:
- `0`:正常
- `1`:凭证已过期或缺失
- `2`即将过期24 小时内)
适用于 cron/systemd无需额外脚本。
## 可选脚本(运维/手机工作流)
这些脚本位于 `scripts/` 目录下,属于**可选项**。它们假定你可以通过 SSH 访问 Gateway网关主机并针对 systemd + Termux 进行了调优。
- `scripts/claude-auth-status.sh` 现在使用 `openclaw models status --json` 作为数据源(如果 CLI 不可用则回退到直接读取文件),因此请确保定时器中 `openclaw``PATH` 中。
- `scripts/auth-monitor.sh`cron/systemd 定时器目标发送告警ntfy 或手机)。
- `scripts/systemd/openclaw-auth-monitor.{service,timer}`systemd 用户定时器。
- `scripts/claude-auth-status.sh`Claude Code + OpenClaw 认证检查器(完整/json/简洁模式)。
- `scripts/mobile-reauth.sh`:通过 SSH 进行引导式重新认证流程。
- `scripts/termux-quick-auth.sh`:一键小组件状态查看 + 打开认证 URL。
- `scripts/termux-auth-widget.sh`:完整的引导式小组件流程。
- `scripts/termux-sync-widget.sh`:将 Claude Code 凭证同步至 OpenClaw。
如果你不需要手机自动化或 systemd 定时器,可以跳过这些脚本。

View file

@ -0,0 +1,434 @@
---
read_when:
- 调度后台任务或唤醒
- 配置需要与心跳一起或并行运行的自动化
- 在心跳和定时任务之间做选择
summary: Gateway网关调度器的定时任务与唤醒
title: 定时任务
x-i18n:
generated_at: "2026-02-01T19:37:32Z"
model: claude-opus-4-5
provider: pi
source_hash: d43268b0029f1b13d0825ddcc9c06a354987ea17ce02f3b5428a9c68bf936676
source_path: automation/cron-jobs.md
workflow: 14
---
# 定时任务Gateway网关调度器
> **定时任务还是心跳?** 请参阅[定时任务与心跳对比](/automation/cron-vs-heartbeat)了解何时使用哪种方式。
定时任务是 Gateway网关内置的调度器。它持久化任务、在合适的时间唤醒智能体并可选择将输出发送回聊天。
如果你想要 _"每天早上运行"__"20 分钟后提醒智能体"_,定时任务就是对应的机制。
## 简要概述
- 定时任务运行在 **Gateway网关内部**(而非模型内部)。
- 任务持久化存储在 `~/.openclaw/cron/` 下,因此重启不会丢失计划。
- 两种执行方式:
- **主会话**:入队一个系统事件,然后在下一次心跳时运行。
- **隔离式**:在 `cron:<jobId>` 中运行专用智能体轮次,可选择投递输出。
- 唤醒是一等功能:任务可以请求"立即唤醒"或"下次心跳时"。
## 快速开始(可操作)
创建一个一次性提醒,验证其存在,然后立即运行:
```bash
openclaw cron add \
--name "Reminder" \
--at "2026-02-01T16:00:00Z" \
--session main \
--system-event "Reminder: check the cron docs draft" \
--wake now \
--delete-after-run
openclaw cron list
openclaw cron run <job-id> --force
openclaw cron runs --id <job-id>
```
调度一个带投递功能的周期性隔离任务:
```bash
openclaw cron add \
--name "Morning brief" \
--cron "0 7 * * *" \
--tz "America/Los_Angeles" \
--session isolated \
--message "Summarize overnight updates." \
--deliver \
--channel slack \
--to "channel:C1234567890"
```
## 工具调用等价形式Gateway网关定时任务工具
有关规范的 JSON 结构和示例,请参阅[工具调用的 JSON 模式](/automation/cron-jobs#json-schema-for-tool-calls)。
## 定时任务的存储位置
定时任务默认持久化存储在 Gateway网关主机的 `~/.openclaw/cron/jobs.json` 中。Gateway网关将文件加载到内存中并在更改时写回因此仅在 Gateway网关停止时手动编辑才是安全的。请优先使用 `openclaw cron add/edit` 或定时任务工具调用 API 进行更改。
## 新手友好概述
将定时任务理解为:**何时**运行 + **做什么**
1. **选择调度计划**
- 一次性提醒 → `schedule.kind = "at"`CLI`--at`
- 重复任务 → `schedule.kind = "every"``schedule.kind = "cron"`
- 如果你的 ISO 时间戳省略了时区,将被视为 **UTC**
2. **选择运行位置**
- `sessionTarget: "main"` → 在下一次心跳时使用主会话上下文运行。
- `sessionTarget: "isolated"` → 在 `cron:<jobId>` 中运行专用智能体轮次。
3. **选择负载**
- 主会话 → `payload.kind = "systemEvent"`
- 隔离会话 → `payload.kind = "agentTurn"`
可选:`deleteAfterRun: true` 会在一次性任务成功运行后将其从存储中删除。
## 概念
### 任务
定时任务是一条存储记录,包含:
- 一个**调度计划**(何时运行),
- 一个**负载**(做什么),
- 可选的**投递**(输出发送到哪里)。
- 可选的**智能体绑定**`agentId`在指定智能体下运行任务如果缺失或未知Gateway网关会回退到默认智能体。
任务通过稳定的 `jobId` 标识(用于 CLI/Gateway网关 API
在智能体工具调用中,`jobId` 是规范字段;旧版 `id` 仍可兼容使用。
任务可以通过 `deleteAfterRun: true` 在一次性任务成功运行后自动删除。
### 调度计划
定时任务支持三种调度类型:
- `at`一次性时间戳自纪元起的毫秒数。Gateway网关接受 ISO 8601 格式并转换为 UTC。
- `every`:固定间隔(毫秒)。
- `cron`5 字段 cron 表达式,可选 IANA 时区。
Cron 表达式使用 `croner`。如果省略时区,将使用 Gateway网关主机的本地时区。
### 主会话与隔离式执行
#### 主会话任务(系统事件)
主会话任务入队一个系统事件,并可选择唤醒心跳运行器。它们必须使用 `payload.kind = "systemEvent"`
- `wakeMode: "next-heartbeat"`(默认):事件等待下一次计划心跳。
- `wakeMode: "now"`:事件触发立即心跳运行。
当你需要正常的心跳提示 + 主会话上下文时,这是最佳选择。参见[心跳](/gateway/heartbeat)。
#### 隔离任务(专用定时会话)
隔离任务在会话 `cron:<jobId>` 中运行专用智能体轮次。
关键行为:
- 提示以 `[cron:<jobId> <任务名称>]` 为前缀,便于追踪。
- 每次运行都会启动一个**全新的会话 ID**(不继承之前的对话)。
- 摘要会发布到主会话(前缀 `Cron`,可配置)。
- `wakeMode: "now"` 在发布摘要后触发立即心跳。
- 如果 `payload.deliver: true`,输出会投递到渠道;否则保留在内部。
对于嘈杂、频繁或"后台杂务"类任务,使用隔离任务可以避免污染你的主聊天记录。
### 负载结构(运行内容)
支持两种负载类型:
- `systemEvent`:仅限主会话,通过心跳提示路由。
- `agentTurn`:仅限隔离会话,运行专用智能体轮次。
常用 `agentTurn` 字段:
- `message`:必填文本提示。
- `model` / `thinking`:可选覆盖(见下文)。
- `timeoutSeconds`:可选超时覆盖。
- `deliver`:设为 `true` 以将输出发送到渠道目标。
- `channel``last` 或特定渠道。
- `to`:渠道特定目标(电话/聊天/频道 ID
- `bestEffortDeliver`:投递失败时避免任务失败。
隔离选项(仅适用于 `session=isolated`
- `postToMainPrefix`CLI`--post-prefix`):主会话中系统事件的前缀。
- `postToMainMode``summary`(默认)或 `full`
- `postToMainMaxChars`:当 `postToMainMode=full` 时的最大字符数(默认 8000
### 模型和思维覆盖
隔离任务(`agentTurn`)可以覆盖模型和思维级别:
- `model`:提供商/模型字符串(例如 `anthropic/claude-sonnet-4-20250514`)或别名(例如 `opus`
- `thinking`:思维级别(`off`、`minimal`、`low`、`medium`、`high`、`xhigh`;仅限 GPT-5.2 + Codex 模型)
注意:你也可以在主会话任务上设置 `model`,但这会更改共享的主会话模型。我们建议仅对隔离任务使用模型覆盖,以避免意外的上下文切换。
优先级解析顺序:
1. 任务负载覆盖(最高优先级)
2. 钩子特定默认值(例如 `hooks.gmail.model`
3. 智能体配置默认值
### 投递(渠道 + 目标)
隔离任务可以将输出投递到渠道。任务负载可以指定:
- `channel``whatsapp` / `telegram` / `discord` / `slack` / `mattermost`(插件)/ `signal` / `imessage` / `last`
- `to`:渠道特定的接收目标
如果省略 `channel``to`,定时任务可以回退到主会话的"最后路由"(智能体最后回复的位置)。
投递说明:
- 如果设置了 `to`,即使省略 `deliver`,定时任务也会自动投递智能体的最终输出。
- 当你需要最后路由投递但不指定明确 `to` 时,使用 `deliver: true`
- 使用 `deliver: false` 即使存在 `to` 也保持输出为内部使用。
目标格式提醒:
- Slack/Discord/Mattermost插件目标应使用明确前缀例如 `channel:<id>`、`user:<id>`)以避免歧义。
- Telegram 主题应使用 `:topic:` 格式(见下文)。
#### Telegram 投递目标(主题/论坛帖子)
Telegram 通过 `message_thread_id` 支持论坛主题。对于定时任务投递,你可以将主题/帖子编码到 `to` 字段中:
- `-1001234567890`(仅聊天 ID
- `-1001234567890:topic:123`(推荐:明确的主题标记)
- `-1001234567890:123`(简写:数字后缀)
带前缀的目标如 `telegram:...` / `telegram:group:...` 也可接受:
- `telegram:group:-1001234567890:topic:123`
## 工具调用的 JSON 模式
直接调用 Gateway网关 `cron.*` 工具(智能体工具调用或 RPC时使用这些结构。CLI 标志接受人类可读的时间格式如 `20m`,但工具调用对 `atMs``everyMs` 使用纪元毫秒数(`at` 时间接受 ISO 时间戳)。
### cron.add 参数
一次性主会话任务(系统事件):
```json
{
"name": "Reminder",
"schedule": { "kind": "at", "atMs": 1738262400000 },
"sessionTarget": "main",
"wakeMode": "now",
"payload": { "kind": "systemEvent", "text": "Reminder text" },
"deleteAfterRun": true
}
```
带投递的周期性隔离任务:
```json
{
"name": "Morning brief",
"schedule": { "kind": "cron", "expr": "0 7 * * *", "tz": "America/Los_Angeles" },
"sessionTarget": "isolated",
"wakeMode": "next-heartbeat",
"payload": {
"kind": "agentTurn",
"message": "Summarize overnight updates.",
"deliver": true,
"channel": "slack",
"to": "channel:C1234567890",
"bestEffortDeliver": true
},
"isolation": { "postToMainPrefix": "Cron", "postToMainMode": "summary" }
}
```
说明:
- `schedule.kind``at``atMs`)、`every``everyMs`)或 `cron``expr`,可选 `tz`)。
- `atMs``everyMs` 为纪元毫秒数。
- `sessionTarget` 必须为 `"main"``"isolated"`,且必须与 `payload.kind` 匹配。
- 可选字段:`agentId`、`description`、`enabled`、`deleteAfterRun`、`isolation`。
- `wakeMode` 省略时默认为 `"next-heartbeat"`
### cron.update 参数
```json
{
"jobId": "job-123",
"patch": {
"enabled": false,
"schedule": { "kind": "every", "everyMs": 3600000 }
}
}
```
说明:
- `jobId` 是规范字段;`id` 可兼容使用。
- 在补丁中使用 `agentId: null` 可清除智能体绑定。
### cron.run 和 cron.remove 参数
```json
{ "jobId": "job-123", "mode": "force" }
```
```json
{ "jobId": "job-123" }
```
## 存储与历史
- 任务存储:`~/.openclaw/cron/jobs.json`Gateway网关管理的 JSON
- 运行历史:`~/.openclaw/cron/runs/<jobId>.jsonl`JSONL自动清理
- 覆盖存储路径:配置中的 `cron.store`
## 配置
```json5
{
cron: {
enabled: true, // 默认 true
store: "~/.openclaw/cron/jobs.json",
maxConcurrentRuns: 1, // 默认 1
},
}
```
完全禁用定时任务:
- `cron.enabled: false`(配置)
- `OPENCLAW_SKIP_CRON=1`(环境变量)
## CLI 快速开始
一次性提醒UTC ISO成功后自动删除
```bash
openclaw cron add \
--name "Send reminder" \
--at "2026-01-12T18:00:00Z" \
--session main \
--system-event "Reminder: submit expense report." \
--wake now \
--delete-after-run
```
一次性提醒(主会话,立即唤醒):
```bash
openclaw cron add \
--name "Calendar check" \
--at "20m" \
--session main \
--system-event "Next heartbeat: check calendar." \
--wake now
```
周期性隔离任务(投递到 WhatsApp
```bash
openclaw cron add \
--name "Morning status" \
--cron "0 7 * * *" \
--tz "America/Los_Angeles" \
--session isolated \
--message "Summarize inbox + calendar for today." \
--deliver \
--channel whatsapp \
--to "+15551234567"
```
周期性隔离任务(投递到 Telegram 主题):
```bash
openclaw cron add \
--name "Nightly summary (topic)" \
--cron "0 22 * * *" \
--tz "America/Los_Angeles" \
--session isolated \
--message "Summarize today; send to the nightly topic." \
--deliver \
--channel telegram \
--to "-1001234567890:topic:123"
```
带模型和思维覆盖的隔离任务:
```bash
openclaw cron add \
--name "Deep analysis" \
--cron "0 6 * * 1" \
--tz "America/Los_Angeles" \
--session isolated \
--message "Weekly deep analysis of project progress." \
--model "opus" \
--thinking high \
--deliver \
--channel whatsapp \
--to "+15551234567"
```
智能体选择(多智能体配置):
```bash
# 将任务绑定到智能体 "ops"(如果该智能体不存在则回退到默认智能体)
openclaw cron add --name "Ops sweep" --cron "0 6 * * *" --session isolated --message "Check ops queue" --agent ops
# 切换或清除现有任务的智能体
openclaw cron edit <jobId> --agent ops
openclaw cron edit <jobId> --clear-agent
```
手动运行(调试):
```bash
openclaw cron run <jobId> --force
```
编辑现有任务(补丁字段):
```bash
openclaw cron edit <jobId> \
--message "Updated prompt" \
--model "opus" \
--thinking low
```
运行历史:
```bash
openclaw cron runs --id <jobId> --limit 50
```
不创建任务直接发送系统事件:
```bash
openclaw system event --mode now --text "Next heartbeat: check battery."
```
## Gateway网关 API 接口
- `cron.list`、`cron.status`、`cron.add`、`cron.update`、`cron.remove`
- `cron.run`(强制或到期)、`cron.runs`
如需不创建任务直接发送系统事件,请使用 [`openclaw system event`](/cli/system)。
## 故障排除
### "没有任何任务运行"
- 检查定时任务是否已启用:`cron.enabled` 和 `OPENCLAW_SKIP_CRON`
- 检查 Gateway网关是否持续运行定时任务运行在 Gateway网关进程内部
- 对于 `cron` 调度:确认时区(`--tz`)与主机时区的关系。
### Telegram 投递到了错误的位置
- 对于论坛主题,使用 `-100…:topic:<id>` 以确保明确无歧义。
- 如果你在日志或存储的"最后路由"目标中看到 `telegram:...` 前缀,这是正常的;定时任务投递接受这些前缀并仍能正确解析主题 ID。

View file

@ -0,0 +1,286 @@
---
read_when:
- 决定如何调度周期性任务
- 设置后台监控或通知
- 优化定期检查的 token 用量
summary: 选择心跳还是定时任务进行自动化的指南
title: 定时任务与心跳对比
x-i18n:
generated_at: "2026-02-01T19:38:18Z"
model: claude-opus-4-5
provider: pi
source_hash: 5f71a63181baa41b1c307eb7bfac561df7943d4627077dfa2861eb9f76ab086b
source_path: automation/cron-vs-heartbeat.md
workflow: 14
---
# 定时任务与心跳:何时使用哪种方式
心跳和定时任务都可以按计划运行任务。本指南帮助你根据使用场景选择合适的机制。
## 快速决策指南
| 使用场景 | 推荐方式 | 原因 |
| ------------------------- | -------------------------- | ---------------------------------------- |
| 每 30 分钟检查收件箱 | 心跳 | 可与其他检查批量处理,具备上下文感知能力 |
| 每天上午 9 点准时发送报告 | 定时任务(隔离式) | 需要精确定时 |
| 监控日历中即将到来的事件 | 心跳 | 天然适合周期性感知 |
| 运行每周深度分析 | 定时任务(隔离式) | 独立任务,可使用不同模型 |
| 20 分钟后提醒我 | 定时任务(主会话,`--at` | 精确定时的一次性任务 |
| 后台项目健康检查 | 心跳 | 搭载在现有周期上 |
## 心跳:周期性感知
心跳在**主会话**中以固定间隔运行默认30 分钟)。它的设计目的是让智能体检查各种事项并呈现重要信息。
### 何时使用心跳
- **多个周期性检查**:与其设置 5 个独立的定时任务分别检查收件箱、日历、天气、通知和项目状态,不如用一次心跳批量处理所有内容。
- **上下文感知决策**:智能体拥有完整的主会话上下文,因此可以智能判断哪些紧急、哪些可以等待。
- **对话连续性**:心跳运行共享同一会话,因此智能体记得最近的对话,可以自然地进行后续跟进。
- **低开销监控**:一次心跳替代多个小型轮询任务。
### 心跳优势
- **批量处理多项检查**:一次智能体轮次可以同时审查收件箱、日历和通知。
- **减少 API 调用**:一次心跳比 5 个隔离式定时任务更经济。
- **上下文感知**:智能体了解你一直在做什么,可以据此排定优先级。
- **智能抑制**:如果没有需要关注的事项,智能体回复 `HEARTBEAT_OK`,不会投递任何消息。
- **自然定时**:会根据队列负载略有漂移,但对大多数监控来说没有问题。
### 心跳示例HEARTBEAT.md 检查清单
```md
# Heartbeat checklist
- Check email for urgent messages
- Review calendar for events in next 2 hours
- If a background task finished, summarize results
- If idle for 8+ hours, send a brief check-in
```
智能体在每次心跳时读取此清单,并在一次轮次中处理所有项目。
### 配置心跳
```json5
{
agents: {
defaults: {
heartbeat: {
every: "30m", // 间隔
target: "last", // 告警投递目标
activeHours: { start: "08:00", end: "22:00" }, // 可选
},
},
},
}
```
完整配置请参阅[心跳](/gateway/heartbeat)。
## 定时任务:精确调度
定时任务在**精确时间**运行,可以在隔离会话中运行而不影响主会话上下文。
### 何时使用定时任务
- **需要精确定时**"每周一上午 9:00 发送"(而不是"大约 9 点左右")。
- **独立任务**:不需要对话上下文的任务。
- **不同的模型/思维级别**:需要更强大模型的深度分析。
- **一次性提醒**:使用 `--at` 实现"20 分钟后提醒我"。
- **嘈杂/频繁的任务**:会把主会话历史搞得杂乱的任务。
- **外部触发器**:无论智能体是否处于活跃状态都应独立运行的任务。
### 定时任务优势
- **精确定时**:支持带时区的 5 字段 cron 表达式。
- **会话隔离**:在 `cron:<jobId>` 中运行,不会污染主会话历史。
- **模型覆盖**:可按任务使用更便宜或更强大的模型。
- **投递控制**:可直接投递到渠道;默认仍会向主会话发布摘要(可配置)。
- **无需智能体上下文**:即使主会话空闲或已压缩,也能运行。
- **一次性支持**`--at` 用于精确的未来时间戳。
### 定时任务示例:每日早间简报
```bash
openclaw cron add \
--name "Morning briefing" \
--cron "0 7 * * *" \
--tz "America/New_York" \
--session isolated \
--message "Generate today's briefing: weather, calendar, top emails, news summary." \
--model opus \
--deliver \
--channel whatsapp \
--to "+15551234567"
```
这会在纽约时间每天早上 7:00 准时运行,使用 Opus 保证质量,并直接投递到 WhatsApp。
### 定时任务示例:一次性提醒
```bash
openclaw cron add \
--name "Meeting reminder" \
--at "20m" \
--session main \
--system-event "Reminder: standup meeting starts in 10 minutes." \
--wake now \
--delete-after-run
```
完整 CLI 参考请参阅[定时任务](/automation/cron-jobs)。
## 决策流程图
```
任务是否需要在精确时间运行?
是 -> 使用定时任务
否 -> 继续...
任务是否需要与主会话隔离?
是 -> 使用定时任务(隔离式)
否 -> 继续...
此任务能否与其他周期性检查批量处理?
是 -> 使用心跳(添加到 HEARTBEAT.md
否 -> 使用定时任务
这是一次性提醒吗?
是 -> 使用定时任务配合 --at
否 -> 继续...
是否需要不同的模型或思维级别?
是 -> 使用定时任务(隔离式)配合 --model/--thinking
否 -> 使用心跳
```
## 组合使用
最高效的配置是**两者结合**
1. **心跳**处理常规监控(收件箱、日历、通知),每 30 分钟批量处理一次。
2. **定时任务**处理精确调度(每日报告、每周回顾)和一次性提醒。
### 示例:高效自动化配置
**HEARTBEAT.md**(每 30 分钟检查一次):
```md
# Heartbeat checklist
- Scan inbox for urgent emails
- Check calendar for events in next 2h
- Review any pending tasks
- Light check-in if quiet for 8+ hours
```
**定时任务**(精确定时):
```bash
# 每天早上 7 点的早间简报
openclaw cron add --name "Morning brief" --cron "0 7 * * *" --session isolated --message "..." --deliver
# 每周一上午 9 点的项目回顾
openclaw cron add --name "Weekly review" --cron "0 9 * * 1" --session isolated --message "..." --model opus
# 一次性提醒
openclaw cron add --name "Call back" --at "2h" --session main --system-event "Call back the client" --wake now
```
## Lobster带审批的确定性工作流
Lobster 是用于**多步骤工具管道**的工作流运行时,适用于需要确定性执行和明确审批的场景。当任务不只是单次智能体轮次,且你需要可恢复的带人工检查点的工作流时,使用它。
### 何时适合使用 Lobster
- **多步骤自动化**:你需要一个固定的工具调用管道,而不是一次性提示。
- **审批关卡**:副作用应暂停直到你批准,然后继续执行。
- **可恢复运行**:继续暂停的工作流而无需重新运行之前的步骤。
### 如何与心跳和定时任务配合
- **心跳/定时任务**决定*何时*运行。
- **Lobster** 定义运行开始后*执行哪些步骤*。
对于计划性工作流,使用定时任务或心跳触发一次调用 Lobster 的智能体轮次。对于临时工作流,直接调用 Lobster。
### 操作说明(来自代码)
- Lobster 以**本地子进程**`lobster` CLI在工具模式下运行并返回 **JSON 信封**
- 如果工具返回 `needs_approval`,你需要使用 `resumeToken``approve` 标志来恢复。
- 该工具是**可选插件**;建议通过 `tools.alsoAllow: ["lobster"]` 附加启用。
- 如果传入 `lobsterPath`,必须是**绝对路径**。
完整用法和示例请参阅 [Lobster](/tools/lobster)。
## 主会话与隔离会话
心跳和定时任务都可以与主会话交互,但方式不同:
| | 心跳 | 定时任务(主会话) | 定时任务(隔离式) |
| ------ | ------------------------ | ---------------------- | ------------------ |
| 会话 | 主会话 | 主会话(通过系统事件) | `cron:<jobId>` |
| 历史 | 共享 | 共享 | 每次运行全新 |
| 上下文 | 完整 | 完整 | 无(从零开始) |
| 模型 | 主会话模型 | 主会话模型 | 可覆盖 |
| 输出 | 非 `HEARTBEAT_OK` 时投递 | 心跳提示 + 事件 | 摘要发布到主会话 |
### 何时使用主会话定时任务
当你需要以下场景时,使用 `--session main` 配合 `--system-event`
- 提醒/事件出现在主会话上下文中
- 智能体在下一次心跳时带着完整上下文处理它
- 不需要单独的隔离运行
```bash
openclaw cron add \
--name "Check project" \
--every "4h" \
--session main \
--system-event "Time for a project health check" \
--wake now
```
### 何时使用隔离式定时任务
当你需要以下场景时,使用 `--session isolated`
- 无先前上下文的全新环境
- 不同的模型或思维设置
- 输出直接投递到渠道(摘要默认仍会发布到主会话)
- 不会把主会话搞得杂乱的历史记录
```bash
openclaw cron add \
--name "Deep analysis" \
--cron "0 6 * * 0" \
--session isolated \
--message "Weekly codebase analysis..." \
--model opus \
--thinking high \
--deliver
```
## 成本考量
| 机制 | 成本特征 |
| ------------------ | ---------------------------------------------- |
| 心跳 | 每 N 分钟一次轮次;随 HEARTBEAT.md 大小扩展 |
| 定时任务(主会话) | 将事件添加到下一次心跳(无隔离轮次) |
| 定时任务(隔离式) | 每个任务一次完整智能体轮次;可使用更便宜的模型 |
**建议**
- 保持 `HEARTBEAT.md` 精简以减少 token 开销。
- 将类似的检查批量放入心跳,而不是创建多个定时任务。
- 如果只需要内部处理,在心跳上使用 `target: "none"`
- 对常规任务使用隔离式定时任务配合更便宜的模型。
## 相关内容
- [心跳](/gateway/heartbeat) - 完整的心跳配置
- [定时任务](/automation/cron-jobs) - 完整的定时任务 CLI 和 API 参考
- [系统](/cli/system) - 系统事件 + 心跳控制

View file

@ -0,0 +1,249 @@
---
read_when:
- 将 Gmail 收件箱触发器接入 OpenClaw
- 为智能体唤醒设置 Pub/Sub 推送
summary: 通过 gogcli 将 Gmail Pub/Sub 推送接入 OpenClaw webhooks
title: Gmail PubSub
x-i18n:
generated_at: "2026-02-01T19:38:47Z"
model: claude-opus-4-5
provider: pi
source_hash: dfb92133b69177e4e984b7d072f5dc28aa53a9e0cf984a018145ed811aa96195
source_path: automation/gmail-pubsub.md
workflow: 14
---
# Gmail Pub/Sub -> OpenClaw
目标Gmail watch -> Pub/Sub 推送 -> `gog gmail watch serve` -> OpenClaw webhook。
## 前置条件
- 已安装并登录 `gcloud`[安装指南](https://docs.cloud.google.com/sdk/docs/install-sdk))。
- 已安装 `gog`gogcli并已授权 Gmail 账号([gogcli.sh](https://gogcli.sh/))。
- 已启用 OpenClaw hooks参见 [Webhooks](/automation/webhook))。
- 已登录 `tailscale`[tailscale.com](https://tailscale.com/))。支持的配置使用 Tailscale Funnel 作为公共 HTTPS 端点。
其他隧道服务也可以使用,但属于自行配置/不受支持,需要手动接线。
目前我们支持的是 Tailscale。
示例 hook 配置(启用 Gmail 预设映射):
```json5
{
hooks: {
enabled: true,
token: "OPENCLAW_HOOK_TOKEN",
path: "/hooks",
presets: ["gmail"],
},
}
```
如需将 Gmail 摘要投递到聊天界面,可覆盖预设并设置带 `deliver` 以及可选的 `channel`/`to` 的映射:
```json5
{
hooks: {
enabled: true,
token: "OPENCLAW_HOOK_TOKEN",
presets: ["gmail"],
mappings: [
{
match: { path: "gmail" },
action: "agent",
wakeMode: "now",
name: "Gmail",
sessionKey: "hook:gmail:{{messages[0].id}}",
messageTemplate: "New email from {{messages[0].from}}\nSubject: {{messages[0].subject}}\n{{messages[0].snippet}}\n{{messages[0].body}}",
model: "openai/gpt-5.2-mini",
deliver: true,
channel: "last",
// to: "+15551234567"
},
],
},
}
```
如果你想要固定渠道,请设置 `channel` + `to`。否则 `channel: "last"` 会使用最后的投递路由(回退到 WhatsApp
如需为 Gmail 运行强制使用更便宜的模型,在映射中设置 `model``provider/model` 或别名)。如果你设置了 `agents.defaults.models`,请将其包含在允许列表中。
如需专门为 Gmail hooks 设置默认模型和思维级别,在配置中添加 `hooks.gmail.model` / `hooks.gmail.thinking`
```json5
{
hooks: {
gmail: {
model: "openrouter/meta-llama/llama-3.3-70b-instruct:free",
thinking: "off",
},
},
}
```
说明:
- 映射中每个 hook 的 `model`/`thinking` 仍会覆盖这些默认值。
- 回退顺序:`hooks.gmail.model` → `agents.defaults.model.fallbacks` → 主模型(认证/速率限制/超时)。
- 如果设置了 `agents.defaults.models`Gmail 模型必须在允许列表中。
- Gmail hook 内容默认使用外部内容安全边界进行包装。
如需禁用(危险),请设置 `hooks.gmail.allowUnsafeExternalContent: true`
如需进一步自定义负载处理,可添加 `hooks.mappings` 或在 `hooks.transformsDir` 下添加 JS/TS 转换模块(参见 [Webhooks](/automation/webhook))。
## 向导(推荐)
使用 OpenClaw 辅助工具一键完成所有配置(在 macOS 上通过 brew 安装依赖):
```bash
openclaw webhooks gmail setup \
--account openclaw@gmail.com
```
默认配置:
- 使用 Tailscale Funnel 作为公共推送端点。
- 为 `openclaw webhooks gmail run` 写入 `hooks.gmail` 配置。
- 启用 Gmail hook 预设(`hooks.presets: ["gmail"]`)。
路径说明:当启用 `tailscale.mode`OpenClaw 会自动将 `hooks.gmail.serve.path` 设置为 `/`,并将公共路径保持在 `hooks.gmail.tailscale.path`(默认 `/gmail-pubsub`),因为 Tailscale 在代理前会去除设置的路径前缀。
如果你需要后端接收带前缀的路径,请将 `hooks.gmail.tailscale.target`(或 `--tailscale-target`)设置为完整 URL例如 `http://127.0.0.1:8788/gmail-pubsub`,并匹配 `hooks.gmail.serve.path`
需要自定义端点?使用 `--push-endpoint <url>``--tailscale off`
平台说明:在 macOS 上,向导通过 Homebrew 安装 `gcloud`、`gogcli` 和 `tailscale`;在 Linux 上请先手动安装它们。
Gateway网关自动启动推荐
- 当 `hooks.enabled=true` 且设置了 `hooks.gmail.account`Gateway网关会在启动时运行 `gog gmail watch serve` 并自动续期 watch。
- 设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1` 可退出自动启动(如果你自行运行守护进程则很有用)。
- 不要同时运行手动守护进程,否则会遇到 `listen tcp 127.0.0.1:8788: bind: address already in use`
手动守护进程(启动 `gog gmail watch serve` + 自动续期):
```bash
openclaw webhooks gmail run
```
## 一次性设置
1. 选择**拥有 `gog` 使用的 OAuth 客户端**的 GCP 项目。
```bash
gcloud auth login
gcloud config set project <project-id>
```
注意Gmail watch 要求 Pub/Sub 主题位于与 OAuth 客户端相同的项目中。
2. 启用 API
```bash
gcloud services enable gmail.googleapis.com pubsub.googleapis.com
```
3. 创建主题:
```bash
gcloud pubsub topics create gog-gmail-watch
```
4. 允许 Gmail 推送发布:
```bash
gcloud pubsub topics add-iam-policy-binding gog-gmail-watch \
--member=serviceAccount:gmail-api-push@system.gserviceaccount.com \
--role=roles/pubsub.publisher
```
## 启动 watch
```bash
gog gmail watch start \
--account openclaw@gmail.com \
--label INBOX \
--topic projects/<project-id>/topics/gog-gmail-watch
```
保存输出中的 `history_id`(用于调试)。
## 运行推送处理器
本地示例(共享令牌认证):
```bash
gog gmail watch serve \
--account openclaw@gmail.com \
--bind 127.0.0.1 \
--port 8788 \
--path /gmail-pubsub \
--token <shared> \
--hook-url http://127.0.0.1:18789/hooks/gmail \
--hook-token OPENCLAW_HOOK_TOKEN \
--include-body \
--max-bytes 20000
```
说明:
- `--token` 保护推送端点(`x-gog-token` 或 `?token=`)。
- `--hook-url` 指向 OpenClaw `/hooks/gmail`(已映射;隔离运行 + 摘要发送到主会话)。
- `--include-body``--max-bytes` 控制发送到 OpenClaw 的正文片段。
推荐:`openclaw webhooks gmail run` 封装了相同的流程并自动续期 watch。
## 暴露处理器(高级,不受支持)
如果你需要非 Tailscale 隧道,请手动接线并在推送订阅中使用公共 URL不受支持无保护措施
```bash
cloudflared tunnel --url http://127.0.0.1:8788 --no-autoupdate
```
使用生成的 URL 作为推送端点:
```bash
gcloud pubsub subscriptions create gog-gmail-watch-push \
--topic gog-gmail-watch \
--push-endpoint "https://<public-url>/gmail-pubsub?token=<shared>"
```
生产环境:使用稳定的 HTTPS 端点并配置 Pub/Sub OIDC JWT然后运行
```bash
gog gmail watch serve --verify-oidc --oidc-email <svc@...>
```
## 测试
向被监控的收件箱发送一封邮件:
```bash
gog gmail send \
--account openclaw@gmail.com \
--to openclaw@gmail.com \
--subject "watch test" \
--body "ping"
```
检查 watch 状态和历史:
```bash
gog gmail watch status --account openclaw@gmail.com
gog gmail history --account openclaw@gmail.com --since <historyId>
```
## 故障排除
- `Invalid topicName`:项目不匹配(主题不在 OAuth 客户端项目中)。
- `User not authorized`:主题缺少 `roles/pubsub.publisher` 权限。
- 空消息Gmail 推送仅提供 `historyId`;通过 `gog gmail history` 获取详情。
## 清理
```bash
gog gmail watch stop --account openclaw@gmail.com
gcloud pubsub subscriptions delete gog-gmail-watch-push
gcloud pubsub topics delete gog-gmail-watch
```

View file

@ -0,0 +1,75 @@
---
read_when:
- 添加或修改投票支持
- 调试从 CLI 或 Gateway网关发送的投票
summary: 通过 Gateway网关 + CLI 发送投票
title: 投票
x-i18n:
generated_at: "2026-02-01T19:38:57Z"
model: claude-opus-4-5
provider: pi
source_hash: 760339865d27ec40def7996cac1d294d58ab580748ad6b32cc34d285d0314eaf
source_path: automation/poll.md
workflow: 14
---
# 投票
## 支持的渠道
- WhatsAppWeb 渠道)
- Discord
- Microsoft TeamsAdaptive Cards
## CLI
```bash
# WhatsApp
openclaw message poll --target +15555550123 \
--poll-question "Lunch today?" --poll-option "Yes" --poll-option "No" --poll-option "Maybe"
openclaw message poll --target 123456789@g.us \
--poll-question "Meeting time?" --poll-option "10am" --poll-option "2pm" --poll-option "4pm" --poll-multi
# Discord
openclaw message poll --channel discord --target channel:123456789 \
--poll-question "Snack?" --poll-option "Pizza" --poll-option "Sushi"
openclaw message poll --channel discord --target channel:123456789 \
--poll-question "Plan?" --poll-option "A" --poll-option "B" --poll-duration-hours 48
# MS Teams
openclaw message poll --channel msteams --target conversation:19:abc@thread.tacv2 \
--poll-question "Lunch?" --poll-option "Pizza" --poll-option "Sushi"
```
选项:
- `--channel``whatsapp`(默认)、`discord` 或 `msteams`
- `--poll-multi`:允许选择多个选项
- `--poll-duration-hours`:仅限 Discord省略时默认为 24
## Gateway网关 RPC
方法:`poll`
参数:
- `to`(字符串,必填)
- `question`(字符串,必填)
- `options`(字符串数组,必填)
- `maxSelections`(数字,可选)
- `durationHours`(数字,可选)
- `channel`(字符串,可选,默认:`whatsapp`
- `idempotencyKey`(字符串,必填)
## 渠道差异
- WhatsApp2-12 个选项,`maxSelections` 必须在选项数量范围内,忽略 `durationHours`
- Discord2-10 个选项,`durationHours` 限制在 1-768 小时(默认 24。`maxSelections > 1` 启用多选Discord 不支持严格的选择数量限制。
- Microsoft TeamsAdaptive Card 投票(由 OpenClaw 管理)。没有原生投票 API`durationHours` 被忽略。
## 智能体工具Message
使用 `message` 工具的 `poll` 操作(`to`、`pollQuestion`、`pollOption`,可选 `pollMulti`、`pollDurationHours`、`channel`)。
注意Discord 没有"精确选择 N 个"模式;`pollMulti` 映射为多选。
Teams 投票以 Adaptive Cards 形式渲染,需要 Gateway网关保持在线以在 `~/.openclaw/msteams-polls.json` 中记录投票结果。

View file

@ -0,0 +1,163 @@
---
read_when:
- 添加或修改 webhook 端点
- 将外部系统接入 OpenClaw
summary: 用于唤醒和隔离式智能体运行的 Webhook 入口
title: Webhooks
x-i18n:
generated_at: "2026-02-01T19:39:20Z"
model: claude-opus-4-5
provider: pi
source_hash: f26b88864567be82366b1f66a4772ef2813c7846110c62fce6caf7313568265e
source_path: automation/webhook.md
workflow: 14
---
# Webhooks
Gateway网关可以暴露一个小型 HTTP webhook 端点用于外部触发。
## 启用
```json5
{
hooks: {
enabled: true,
token: "shared-secret",
path: "/hooks",
},
}
```
说明:
- 当 `hooks.enabled=true` 时,`hooks.token` 为必填项。
- `hooks.path` 默认为 `/hooks`
## 认证
每个请求必须包含 hook 令牌。推荐使用请求头:
- `Authorization: Bearer <token>`(推荐)
- `x-openclaw-token: <token>`
- `?token=<token>`(已弃用;会记录警告,将在未来的主要版本中移除)
## 端点
### `POST /hooks/wake`
请求体:
```json
{ "text": "System line", "mode": "now" }
```
- `text` **必填**(字符串):事件描述(例如 "New email received")。
- `mode` 可选(`now` | `next-heartbeat`):是否触发立即心跳(默认 `now`)或等待下一次周期性检查。
效果:
- 为**主**会话入队一个系统事件
- 如果 `mode=now`,触发立即心跳
### `POST /hooks/agent`
请求体:
```json
{
"message": "Run this",
"name": "Email",
"sessionKey": "hook:email:msg-123",
"wakeMode": "now",
"deliver": true,
"channel": "last",
"to": "+15551234567",
"model": "openai/gpt-5.2-mini",
"thinking": "low",
"timeoutSeconds": 120
}
```
- `message` **必填**(字符串):智能体处理的提示或消息。
- `name` 可选字符串hook 的人类可读名称(例如 "GitHub"),用作会话摘要的前缀。
- `sessionKey` 可选(字符串):用于标识智能体会话的键。默认为随机的 `hook:<uuid>`。使用一致的键可以在 hook 上下文中进行多轮对话。
- `wakeMode` 可选(`now` | `next-heartbeat`):是否触发立即心跳(默认 `now`)或等待下一次周期性检查。
- `deliver` 可选(布尔值):如果为 `true`,智能体的回复将发送到消息渠道。默认为 `true`。仅为心跳确认的回复会被自动跳过。
- `channel` 可选(字符串):投递的消息渠道。可选值:`last`、`whatsapp`、`telegram`、`discord`、`slack`、`mattermost`(插件)、`signal`、`imessage`、`msteams`。默认为 `last`
- `to` 可选(字符串):渠道的接收方标识符(例如 WhatsApp/Signal 的电话号码、Telegram 的聊天 ID、Discord/Slack/Mattermost插件的频道 ID、Microsoft Teams 的会话 ID。默认为主会话中的最后一个接收方。
- `model` 可选(字符串):模型覆盖(例如 `anthropic/claude-3-5-sonnet` 或别名)。如果有模型限制,必须在允许的模型列表中。
- `thinking` 可选(字符串):思维级别覆盖(例如 `low`、`medium`、`high`)。
- `timeoutSeconds` 可选(数字):智能体运行的最大持续时间(秒)。
效果:
- 运行一次**隔离式**智能体轮次(使用独立的会话键)
- 始终将摘要发布到**主**会话
- 如果 `wakeMode=now`,触发立即心跳
### `POST /hooks/<name>`(映射)
自定义 hook 名称通过 `hooks.mappings` 解析(参见配置)。映射可以将任意请求体转换为 `wake``agent` 操作,并支持可选的模板或代码转换。
映射选项(概要):
- `hooks.presets: ["gmail"]` 启用内置的 Gmail 映射。
- `hooks.mappings` 允许你在配置中定义 `match`、`action` 和模板。
- `hooks.transformsDir` + `transform.module` 加载 JS/TS 模块以实现自定义逻辑。
- 使用 `match.source` 保持通用的接收端点(基于请求体的路由)。
- TS 转换需要 TS 加载器(例如 `bun``tsx`)或运行时预编译的 `.js`
- 在映射上设置 `deliver: true` + `channel`/`to` 可将回复路由到聊天界面(`channel` 默认为 `last`,回退到 WhatsApp
- `allowUnsafeExternalContent: true` 为该 hook 禁用外部内容安全包装(危险;仅限受信任的内部来源)。
- `openclaw webhooks gmail setup``openclaw webhooks gmail run` 写入 `hooks.gmail` 配置。完整的 Gmail watch 流程请参阅 [Gmail Pub/Sub](/automation/gmail-pubsub)。
## 响应
- `200` 用于 `/hooks/wake`
- `202` 用于 `/hooks/agent`(异步运行已启动)
- `401` 认证失败
- `400` 无效请求体
- `413` 请求体过大
## 示例
```bash
curl -X POST http://127.0.0.1:18789/hooks/wake \
-H 'Authorization: Bearer SECRET' \
-H 'Content-Type: application/json' \
-d '{"text":"New email received","mode":"now"}'
```
```bash
curl -X POST http://127.0.0.1:18789/hooks/agent \
-H 'x-openclaw-token: SECRET' \
-H 'Content-Type: application/json' \
-d '{"message":"Summarize inbox","name":"Email","wakeMode":"next-heartbeat"}'
```
### 使用不同的模型
在 agent 请求体(或映射)中添加 `model` 以覆盖该次运行的模型:
```bash
curl -X POST http://127.0.0.1:18789/hooks/agent \
-H 'x-openclaw-token: SECRET' \
-H 'Content-Type: application/json' \
-d '{"message":"Summarize inbox","name":"Email","model":"openai/gpt-5.2-mini"}'
```
如果你设置了 `agents.defaults.models`,请确保覆盖的模型包含在其中。
```bash
curl -X POST http://127.0.0.1:18789/hooks/gmail \
-H 'Authorization: Bearer SECRET' \
-H 'Content-Type: application/json' \
-d '{"source":"gmail","messages":[{"from":"Ada","subject":"Hello","snippet":"Hi"}]}'
```
## 安全
- 将 hook 端点限制在 local loopback、tailnet 或受信任的反向代理之后。
- 使用专用的 hook 令牌;不要复用 Gateway网关认证令牌。
- 避免在 webhook 日志中包含敏感的原始请求体。
- Hook 请求体默认被视为不受信任的,并使用安全边界进行包装。如果你必须为特定 hook 禁用此功能,请在该 hook 的映射中设置 `allowUnsafeExternalContent: true`(危险)。

170
docs/zh-CN/bedrock.md Normal file
View file

@ -0,0 +1,170 @@
---
read_when:
- 你想在 OpenClaw 中使用 Amazon Bedrock 模型
- 你需要为模型调用设置 AWS 凭证/区域
summary: 在 OpenClaw 中使用 Amazon BedrockConverse API模型
title: Amazon Bedrock
x-i18n:
generated_at: "2026-02-01T19:39:40Z"
model: claude-opus-4-5
provider: pi
source_hash: 318f1048451a1910b70522e2f7f9dfc87084de26d9e3938a29d372eed32244a8
source_path: bedrock.md
workflow: 14
---
# Amazon Bedrock
OpenClaw 可以通过 piai 的 **Bedrock Converse** 流式提供商使用 **Amazon Bedrock** 模型。Bedrock 认证使用 **AWS SDK 默认凭证链**,而非 API 密钥。
## piai 支持的内容
- 提供商:`amazon-bedrock`
- API`bedrock-converse-stream`
- 认证AWS 凭证(环境变量、共享配置或实例角色)
- 区域:`AWS_REGION` 或 `AWS_DEFAULT_REGION`(默认:`us-east-1`
## 自动模型发现
如果检测到 AWS 凭证OpenClaw 可以自动发现支持**流式传输**和**文本输出**的 Bedrock 模型。发现功能使用 `bedrock:ListFoundationModels`并带有缓存默认1 小时)。
配置选项位于 `models.bedrockDiscovery` 下:
```json5
{
models: {
bedrockDiscovery: {
enabled: true,
region: "us-east-1",
providerFilter: ["anthropic", "amazon"],
refreshInterval: 3600,
defaultContextWindow: 32000,
defaultMaxTokens: 4096,
},
},
}
```
说明:
- 当 AWS 凭证存在时,`enabled` 默认为 `true`
- `region` 默认为 `AWS_REGION``AWS_DEFAULT_REGION`,然后是 `us-east-1`
- `providerFilter` 匹配 Bedrock 提供商名称(例如 `anthropic`)。
- `refreshInterval` 单位为秒;设置为 `0` 可禁用缓存。
- `defaultContextWindow`(默认:`32000`)和 `defaultMaxTokens`(默认:`4096`)用于发现的模型(如果你了解模型限制可以覆盖)。
## 设置(手动)
1. 确保 AWS 凭证在 **Gateway网关主机**上可用:
```bash
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_REGION="us-east-1"
# 可选:
export AWS_SESSION_TOKEN="..."
export AWS_PROFILE="your-profile"
# 可选Bedrock API 密钥/Bearer 令牌):
export AWS_BEARER_TOKEN_BEDROCK="..."
```
2. 在配置中添加 Bedrock 提供商和模型(无需 `apiKey`
```json5
{
models: {
providers: {
"amazon-bedrock": {
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
api: "bedrock-converse-stream",
auth: "aws-sdk",
models: [
{
id: "anthropic.claude-opus-4-5-20251101-v1:0",
name: "Claude Opus 4.5 (Bedrock)",
reasoning: true,
input: ["text", "image"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 200000,
maxTokens: 8192,
},
],
},
},
},
agents: {
defaults: {
model: { primary: "amazon-bedrock/anthropic.claude-opus-4-5-20251101-v1:0" },
},
},
}
```
## EC2 实例角色
在附加了 IAM 角色的 EC2 实例上运行 OpenClaw 时AWS SDK 会自动使用实例元数据服务IMDS进行认证。但是OpenClaw 的凭证检测目前仅检查环境变量,不检查 IMDS 凭证。
**解决方法:** 设置 `AWS_PROFILE=default` 以表明 AWS 凭证可用。实际认证仍通过 IMDS 使用实例角色。
```bash
# 添加到 ~/.bashrc 或你的 shell 配置文件
export AWS_PROFILE=default
export AWS_REGION=us-east-1
```
EC2 实例角色**所需的 IAM 权限**
- `bedrock:InvokeModel`
- `bedrock:InvokeModelWithResponseStream`
- `bedrock:ListFoundationModels`(用于自动发现)
或附加托管策略 `AmazonBedrockFullAccess`
**快速设置:**
```bash
# 1. 创建 IAM 角色和实例配置文件
aws iam create-role --role-name EC2-Bedrock-Access \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
aws iam attach-role-policy --role-name EC2-Bedrock-Access \
--policy-arn arn:aws:iam::aws:policy/AmazonBedrockFullAccess
aws iam create-instance-profile --instance-profile-name EC2-Bedrock-Access
aws iam add-role-to-instance-profile \
--instance-profile-name EC2-Bedrock-Access \
--role-name EC2-Bedrock-Access
# 2. 附加到你的 EC2 实例
aws ec2 associate-iam-instance-profile \
--instance-id i-xxxxx \
--iam-instance-profile Name=EC2-Bedrock-Access
# 3. 在 EC2 实例上启用发现
openclaw config set models.bedrockDiscovery.enabled true
openclaw config set models.bedrockDiscovery.region us-east-1
# 4. 设置解决方法的环境变量
echo 'export AWS_PROFILE=default' >> ~/.bashrc
echo 'export AWS_REGION=us-east-1' >> ~/.bashrc
source ~/.bashrc
# 5. 验证模型已被发现
openclaw models list
```
## 说明
- Bedrock 需要在你的 AWS 账户/区域中启用**模型访问**。
- 自动发现需要 `bedrock:ListFoundationModels` 权限。
- 如果你使用配置文件,请在 Gateway网关主机上设置 `AWS_PROFILE`
- OpenClaw 按以下顺序检测凭证来源:`AWS_BEARER_TOKEN_BEDROCK`,然后 `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`,然后 `AWS_PROFILE`,最后是默认的 AWS SDK 链。
- 推理支持取决于模型;请查看 Bedrock 模型卡了解当前功能。
- 如果你偏好托管密钥流程,也可以在 Bedrock 前面放置一个兼容 OpenAI 的代理,将其配置为 OpenAI 提供商。

View file

@ -0,0 +1,48 @@
---
read_when:
- 你想使用 Brave Search 进行 web_search
- 你需要 BRAVE_API_KEY 或套餐详情
summary: 为 web_search 设置 Brave Search API
title: Brave Search
x-i18n:
generated_at: "2026-02-01T19:39:45Z"
model: claude-opus-4-5
provider: pi
source_hash: cdcb037b092b8a10609f02acf062b4164cb826ac22bdb3fb2909c842a1405341
source_path: brave-search.md
workflow: 14
---
# Brave Search API
OpenClaw 使用 Brave Search 作为 `web_search` 的默认提供商。
## 获取 API 密钥
1. 在 https://brave.com/search/api/ 创建 Brave Search API 账户。
2. 在控制面板中,选择 **Data for Search** 套餐并生成 API 密钥。
3. 将密钥存储在配置中(推荐)或在 Gateway网关环境中设置 `BRAVE_API_KEY`
## 配置示例
```json5
{
tools: {
web: {
search: {
provider: "brave",
apiKey: "BRAVE_API_KEY_HERE",
maxResults: 5,
timeoutSeconds: 30,
},
},
},
}
```
## 说明
- Data for AI 套餐与 `web_search` **不**兼容。
- Brave 提供免费套餐和付费套餐;请查看 Brave API 门户了解当前限制。
完整的 web_search 配置请参阅 [Web 工具](/tools/web)。

View file

@ -0,0 +1,449 @@
---
read_when:
- 配置广播群组
- 调试 WhatsApp 中的多智能体回复
status: experimental
summary: 将 WhatsApp 消息广播给多个智能体
title: 广播群组
x-i18n:
generated_at: "2026-02-01T19:40:25Z"
model: claude-opus-4-5
provider: pi
source_hash: eaeb4035912c49413e012177cf0bd28b348130d30d3317674418dca728229b70
source_path: broadcast-groups.md
workflow: 14
---
# 广播群组
**状态:** 实验性
**版本:** 在 2026.1.9 中添加
## 概述
广播群组允许多个智能体同时处理和回复同一条消息。这使你可以创建在单个 WhatsApp 群组或私聊中协同工作的专业智能体团队——全部使用同一个电话号码。
当前范围:**仅限 WhatsApp**Web 渠道)。
广播群组在渠道允许列表和群组激活规则之后进行评估。在 WhatsApp 群组中,这意味着广播发生在 OpenClaw 正常回复的时机(例如:被提及时,取决于你的群组设置)。
## 使用场景
### 1. 专业智能体团队
部署多个具有原子化、专注职责的智能体:
```
群组:"Development Team"
智能体:
- CodeReviewer审查代码片段
- DocumentationBot生成文档
- SecurityAuditor检查漏洞
- TestGenerator建议测试用例
```
每个智能体处理同一条消息并提供其专业视角。
### 2. 多语言支持
```
群组:"International Support"
智能体:
- Agent_EN用英语回复
- Agent_DE用德语回复
- Agent_ES用西班牙语回复
```
### 3. 质量保证工作流
```
群组:"Customer Support"
智能体:
- SupportAgent提供回答
- QAAgent审查质量仅在发现问题时回复
```
### 4. 任务自动化
```
群组:"Project Management"
智能体:
- TaskTracker更新任务数据库
- TimeLogger记录时间消耗
- ReportGenerator创建摘要
```
## 配置
### 基本设置
添加顶层 `broadcast` 部分(与 `bindings` 同级)。键为 WhatsApp peer ID
- 群聊:群组 JID例如 `120363403215116621@g.us`
- 私聊E.164 格式电话号码(例如 `+15551234567`
```json
{
"broadcast": {
"120363403215116621@g.us": ["alfred", "baerbel", "assistant3"]
}
}
```
**效果:** 当 OpenClaw 在此聊天中回复时,它会运行所有三个智能体。
### 处理策略
控制智能体如何处理消息:
#### 并行(默认)
所有智能体同时处理:
```json
{
"broadcast": {
"strategy": "parallel",
"120363403215116621@g.us": ["alfred", "baerbel"]
}
}
```
#### 顺序
智能体按顺序处理(每个等待前一个完成):
```json
{
"broadcast": {
"strategy": "sequential",
"120363403215116621@g.us": ["alfred", "baerbel"]
}
}
```
### 完整示例
```json
{
"agents": {
"list": [
{
"id": "code-reviewer",
"name": "Code Reviewer",
"workspace": "/path/to/code-reviewer",
"sandbox": { "mode": "all" }
},
{
"id": "security-auditor",
"name": "Security Auditor",
"workspace": "/path/to/security-auditor",
"sandbox": { "mode": "all" }
},
{
"id": "docs-generator",
"name": "Documentation Generator",
"workspace": "/path/to/docs-generator",
"sandbox": { "mode": "all" }
}
]
},
"broadcast": {
"strategy": "parallel",
"120363403215116621@g.us": ["code-reviewer", "security-auditor", "docs-generator"],
"120363424282127706@g.us": ["support-en", "support-de"],
"+15555550123": ["assistant", "logger"]
}
}
```
## 工作原理
### 消息流程
1. **收到消息**,来自 WhatsApp 群组
2. **广播检查**:系统检查 peer ID 是否在 `broadcast`
3. **如果在广播列表中**
- 所有列出的智能体处理该消息
- 每个智能体有自己的会话键和隔离的上下文
- 智能体并行(默认)或顺序处理
4. **如果不在广播列表中**
- 应用正常路由(第一个匹配的绑定)
注意:广播群组不会绕过渠道允许列表或群组激活规则(提及/命令等)。它们仅在消息符合处理条件时改变*哪些智能体运行*。
### 会话隔离
广播群组中的每个智能体维护完全独立的:
- **会话键**`agent:alfred:whatsapp:group:120363...` 与 `agent:baerbel:whatsapp:group:120363...`
- **对话历史**(智能体看不到其他智能体的消息)
- **工作区**(如果配置了则为独立沙箱)
- **工具访问**(不同的允许/拒绝列表)
- **记忆/上下文**(独立的 IDENTITY.md、SOUL.md 等)
- **群组上下文缓冲区**(用于上下文的最近群组消息)按 peer 共享,因此所有广播智能体在触发时看到相同的上下文
这使得每个智能体可以拥有:
- 不同的个性
- 不同的工具访问权限(例如只读与读写)
- 不同的模型(例如 opus 与 sonnet
- 不同的已安装 Skills
### 示例:隔离会话
在群组 `120363403215116621@g.us` 中,智能体为 `["alfred", "baerbel"]`
**Alfred 的上下文:**
```
会话agent:alfred:whatsapp:group:120363403215116621@g.us
历史:[用户消息alfred 之前的回复]
工作区:/Users/pascal/openclaw-alfred/
工具read、write、exec
```
**Bärbel 的上下文:**
```
会话agent:baerbel:whatsapp:group:120363403215116621@g.us
历史:[用户消息baerbel 之前的回复]
工作区:/Users/pascal/openclaw-baerbel/
工具:仅 read
```
## 最佳实践
### 1. 保持智能体专注
为每个智能体设计单一、明确的职责:
```json
{
"broadcast": {
"DEV_GROUP": ["formatter", "linter", "tester"]
}
}
```
**好的做法:** 每个智能体只有一项工作
**不好的做法:** 一个通用的 "dev-helper" 智能体
### 2. 使用描述性名称
让每个智能体的功能一目了然:
```json
{
"agents": {
"security-scanner": { "name": "Security Scanner" },
"code-formatter": { "name": "Code Formatter" },
"test-generator": { "name": "Test Generator" }
}
}
```
### 3. 配置不同的工具访问权限
只给智能体它们需要的工具:
```json
{
"agents": {
"reviewer": {
"tools": { "allow": ["read", "exec"] } // 只读
},
"fixer": {
"tools": { "allow": ["read", "write", "edit", "exec"] } // 读写
}
}
}
```
### 4. 监控性能
当智能体数量较多时,请考虑:
- 使用 `"strategy": "parallel"`(默认)以提高速度
- 将广播群组限制在 5-10 个智能体
- 为较简单的智能体使用更快的模型
### 5. 优雅处理失败
智能体独立失败。一个智能体的错误不会阻塞其他智能体:
```
消息 → [智能体 A ✓, 智能体 B ✗ 错误, 智能体 C ✓]
结果:智能体 A 和 C 回复,智能体 B 记录错误
```
## 兼容性
### 提供商
广播群组目前支持:
- ✅ WhatsApp已实现
- 🚧 Telegram计划中
- 🚧 Discord计划中
- 🚧 Slack计划中
### 路由
广播群组与现有路由并行工作:
```json
{
"bindings": [
{
"match": { "channel": "whatsapp", "peer": { "kind": "group", "id": "GROUP_A" } },
"agentId": "alfred"
}
],
"broadcast": {
"GROUP_B": ["agent1", "agent2"]
}
}
```
- `GROUP_A`:仅 alfred 回复(正常路由)
- `GROUP_B`agent1 和 agent2 都回复(广播)
**优先级:** `broadcast` 优先于 `bindings`
## 故障排除
### 智能体没有回复
**检查:**
1. 智能体 ID 存在于 `agents.list`
2. Peer ID 格式正确(例如 `120363403215116621@g.us`
3. 智能体不在拒绝列表中
**调试:**
```bash
tail -f ~/.openclaw/logs/gateway.log | grep broadcast
```
### 仅一个智能体回复
**原因:** Peer ID 可能在 `bindings` 中但不在 `broadcast` 中。
**修复:** 添加到广播配置中或从 bindings 中移除。
### 性能问题
**如果智能体较多时速度慢:**
- 减少每个群组的智能体数量
- 使用更轻量的模型sonnet 而非 opus
- 检查沙箱启动时间
## 示例
### 示例 1代码审查团队
```json
{
"broadcast": {
"strategy": "parallel",
"120363403215116621@g.us": [
"code-formatter",
"security-scanner",
"test-coverage",
"docs-checker"
]
},
"agents": {
"list": [
{
"id": "code-formatter",
"workspace": "~/agents/formatter",
"tools": { "allow": ["read", "write"] }
},
{
"id": "security-scanner",
"workspace": "~/agents/security",
"tools": { "allow": ["read", "exec"] }
},
{
"id": "test-coverage",
"workspace": "~/agents/testing",
"tools": { "allow": ["read", "exec"] }
},
{ "id": "docs-checker", "workspace": "~/agents/docs", "tools": { "allow": ["read"] } }
]
}
}
```
**用户发送:** 代码片段
**回复:**
- code-formatter"已修复缩进并添加了类型提示"
- security-scanner"⚠️ 第 12 行存在 SQL 注入漏洞"
- test-coverage"覆盖率为 45%,缺少错误情况的测试"
- docs-checker"函数 `process_data` 缺少文档字符串"
### 示例 2多语言支持
```json
{
"broadcast": {
"strategy": "sequential",
"+15555550123": ["detect-language", "translator-en", "translator-de"]
},
"agents": {
"list": [
{ "id": "detect-language", "workspace": "~/agents/lang-detect" },
{ "id": "translator-en", "workspace": "~/agents/translate-en" },
{ "id": "translator-de", "workspace": "~/agents/translate-de" }
]
}
}
```
## API 参考
### 配置模式
```typescript
interface OpenClawConfig {
broadcast?: {
strategy?: "parallel" | "sequential";
[peerId: string]: string[];
};
}
```
### 字段
- `strategy`(可选):智能体的处理方式
- `"parallel"`(默认):所有智能体同时处理
- `"sequential"`:智能体按数组顺序处理
- `[peerId]`WhatsApp 群组 JID、E.164 号码或其他 peer ID
- 值:应处理消息的智能体 ID 数组
## 限制
1. **最大智能体数:** 无硬性限制,但 10 个以上可能会变慢
2. **共享上下文:** 智能体看不到彼此的回复(设计如此)
3. **消息排序:** 并行回复可能以任意顺序到达
4. **速率限制:** 所有智能体共同计入 WhatsApp 速率限制
## 未来增强
计划中的功能:
- [ ] 共享上下文模式(智能体可以看到彼此的回复)
- [ ] 智能体协调(智能体可以互相通信)
- [ ] 动态智能体选择(根据消息内容选择智能体)
- [ ] 智能体优先级(某些智能体先于其他智能体回复)
## 另请参阅
- [多智能体配置](/multi-agent-sandbox-tools)
- [路由配置](/concepts/channel-routing)
- [会话管理](/concepts/sessions)

View file

@ -0,0 +1,271 @@
---
read_when:
- 设置 BlueBubbles 渠道
- 排查 webhook 配对问题
- 在 macOS 上配置 iMessage
summary: 通过 BlueBubbles macOS 服务器集成 iMessageREST 发送/接收、输入状态、回应、配对、高级操作)。
title: BlueBubbles
x-i18n:
generated_at: "2026-02-01T19:41:18Z"
model: claude-opus-4-5
provider: pi
source_hash: ac9a9d71f3bbc661da6cb2897ea32d290bbd16b35925250601cfff53bc85de8c
source_path: channels/bluebubbles.md
workflow: 14
---
# BlueBubblesmacOS REST
状态:内置插件,通过 HTTP 与 BlueBubbles macOS 服务器通信。**推荐用于 iMessage 集成**,因为相比旧版 imsg 渠道,其 API 更丰富且更易于设置。
## 概述
- 通过 BlueBubbles 辅助应用在 macOS 上运行([bluebubbles.app](https://bluebubbles.app))。
- 推荐/已测试macOS Sequoia (15)。macOS Tahoe (26) 可用;编辑功能目前在 Tahoe 上不可用,群组图标更新可能报告成功但不会同步。
- OpenClaw 通过其 REST API 与之通信(`GET /api/v1/ping`、`POST /message/text`、`POST /chat/:id/*`)。
- 收到的消息通过 webhooks 到达;发出的回复、输入指示器、已读回执和 tapback 回应均为 REST 调用。
- 附件和贴纸作为入站媒体被接收(在可能的情况下呈现给智能体)。
- 配对/允许列表与其他渠道的工作方式相同(`/start/pairing` 等),使用 `channels.bluebubbles.allowFrom` + 配对码。
- 回应作为系统事件呈现,与 Slack/Telegram 相同,因此智能体可以在回复前"提及"它们。
- 高级功能:编辑、撤回、回复线程、消息特效、群组管理。
## 快速开始
1. 在你的 Mac 上安装 BlueBubbles 服务器(按照 [bluebubbles.app/install](https://bluebubbles.app/install) 的说明操作)。
2. 在 BlueBubbles 配置中,启用 Web API 并设置密码。
3. 运行 `openclaw onboard` 并选择 BlueBubbles或手动配置
```json5
{
channels: {
bluebubbles: {
enabled: true,
serverUrl: "http://192.168.1.100:1234",
password: "example-password",
webhookPath: "/bluebubbles-webhook",
},
},
}
```
4. 将 BlueBubbles webhooks 指向你的 Gateway网关示例`https://your-gateway-host:3000/bluebubbles-webhook?password=<password>`)。
5. 启动 Gateway网关它将注册 webhook 处理器并开始配对。
## 新手引导
BlueBubbles 可在交互式设置向导中使用:
```
openclaw onboard
```
向导会提示输入:
- **服务器 URL**必填BlueBubbles 服务器地址(例如 `http://192.168.1.100:1234`
- **密码**(必填):来自 BlueBubbles 服务器设置的 API 密码
- **Webhook 路径**(可选):默认为 `/bluebubbles-webhook`
- **私聊策略**:配对、允许列表、开放或禁用
- **允许列表**:电话号码、邮箱或聊天目标
你也可以通过 CLI 添加 BlueBubbles
```
openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password <password>
```
## 访问控制(私聊 + 群组)
私聊:
- 默认:`channels.bluebubbles.dmPolicy = "pairing"`。
- 未知发送者会收到配对码;消息在批准前会被忽略(配对码 1 小时后过期)。
- 通过以下方式批准:
- `openclaw pairing list bluebubbles`
- `openclaw pairing approve bluebubbles <CODE>`
- 配对是默认的令牌交换方式。详情:[配对](/start/pairing)
群组:
- `channels.bluebubbles.groupPolicy = open | allowlist | disabled`(默认:`allowlist`)。
- 当设置为 `allowlist` 时,`channels.bluebubbles.groupAllowFrom` 控制谁可以在群组中触发。
### 提及门控(群组)
BlueBubbles 支持群聊的提及门控,与 iMessage/WhatsApp 行为一致:
- 使用 `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)检测提及。
- 当群组启用 `requireMention` 时,智能体仅在被提及时回复。
- 来自授权发送者的控制命令会绕过提及门控。
按群组配置:
```json5
{
channels: {
bluebubbles: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: {
"*": { requireMention: true }, // 所有群组的默认值
"iMessage;-;chat123": { requireMention: false }, // 针对特定群组的覆盖
},
},
},
}
```
### 命令门控
- 控制命令(例如 `/config`、`/model`)需要授权。
- 使用 `allowFrom``groupAllowFrom` 来确定命令授权。
- 授权发送者即使在群组中未提及也可以运行控制命令。
## 输入状态 + 已读回执
- **输入指示器**:在生成回复前和生成过程中自动发送。
- **已读回执**:由 `channels.bluebubbles.sendReadReceipts` 控制(默认:`true`)。
- **输入指示器**OpenClaw 发送输入开始事件BlueBubbles 在发送或超时时自动清除输入状态(通过 DELETE 手动停止不可靠)。
```json5
{
channels: {
bluebubbles: {
sendReadReceipts: false, // 禁用已读回执
},
},
}
```
## 高级操作
在配置中启用后BlueBubbles 支持高级消息操作:
```json5
{
channels: {
bluebubbles: {
actions: {
reactions: true, // tapback 回应默认true
edit: true, // 编辑已发送消息macOS 13+macOS 26 Tahoe 上不可用)
unsend: true, // 撤回消息macOS 13+
reply: true, // 按消息 GUID 回复线程
sendWithEffect: true, // 消息特效slam、loud 等)
renameGroup: true, // 重命名群聊
setGroupIcon: true, // 设置群聊图标/头像macOS 26 Tahoe 上不稳定)
addParticipant: true, // 向群组添加参与者
removeParticipant: true, // 从群组移除参与者
leaveGroup: true, // 离开群聊
sendAttachment: true, // 发送附件/媒体
},
},
},
}
```
可用操作:
- **react**:添加/移除 tapback 回应(`messageId`、`emoji`、`remove`
- **edit**:编辑已发送的消息(`messageId`、`text`
- **unsend**:撤回消息(`messageId`
- **reply**:回复特定消息(`messageId`、`text`、`to`
- **sendWithEffect**:使用 iMessage 特效发送(`text`、`to`、`effectId`
- **renameGroup**:重命名群聊(`chatGuid`、`displayName`
- **setGroupIcon**:设置群聊图标/头像(`chatGuid`、`media`)——在 macOS 26 Tahoe 上不稳定API 可能返回成功但图标不会同步)。
- **addParticipant**:向群组添加成员(`chatGuid`、`address`
- **removeParticipant**:从群组移除成员(`chatGuid`、`address`
- **leaveGroup**:离开群聊(`chatGuid`
- **sendAttachment**:发送媒体/文件(`to`、`buffer`、`filename`、`asVoice`
- 语音备忘录:设置 `asVoice: true` 并使用 **MP3****CAF** 音频以 iMessage 语音消息形式发送。BlueBubbles 在发送语音备忘录时会将 MP3 转换为 CAF。
### 消息 ID短格式与完整格式
OpenClaw 可能会呈现*短*消息 ID例如 `1`、`2`)以节省 token。
- `MessageSid` / `ReplyToId` 可以是短 ID。
- `MessageSidFull` / `ReplyToIdFull` 包含提供商的完整 ID。
- 短 ID 存储在内存中;它们可能在重启或缓存清除后过期。
- 操作接受短格式或完整格式的 `messageId`,但如果短 ID 不再可用则会报错。
对于持久化自动化和存储,请使用完整 ID
- 模板:`{{MessageSidFull}}`、`{{ReplyToIdFull}}`
- 上下文:入站负载中的 `MessageSidFull` / `ReplyToIdFull`
模板变量请参阅[配置](/gateway/configuration)。
## 分块流式传输
控制回复是作为单条消息发送还是分块流式传输:
```json5
{
channels: {
bluebubbles: {
blockStreaming: true, // 启用分块流式传输(默认行为)
},
},
}
```
## 媒体 + 限制
- 入站附件会被下载并存储在媒体缓存中。
- 媒体上限通过 `channels.bluebubbles.mediaMaxMb` 设置默认8 MB
- 出站文本按 `channels.bluebubbles.textChunkLimit` 进行分块默认4000 字符)。
## 配置参考
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.bluebubbles.enabled`:启用/禁用渠道。
- `channels.bluebubbles.serverUrl`BlueBubbles REST API 基础 URL。
- `channels.bluebubbles.password`API 密码。
- `channels.bluebubbles.webhookPath`Webhook 端点路径(默认:`/bluebubbles-webhook`)。
- `channels.bluebubbles.dmPolicy``pairing | allowlist | open | disabled`(默认:`pairing`)。
- `channels.bluebubbles.allowFrom`私聊允许列表句柄、邮箱、E.164 号码、`chat_id:*`、`chat_guid:*`)。
- `channels.bluebubbles.groupPolicy``open | allowlist | disabled`(默认:`allowlist`)。
- `channels.bluebubbles.groupAllowFrom`:群组发送者允许列表。
- `channels.bluebubbles.groups`:按群组配置(`requireMention` 等)。
- `channels.bluebubbles.sendReadReceipts`:发送已读回执(默认:`true`)。
- `channels.bluebubbles.blockStreaming`:启用分块流式传输(默认:`true`)。
- `channels.bluebubbles.textChunkLimit`出站分块大小字符数默认4000
- `channels.bluebubbles.chunkMode``length`(默认)仅在超过 `textChunkLimit` 时分割;`newline` 在空行(段落边界)处分割,然后再进行长度分块。
- `channels.bluebubbles.mediaMaxMb`入站媒体上限MB默认8
- `channels.bluebubbles.historyLimit`用于上下文的最大群组消息数0 表示禁用)。
- `channels.bluebubbles.dmHistoryLimit`:私聊历史限制。
- `channels.bluebubbles.actions`:启用/禁用特定操作。
- `channels.bluebubbles.accounts`:多账户配置。
相关全局选项:
- `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)。
- `messages.responsePrefix`
## 寻址/投递目标
推荐使用 `chat_guid` 以实现稳定路由:
- `chat_guid:iMessage;-;+15555550123`(群组推荐使用)
- `chat_id:123`
- `chat_identifier:...`
- 直接句柄:`+15555550123`、`user@example.com`
- 如果直接句柄没有现有的私聊会话OpenClaw 将通过 `POST /api/v1/chat/new` 创建一个。这需要启用 BlueBubbles Private API。
## 安全
- Webhook 请求通过将 `guid`/`password` 查询参数或请求头与 `channels.bluebubbles.password` 比较来进行认证。来自 `localhost` 的请求也会被接受。
- 请保密 API 密码和 webhook 端点(将其视为凭证)。
- localhost 信任意味着同主机的反向代理可能会无意间绕过密码。如果你为 Gateway网关设置了代理请在代理层要求认证并配置 `gateway.trustedProxies`。参见 [Gateway网关安全](/gateway/security#reverse-proxy-configuration)。
- 如果将 BlueBubbles 服务器暴露到局域网外部,请启用 HTTPS + 防火墙规则。
## 故障排除
- 如果输入/已读事件停止工作,请检查 BlueBubbles webhook 日志并验证 Gateway网关路径是否与 `channels.bluebubbles.webhookPath` 匹配。
- 配对码在一小时后过期;使用 `openclaw pairing list bluebubbles``openclaw pairing approve bluebubbles <code>`
- 回应功能需要 BlueBubbles private API`POST /api/v1/message/react`);请确保服务器版本已暴露该接口。
- 编辑/撤回需要 macOS 13+ 和兼容的 BlueBubbles 服务器版本。在 macOS 26Tahoe由于 private API 变更,编辑功能目前不可用。
- 群组图标更新在 macOS 26Tahoe上可能不稳定API 可能返回成功但新图标不会同步。
- OpenClaw 会根据 BlueBubbles 服务器的 macOS 版本自动隐藏已知不可用的操作。如果编辑功能在 macOS 26Tahoe上仍然显示请手动通过 `channels.bluebubbles.actions.edit=false` 禁用。
- 查看状态/健康信息:`openclaw status --all` 或 `openclaw status --deep`
通用渠道工作流参考请参阅[渠道](/channels)和[插件](/plugins)指南。

View file

@ -0,0 +1,463 @@
---
read_when:
- 开发 Discord 渠道功能
summary: Discord 机器人支持状态、功能和配置
title: Discord
x-i18n:
generated_at: "2026-02-01T19:19:25Z"
model: claude-opus-4-5
provider: pi
source_hash: 44e44e855481a81557d9c205bacaa82efef528f8dba59a2c39c26aeb4f420c62
source_path: channels/discord.md
workflow: 14
---
# DiscordBot API
状态:已可用于通过官方 Discord 机器人网关进行私信和服务器文字频道通信。
## 快速设置(新手)
1. 创建一个 Discord 机器人并复制机器人 token。
2. 在 Discord 应用设置中,启用 **Message Content Intent**(如果你计划使用允许列表或名称查找,还需启用 **Server Members Intent**)。
3. 为 OpenClaw 设置 token
- 环境变量:`DISCORD_BOT_TOKEN=...`
- 或配置:`channels.discord.token: "..."`。
- 如果两者都设置了,配置优先(环境变量回退仅用于默认账户)。
4. 邀请机器人到你的服务器并赋予消息权限(如果只想用私信可以创建一个私人服务器)。
5. 启动 Gateway网关。
6. 私信访问默认需要配对;首次联系时批准配对码即可。
最小配置:
```json5
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}
```
## 目标
- 通过 Discord 私信或服务器频道与 OpenClaw 对话。
- 私聊合并到智能体的主会话(默认 `agent:main:main`);服务器频道作为 `agent:<agentId>:discord:channel:<channelId>` 保持隔离(显示名称使用 `discord:<guildSlug>#<channelSlug>`)。
- 群组私信默认被忽略;通过 `channels.discord.dm.groupEnabled` 启用,可选通过 `channels.discord.dm.groupChannels` 限制。
- 保持路由确定性:回复始终发回消息到达的渠道。
## 工作原理
1. 创建 Discord 应用 → Bot启用所需的 intent私信 + 服务器消息 + 消息内容),获取机器人 token。
2. 邀请机器人到你的服务器,赋予在你需要使用的地方读取/发送消息所需的权限。
3. 使用 `channels.discord.token` 配置 OpenClaw或使用 `DISCORD_BOT_TOKEN` 作为回退)。
4. 运行 Gateway网关当 token 可用(配置优先,环境变量回退)且 `channels.discord.enabled` 不为 `false` 时,它会自动启动 Discord 渠道。
- 如果你偏好使用环境变量,设置 `DISCORD_BOT_TOKEN`(配置块是可选的)。
5. 私聊:投递时使用 `user:<id>`(或 `<@id>` 提及);所有回合都进入共享的 `main` 会话。裸数字 ID 具有歧义性,会被拒绝。
6. 服务器频道:投递时使用 `channel:<channelId>`。默认需要提及,可按服务器或按频道设置。
7. 私聊:默认通过 `channels.discord.dm.policy`(默认:`"pairing"`进行安全保护。未知发送者会收到配对码1 小时后过期);通过 `openclaw pairing approve discord <code>` 批准。
- 要保持旧的"对任何人开放"行为:设置 `channels.discord.dm.policy="open"``channels.discord.dm.allowFrom=["*"]`
- 要硬性限制允许列表:设置 `channels.discord.dm.policy="allowlist"` 并在 `channels.discord.dm.allowFrom` 中列出发送者。
- 要忽略所有私信:设置 `channels.discord.dm.enabled=false``channels.discord.dm.policy="disabled"`
8. 群组私信默认被忽略;通过 `channels.discord.dm.groupEnabled` 启用,可选通过 `channels.discord.dm.groupChannels` 限制。
9. 可选的服务器规则:设置 `channels.discord.guilds`,以服务器 ID推荐或 slug 为键,包含按频道的规则。
10. 可选的原生命令:`commands.native` 默认为 `"auto"`Discord/Telegram 开启Slack 关闭)。通过 `channels.discord.commands.native: true|false|"auto"` 覆盖;`false` 会清除之前注册的命令。文本命令由 `commands.text` 控制,必须作为独立的 `/...` 消息发送。使用 `commands.useAccessGroups: false` 可绕过命令的访问组检查。
- 完整命令列表 + 配置:[斜杠命令](/tools/slash-commands)
11. 可选的服务器上下文历史:设置 `channels.discord.historyLimit`(默认 20回退到 `messages.groupChat.historyLimit`)以在回复提及时包含最近 N 条服务器消息作为上下文。设置 `0` 可禁用。
12. 回应:智能体可以通过 `discord` 工具触发回应(由 `channels.discord.actions.*` 控制)。
- 回应移除语义:参见 [/tools/reactions](/tools/reactions)。
- `discord` 工具仅在当前渠道为 Discord 时暴露。
13. 原生命令使用隔离的会话键(`agent:<agentId>:discord:slash:<userId>`)而非共享的 `main` 会话。
注意:名称 → ID 解析使用服务器成员搜索,需要 Server Members Intent如果机器人无法搜索成员请使用 ID 或 `<@id>` 提及。
注意Slug 为小写且空格替换为 `-`。频道名称的 slug 不包含前导 `#`
注意:服务器上下文 `[from:]` 行包含 `author.tag` + `id`,方便进行可直接 ping 的回复。
## 配置写入
默认情况下Discord 允许通过 `/config set|unset` 触发的配置更新写入(需要 `commands.config: true`)。
通过以下方式禁用:
```json5
{
channels: { discord: { configWrites: false } },
}
```
## 如何创建自己的机器人
这是在服务器guild频道`#help`)中运行 OpenClaw 的"Discord 开发者门户"设置。
### 1) 创建 Discord 应用 + 机器人用户
1. Discord 开发者门户 → **Applications** → **New Application**
2. 在你的应用中:
- **Bot** → **Add Bot**
- 复制 **Bot Token**(这就是你放入 `DISCORD_BOT_TOKEN` 的值)
### 2) 启用 OpenClaw 所需的网关 intent
Discord 会阻止"特权 intent",除非你明确启用。
**Bot****Privileged Gateway Intents** 中,启用:
- **Message Content Intent**(在大多数服务器中读取消息文本所必需;没有它你会看到"Used disallowed intents"或机器人会连接但不响应消息)
- **Server Members Intent**(推荐;某些成员/用户查找和服务器中的允许列表匹配所必需)
通常你**不**需要 **Presence Intent**
### 3) 生成邀请 URLOAuth2 URL 生成器)
在你的应用中:**OAuth2** → **URL Generator**
**Scopes**
- ✅ `bot`
- ✅ `applications.commands`(原生命令所必需)
**Bot Permissions**(最小基线)
- ✅ View Channels
- ✅ Send Messages
- ✅ Read Message History
- ✅ Embed Links
- ✅ Attach Files
- ✅ Add Reactions可选但推荐
- ✅ Use External Emojis / Stickers可选仅在你需要时
除非你在调试且完全信任机器人,否则避免使用 **Administrator**
复制生成的 URL打开它选择你的服务器安装机器人。
### 4) 获取 ID服务器/用户/频道)
Discord 到处使用数字 IDOpenClaw 配置推荐使用 ID。
1. Discord桌面/网页)→ **用户设置****高级** → 启用 **开发者模式**
2. 右键点击:
- 服务器名称 → **复制服务器 ID**guild id
- 频道(例如 `#help`)→ **复制频道 ID**
- 你的用户 → **复制用户 ID**
### 5) 配置 OpenClaw
#### Token
通过环境变量设置机器人 token推荐用于服务器
- `DISCORD_BOT_TOKEN=...`
或通过配置:
```json5
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}
```
多账户支持:使用 `channels.discord.accounts`,每个账户配置独立的 token 和可选的 `name`。共享模式请参阅 [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts)。
#### 允许列表 + 频道路由
示例"单服务器,只允许我,只允许 #help"
```json5
{
channels: {
discord: {
enabled: true,
dm: { enabled: false },
guilds: {
YOUR_GUILD_ID: {
users: ["YOUR_USER_ID"],
requireMention: true,
channels: {
help: { allow: true, requireMention: true },
},
},
},
retry: {
attempts: 3,
minDelayMs: 500,
maxDelayMs: 30000,
jitter: 0.1,
},
},
},
}
```
注意事项:
- `requireMention: true` 表示机器人仅在被提及时回复(推荐用于共享频道)。
- `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)对服务器消息也算作提及。
- 多智能体覆盖:在 `agents.list[].groupChat.mentionPatterns` 上设置每个智能体的模式。
- 如果存在 `channels`,任何未列出的频道默认被拒绝。
- 使用 `"*"` 频道条目来应用所有频道的默认值;明确的频道条目会覆盖通配符。
- 帖子继承父频道配置(允许列表、`requireMention`、Skills、提示等除非你明确添加帖子频道 ID。
- 机器人发送的消息默认被忽略;设置 `channels.discord.allowBots=true` 可允许它们(自己的消息仍然被过滤)。
- 警告:如果你允许回复其他机器人(`channels.discord.allowBots=true`),请使用 `requireMention`、`channels.discord.guilds.*.channels.<id>.users` 允许列表和/或在 `AGENTS.md``SOUL.md` 中设置明确的防护规则来防止机器人之间的回复循环。
### 6) 验证是否正常工作
1. 启动 Gateway网关。
2. 在你的服务器频道中,发送:`@Krill hello`(或你的机器人名称)。
3. 如果没有响应:查看下方**故障排除**。
### 故障排除
- 首先:运行 `openclaw doctor``openclaw channels status --probe`(可操作的警告 + 快速审计)。
- **"Used disallowed intents"**:在开发者门户中启用 **Message Content Intent**(以及可能的 **Server Members Intent**),然后重启 Gateway网关。
- **机器人连接但在服务器频道中从不回复**
- 缺少 **Message Content Intent**,或
- 机器人缺少频道权限View/Send/Read History
- 你的配置要求提及但你没有提及它,或
- 你的服务器/频道允许列表拒绝了该频道/用户。
- **`requireMention: false` 但仍然没有回复**
- `channels.discord.groupPolicy` 默认为 **allowlist**;将其设置为 `"open"` 或在 `channels.discord.guilds` 下添加服务器条目(可选在 `channels.discord.guilds.<id>.channels` 下列出频道以进行限制)。
- 如果你只设置了 `DISCORD_BOT_TOKEN` 且从未创建 `channels.discord` 部分,运行时默认将 `groupPolicy` 设为 `open`。添加 `channels.discord.groupPolicy`、`channels.defaults.groupPolicy` 或服务器/频道允许列表来锁定它。
- `requireMention` 必须位于 `channels.discord.guilds`(或特定频道)下。顶层的 `channels.discord.requireMention` 会被忽略。
- **权限审计**`channels status --probe`)仅检查数字频道 ID。如果你使用 slug/名称作为 `channels.discord.guilds.*.channels` 的键,审计无法验证权限。
- **私信不工作**`channels.discord.dm.enabled=false`、`channels.discord.dm.policy="disabled"`,或你尚未被批准(`channels.discord.dm.policy="pairing"`)。
## 功能与限制
- 私信和服务器文字频道(帖子被视为独立频道;不支持语音)。
- 输入指示尽力发送;消息分块使用 `channels.discord.textChunkLimit`(默认 2000并按行数分割较长回复`channels.discord.maxLinesPerMessage`,默认 17
- 可选的换行分块:设置 `channels.discord.chunkMode="newline"` 在按长度分块之前按空行(段落边界)分割。
- 支持文件上传,上限为配置的 `channels.discord.mediaMaxMb`(默认 8 MB
- 服务器回复默认需要提及门控,以避免嘈杂的机器人。
- 当消息引用另一条消息时,会注入回复上下文(引用内容 + ID
- 原生回复线程**默认关闭**;通过 `channels.discord.replyToMode` 和回复标签启用。
## 重试策略
出站 Discord API 调用在速率限制429时使用 Discord 的 `retry_after`(如可用)进行重试,采用指数退避和抖动。通过 `channels.discord.retry` 配置。参见[重试策略](/concepts/retry)。
## 配置
```json5
{
channels: {
discord: {
enabled: true,
token: "abc.123",
groupPolicy: "allowlist",
guilds: {
"*": {
channels: {
general: { allow: true },
},
},
},
mediaMaxMb: 8,
actions: {
reactions: true,
stickers: true,
emojiUploads: true,
stickerUploads: true,
polls: true,
permissions: true,
messages: true,
threads: true,
pins: true,
search: true,
memberInfo: true,
roleInfo: true,
roles: false,
channelInfo: true,
channels: true,
voiceStatus: true,
events: true,
moderation: false,
},
replyToMode: "off",
dm: {
enabled: true,
policy: "pairing", // pairing | allowlist | open | disabled
allowFrom: ["123456789012345678", "steipete"],
groupEnabled: false,
groupChannels: ["openclaw-dm"],
},
guilds: {
"*": { requireMention: true },
"123456789012345678": {
slug: "friends-of-openclaw",
requireMention: false,
reactionNotifications: "own",
users: ["987654321098765432", "steipete"],
channels: {
general: { allow: true },
help: {
allow: true,
requireMention: true,
users: ["987654321098765432"],
skills: ["search", "docs"],
systemPrompt: "Keep answers short.",
},
},
},
},
},
},
}
```
确认回应由 `messages.ackReaction` + `messages.ackReactionScope` 全局控制。使用 `messages.removeAckAfterReply` 在机器人回复后清除确认回应。
- `dm.enabled`:设置 `false` 可忽略所有私信(默认 `true`)。
- `dm.policy`:私信访问控制(推荐 `pairing`)。`"open"` 需要 `dm.allowFrom=["*"]`
- `dm.allowFrom`:私信允许列表(用户 ID 或名称)。用于 `dm.policy="allowlist"``dm.policy="open"` 验证。向导接受用户名并在机器人可以搜索成员时将其解析为 ID。
- `dm.groupEnabled`:启用群组私信(默认 `false`)。
- `dm.groupChannels`:群组私信频道 ID 或 slug 的可选允许列表。
- `groupPolicy`:控制服务器频道处理方式(`open|disabled|allowlist``allowlist` 需要频道允许列表。
- `guilds`:按服务器 ID推荐或 slug 为键的按服务器规则。
- `guilds."*"`:当没有明确条目时应用的默认按服务器设置。
- `guilds.<id>.slug`:用于显示名称的可选友好 slug。
- `guilds.<id>.users`可选的按服务器用户允许列表ID 或名称)。
- `guilds.<id>.tools`:可选的按服务器工具策略覆盖(`allow`/`deny`/`alsoAllow`),在频道覆盖缺失时使用。
- `guilds.<id>.toolsBySender`:可选的按发送者工具策略覆盖(服务器级别,在频道覆盖缺失时应用;支持 `"*"` 通配符)。
- `guilds.<id>.channels.<channel>.allow`:当 `groupPolicy="allowlist"` 时允许/拒绝频道。
- `guilds.<id>.channels.<channel>.requireMention`:频道的提及门控。
- `guilds.<id>.channels.<channel>.tools`:可选的按频道工具策略覆盖(`allow`/`deny`/`alsoAllow`)。
- `guilds.<id>.channels.<channel>.toolsBySender`:可选的频道内按发送者工具策略覆盖(支持 `"*"` 通配符)。
- `guilds.<id>.channels.<channel>.users`:可选的按频道用户允许列表。
- `guilds.<id>.channels.<channel>.skills`Skills 过滤器(省略 = 所有 Skills空 = 无)。
- `guilds.<id>.channels.<channel>.systemPrompt`:频道的额外系统提示(与频道主题合并)。
- `guilds.<id>.channels.<channel>.enabled`:设置 `false` 可禁用频道。
- `guilds.<id>.channels`:频道规则(键为频道 slug 或 ID
- `guilds.<id>.requireMention`:按服务器的提及要求(可按频道覆盖)。
- `guilds.<id>.reactionNotifications`:回应系统事件模式(`off`、`own`、`all`、`allowlist`)。
- `textChunkLimit`出站文本分块大小字符。默认2000。
- `chunkMode``length`(默认)仅在超过 `textChunkLimit` 时分割;`newline` 在按长度分块之前按空行(段落边界)分割。
- `maxLinesPerMessage`每条消息的软最大行数。默认17。
- `mediaMaxMb`:限制保存到磁盘的入站媒体大小。
- `historyLimit`:回复提及时包含的最近服务器消息数作为上下文(默认 20回退到 `messages.groupChat.historyLimit``0` 禁用)。
- `dmHistoryLimit`:私信历史限制(用户回合数)。按用户覆盖:`dms["<user_id>"].historyLimit`。
- `retry`:出站 Discord API 调用的重试策略attempts、minDelayMs、maxDelayMs、jitter
- `pluralkit`:解析 PluralKit 代理消息,使系统成员显示为不同的发送者。
- `actions`:按操作的工具门控;省略则允许所有(设置 `false` 可禁用)。
- `reactions`(涵盖添加回应 + 读取回应)
- `stickers`、`emojiUploads`、`stickerUploads`、`polls`、`permissions`、`messages`、`threads`、`pins`、`search`
- `memberInfo`、`roleInfo`、`channelInfo`、`voiceStatus`、`events`
- `channels`(创建/编辑/删除频道 + 分类 + 权限)
- `roles`(角色添加/移除,默认 `false`
- `moderation`(超时/踢出/封禁,默认 `false`
回应通知使用 `guilds.<id>.reactionNotifications`
- `off`:无回应事件。
- `own`:机器人自己消息上的回应(默认)。
- `all`:所有消息上的所有回应。
- `allowlist`:来自 `guilds.<id>.users` 的用户在所有消息上的回应(空列表则禁用)。
### PluralKitPK支持
启用 PK 查找,使代理消息解析为底层的系统 + 成员。启用后OpenClaw 使用成员身份进行允许列表匹配,并将发送者标记为 `Member (PK:System)` 以避免意外的 Discord ping。
```json5
{
channels: {
discord: {
pluralkit: {
enabled: true,
token: "pk_live_...", // 可选;私有系统需要
},
},
},
}
```
允许列表注意事项(启用 PK 时):
- 在 `dm.allowFrom`、`guilds.<id>.users` 或按频道的 `users` 中使用 `pk:<memberId>`
- 成员显示名称也通过名称/slug 匹配。
- 查找使用**原始** Discord 消息 ID代理前的消息因此 PK API 仅在其 30 分钟窗口内解析它。
- 如果 PK 查找失败(例如没有 token 的私有系统),代理消息被视为机器人消息并被丢弃,除非设置 `channels.discord.allowBots=true`
### 工具操作默认值
| 操作组 | 默认值 | 说明 |
| -------------- | ------ | ------------------------------- |
| reactions | 启用 | 添加回应 + 列出回应 + emojiList |
| stickers | 启用 | 发送贴纸 |
| emojiUploads | 启用 | 上传表情 |
| stickerUploads | 启用 | 上传贴纸 |
| polls | 启用 | 创建投票 |
| permissions | 启用 | 频道权限快照 |
| messages | 启用 | 读取/发送/编辑/删除 |
| threads | 启用 | 创建/列出/回复 |
| pins | 启用 | 置顶/取消置顶/列出 |
| search | 启用 | 消息搜索(预览功能) |
| memberInfo | 启用 | 成员信息 |
| roleInfo | 启用 | 角色列表 |
| channelInfo | 启用 | 频道信息 + 列表 |
| channels | 启用 | 频道/分类管理 |
| voiceStatus | 启用 | 语音状态查询 |
| events | 启用 | 列出/创建计划事件 |
| roles | 禁用 | 角色添加/移除 |
| moderation | 禁用 | 超时/踢出/封禁 |
- `replyToMode``off`(默认)、`first` 或 `all`。仅在模型输出包含回复标签时生效。
## 回复标签
要请求线程回复,模型可以在输出中包含一个标签:
- `[[reply_to_current]]` — 回复触发的 Discord 消息。
- `[[reply_to:<id>]]` — 回复上下文/历史中的特定消息 ID。
当前消息 ID 以 `[message_id: …]` 附加到提示中;历史条目已包含 ID。
行为由 `channels.discord.replyToMode` 控制:
- `off`:忽略标签。
- `first`:仅第一个出站分块/附件作为回复。
- `all`:每个出站分块/附件都作为回复。
允许列表匹配注意事项:
- `allowFrom`/`users`/`groupChannels` 接受 ID、名称、标签或 `<@id>` 格式的提及。
- 支持 `discord:`/`user:`(用户)和 `channel:`(群组私信)等前缀。
- 使用 `*` 允许任何发送者/频道。
- 当存在 `guilds.<id>.channels` 时,未列出的频道默认被拒绝。
- 当省略 `guilds.<id>.channels` 时,允许列表中服务器的所有频道都被允许。
- 要**不允许任何频道**,设置 `channels.discord.groupPolicy: "disabled"`(或保持空的允许列表)。
- 配置向导接受 `Guild/Channel` 名称(公共 + 私有)并在可能时将其解析为 ID。
- 启动时OpenClaw 将允许列表中的频道/用户名称解析为 ID当机器人可以搜索成员时并记录映射未解析的条目保持原样。
原生命令注意事项:
- 注册的命令与 OpenClaw 的聊天命令一致。
- 原生命令遵循与私信/服务器消息相同的允许列表(`channels.discord.dm.allowFrom`、`channels.discord.guilds`、按频道规则)。
- 斜杠命令在 Discord UI 中可能对不在允许列表中的用户仍然可见OpenClaw 在执行时强制执行允许列表并回复"未授权"。
## 工具操作
智能体可以调用 `discord` 执行以下操作:
- `react` / `reactions`(添加或列出回应)
- `sticker`、`poll`、`permissions`
- `readMessages`、`sendMessage`、`editMessage`、`deleteMessage`
- 读取/搜索/置顶工具的负载包含标准化的 `timestampMs`UTC 纪元毫秒)和 `timestampUtc`,同时保留原始 Discord `timestamp`
- `threadCreate`、`threadList`、`threadReply`
- `pinMessage`、`unpinMessage`、`listPins`
- `searchMessages`、`memberInfo`、`roleInfo`、`roleAdd`、`roleRemove`、`emojiList`
- `channelInfo`、`channelList`、`voiceStatus`、`eventList`、`eventCreate`
- `timeout`、`kick`、`ban`
Discord 消息 ID 在注入的上下文中呈现(`[discord message id: …]` 和历史行),方便智能体定位它们。
表情可以是 unicode例如 `✅`)或自定义表情语法如 `<:party_blob:1234567890>`
## 安全与运维
- 将机器人 token 视为密码;在受管主机上推荐使用 `DISCORD_BOT_TOKEN` 环境变量或锁定配置文件权限。
- 仅授予机器人所需的权限(通常是读取/发送消息)。
- 如果机器人卡住或被速率限制,在确认没有其他进程占用 Discord 会话后重启 Gateway网关`openclaw gateway --force`)。

View file

@ -0,0 +1,257 @@
---
read_when:
- 开发 Google Chat 渠道功能
summary: Google Chat 应用支持状态、功能和配置
title: Google Chat
x-i18n:
generated_at: "2026-02-01T19:20:03Z"
model: claude-opus-4-5
provider: pi
source_hash: 3b2bb116cdd12614c3d5afddd0879e9deb05c3606e3a2385cbc07f23552b357e
source_path: channels/googlechat.md
workflow: 14
---
# Google ChatChat API
状态:已可通过 Google Chat API webhook仅 HTTP用于私信和空间。
## 快速设置(新手)
1. 创建一个 Google Cloud 项目并启用 **Google Chat API**
- 前往:[Google Chat API 凭据](https://console.cloud.google.com/apis/api/chat.googleapis.com/credentials)
- 如果尚未启用,请启用该 API。
2. 创建**服务账户**
- 点击 **Create Credentials** > **Service Account**
- 随意命名(例如 `openclaw-chat`)。
- 权限留空(点击 **Continue**)。
- 有权访问的主体留空(点击 **Done**)。
3. 创建并下载 **JSON 密钥**
- 在服务账户列表中,点击你刚创建的那个。
- 进入 **Keys** 标签页。
- 点击 **Add Key** > **Create new key**
- 选择 **JSON** 并点击 **Create**
4. 将下载的 JSON 文件存储在你的 Gateway网关主机上例如 `~/.openclaw/googlechat-service-account.json`)。
5. 在 [Google Cloud Console Chat 配置](https://console.cloud.google.com/apis/api/chat.googleapis.com/hangouts-chat) 中创建 Google Chat 应用:
- 填写 **Application info**
- **App name**:(例如 `OpenClaw`
- **Avatar URL**:(例如 `https://openclaw.ai/logo.png`
- **Description**:(例如 `Personal AI Assistant`
- 启用 **Interactive features**
- 在 **Functionality** 下,勾选 **Join spaces and group conversations**
- 在 **Connection settings** 下,选择 **HTTP endpoint URL**
- 在 **Triggers** 下,选择 **Use a common HTTP endpoint URL for all triggers** 并将其设置为你的 Gateway网关公共 URL 后跟 `/googlechat`
- _提示运行 `openclaw status` 可查找你的 Gateway网关公共 URL。_
- 在 **Visibility** 下,勾选 **Make this Chat app available to specific people and groups in &lt;Your Domain&gt;**
- 在文本框中输入你的邮箱地址(例如 `user@example.com`)。
- 点击底部的 **Save**
6. **启用应用状态**
- 保存后,**刷新页面**。
- 查找 **App status** 部分(通常在保存后位于顶部或底部附近)。
- 将状态更改为 **Live - available to users**
- 再次点击 **Save**
7. 使用服务账户路径 + webhook audience 配置 OpenClaw
- 环境变量:`GOOGLE_CHAT_SERVICE_ACCOUNT_FILE=/path/to/service-account.json`
- 或配置:`channels.googlechat.serviceAccountFile: "/path/to/service-account.json"`。
8. 设置 webhook audience 类型 + 值(与你的 Chat 应用配置匹配)。
9. 启动 Gateway网关。Google Chat 将向你的 webhook 路径发送 POST 请求。
## 添加到 Google Chat
Gateway网关运行且你的邮箱已添加到可见性列表后
1. 前往 [Google Chat](https://chat.google.com/)。
2. 点击 **Direct Messages** 旁边的 **+**(加号)图标。
3. 在搜索栏中(通常用于添加人员的地方),输入你在 Google Cloud Console 中配置的 **App name**
- **注意**:机器人*不会*出现在"Marketplace"浏览列表中,因为它是私有应用。你必须按名称搜索。
4. 从结果中选择你的机器人。
5. 点击 **Add****Chat** 开始一对一对话。
6. 发送"Hello"来触发助手!
## 公共 URL仅 Webhook
Google Chat webhook 需要公共 HTTPS 端点。为安全起见,**仅将 `/googlechat` 路径暴露**到互联网。将 OpenClaw 仪表板和其他敏感端点保持在私有网络上。
### 方案 ATailscale Funnel推荐
使用 Tailscale Serve 用于私有仪表板Funnel 用于公共 webhook 路径。这样 `/` 保持私有,仅暴露 `/googlechat`
1. **检查你的 Gateway网关绑定在哪个地址上**
```bash
ss -tlnp | grep 18789
```
注意 IP 地址(例如 `127.0.0.1`、`0.0.0.0` 或你的 Tailscale IP 如 `100.x.x.x`)。
2. **仅将仪表板暴露给 tailnet端口 8443**
```bash
# 如果绑定到 localhost127.0.0.1 或 0.0.0.0
tailscale serve --bg --https 8443 http://127.0.0.1:18789
# 如果仅绑定到 Tailscale IP例如 100.106.161.80
tailscale serve --bg --https 8443 http://100.106.161.80:18789
```
3. **仅公开暴露 webhook 路径:**
```bash
# 如果绑定到 localhost127.0.0.1 或 0.0.0.0
tailscale funnel --bg --set-path /googlechat http://127.0.0.1:18789/googlechat
# 如果仅绑定到 Tailscale IP例如 100.106.161.80
tailscale funnel --bg --set-path /googlechat http://100.106.161.80:18789/googlechat
```
4. **为节点授权 Funnel 访问:**
如果出现提示,请访问输出中显示的授权 URL在你的 tailnet 策略中为此节点启用 Funnel。
5. **验证配置:**
```bash
tailscale serve status
tailscale funnel status
```
你的公共 webhook URL 将是:
`https://<node-name>.<tailnet>.ts.net/googlechat`
你的私有仪表板仅限 tailnet 访问:
`https://<node-name>.<tailnet>.ts.net:8443/`
在 Google Chat 应用配置中使用公共 URL不带 `:8443`)。
> 注意:此配置在重启后持续有效。要在之后移除,运行 `tailscale funnel reset``tailscale serve reset`
### 方案 B反向代理Caddy
如果你使用像 Caddy 这样的反向代理,仅代理特定路径:
```caddy
your-domain.com {
reverse_proxy /googlechat* localhost:18789
}
```
使用此配置,对 `your-domain.com/` 的任何请求将被忽略或返回 404`your-domain.com/googlechat` 安全地路由到 OpenClaw。
### 方案 CCloudflare Tunnel
配置你的隧道入口规则,仅路由 webhook 路径:
- **路径**`/googlechat` -> `http://localhost:18789/googlechat`
- **默认规则**HTTP 404Not Found
## 工作原理
1. Google Chat 向 Gateway网关发送 webhook POST 请求。每个请求包含一个 `Authorization: Bearer <token>` 头。
2. OpenClaw 根据配置的 `audienceType` + `audience` 验证 token
- `audienceType: "app-url"` → audience 是你的 HTTPS webhook URL。
- `audienceType: "project-number"` → audience 是 Cloud 项目编号。
3. 消息按空间路由:
- 私信使用会话键 `agent:<agentId>:googlechat:dm:<spaceId>`
- 空间使用会话键 `agent:<agentId>:googlechat:group:<spaceId>`
4. 私信访问默认需要配对。未知发送者会收到配对码;通过以下方式批准:
- `openclaw pairing approve googlechat <code>`
5. 群组空间默认需要 @提及。如果提及检测需要应用的用户名,请使用 `botUser`
## 目标
使用以下标识符进行投递和允许列表:
- 私信:`users/<userId>` 或 `users/<email>`(接受邮箱地址)。
- 空间:`spaces/<spaceId>`。
## 配置要点
```json5
{
channels: {
googlechat: {
enabled: true,
serviceAccountFile: "/path/to/service-account.json",
audienceType: "app-url",
audience: "https://gateway.example.com/googlechat",
webhookPath: "/googlechat",
botUser: "users/1234567890", // 可选;辅助提及检测
dm: {
policy: "pairing",
allowFrom: ["users/1234567890", "name@example.com"],
},
groupPolicy: "allowlist",
groups: {
"spaces/AAAA": {
allow: true,
requireMention: true,
users: ["users/1234567890"],
systemPrompt: "Short answers only.",
},
},
actions: { reactions: true },
typingIndicator: "message",
mediaMaxMb: 20,
},
},
}
```
注意事项:
- 服务账户凭据也可以通过 `serviceAccount`JSON 字符串)内联传递。
- 如果未设置 `webhookPath`,默认 webhook 路径为 `/googlechat`
- 当 `actions.reactions` 启用时,可通过 `reactions` 工具和 `channels action` 使用回应功能。
- `typingIndicator` 支持 `none`、`message`(默认)和 `reaction`reaction 需要用户 OAuth
- 附件通过 Chat API 下载并存储在媒体管道中(大小由 `mediaMaxMb` 限制)。
## 故障排除
### 405 Method Not Allowed
如果 Google Cloud Logs Explorer 显示如下错误:
```
status code: 405, reason phrase: HTTP error response: HTTP/1.1 405 Method Not Allowed
```
这意味着 webhook 处理器未注册。常见原因:
1. **渠道未配置**:配置中缺少 `channels.googlechat` 部分。通过以下方式验证:
```bash
openclaw config get channels.googlechat
```
如果返回"Config path not found",添加配置(参见[配置要点](#配置要点))。
2. **插件未启用**:检查插件状态:
```bash
openclaw plugins list | grep googlechat
```
如果显示"disabled",在配置中添加 `plugins.entries.googlechat.enabled: true`
3. **Gateway网关未重启**:添加配置后,重启 Gateway网关
```bash
openclaw gateway restart
```
验证渠道是否正在运行:
```bash
openclaw channels status
# 应显示Google Chat default: enabled, configured, ...
```
### 其他问题
- 检查 `openclaw channels status --probe` 查看认证错误或缺失的 audience 配置。
- 如果没有消息到达,确认 Chat 应用的 webhook URL + 事件订阅。
- 如果提及门控阻止了回复,将 `botUser` 设置为应用的用户资源名称并验证 `requireMention`
- 发送测试消息时使用 `openclaw logs --follow` 查看请求是否到达 Gateway网关。
相关文档:
- [Gateway网关配置](/gateway/configuration)
- [安全](/gateway/security)
- [回应](/tools/reactions)

View file

@ -0,0 +1,38 @@
---
read_when:
- 开发 Telegram 或 grammY 相关功能
summary: 通过 grammY 集成 Telegram Bot API 及设置说明
title: grammY
x-i18n:
generated_at: "2026-02-01T19:20:16Z"
model: claude-opus-4-5
provider: pi
source_hash: ea7ef23e6d77801f4ef5fc56685ef4470f79f5aecab448d644a72cbab53521b7
source_path: channels/grammy.md
workflow: 14
---
# grammY 集成Telegram Bot API
# 为什么选择 grammY
- TypeScript 优先的 Bot API 客户端,内置长轮询 + webhook 辅助工具、中间件、错误处理、速率限制器。
- 比手动编写 fetch + FormData 更简洁的媒体辅助工具;支持所有 Bot API 方法。
- 可扩展:通过自定义 fetch 支持代理,会话中间件(可选),类型安全的上下文。
# 已交付的功能
- **单一客户端路径:** 基于 fetch 的实现已移除grammY 现在是唯一的 Telegram 客户端(发送 + Gateway网关默认启用 grammY throttler。
- **Gateway网关** `monitorTelegramProvider` 构建一个 grammY `Bot`,接入提及/允许列表门控、通过 `getFile`/`download` 下载媒体,并通过 `sendMessage/sendPhoto/sendVideo/sendAudio/sendDocument` 投递回复。支持通过 `webhookCallback` 进行长轮询或 webhook。
- **代理:** 可选的 `channels.telegram.proxy` 通过 grammY 的 `client.baseFetch` 使用 `undici.ProxyAgent`
- **Webhook 支持:** `webhook-set.ts` 封装了 `setWebhook/deleteWebhook``webhook.ts` 托管回调并支持健康检查 + 优雅关闭。当设置了 `channels.telegram.webhookUrl` + `channels.telegram.webhookSecret` 时 Gateway网关启用 webhook 模式(否则使用长轮询)。
- **会话:** 私聊合并到智能体主会话(`agent:<agentId>:<mainKey>`);群组使用 `agent:<agentId>:telegram:group:<chatId>`;回复路由回同一渠道。
- **配置选项:** `channels.telegram.botToken`、`channels.telegram.dmPolicy`、`channels.telegram.groups`(允许列表 + 提及默认值)、`channels.telegram.allowFrom`、`channels.telegram.groupAllowFrom`、`channels.telegram.groupPolicy`、`channels.telegram.mediaMaxMb`、`channels.telegram.linkPreview`、`channels.telegram.proxy`、`channels.telegram.webhookSecret`、`channels.telegram.webhookUrl`。
- **草稿流式传输:** 可选的 `channels.telegram.streamMode` 在私有话题聊天中使用 `sendMessageDraft`Bot API 9.3+)。这与渠道分块流式传输是分开的。
- **测试:** grammY mock 覆盖了私信 + 群组提及门控和出站发送;欢迎更多媒体/webhook 测试用例。
待讨论问题
- 如果遇到 Bot API 429 错误,考虑使用可选的 grammY 插件throttler
- 添加更多结构化的媒体测试(贴纸、语音消息)。
- 使 webhook 监听端口可配置(目前固定为 8787除非通过 Gateway网关接入

View file

@ -0,0 +1,302 @@
---
read_when:
- 设置 iMessage 支持
- 调试 iMessage 收发
summary: 通过 imsg基于 stdio 的 JSON-RPC实现 iMessage 支持、设置和 chat_id 路由
title: iMessage
x-i18n:
generated_at: "2026-02-01T19:21:07Z"
model: claude-opus-4-5
provider: pi
source_hash: bc19756a42ead80a0845f18c4830c3f1f40948f69b2b016a4026598cfb8fef0d
source_path: channels/imessage.md
workflow: 14
---
# iMessageimsg
状态:外部 CLI 集成。Gateway网关启动 `imsg rpc`(基于 stdio 的 JSON-RPC
## 快速设置(新手)
1. 确保此 Mac 上的"信息"已登录。
2. 安装 `imsg`
- `brew install steipete/tap/imsg`
3. 配置 OpenClaw 的 `channels.imessage.cliPath``channels.imessage.dbPath`
4. 启动 Gateway网关并批准所有 macOS 提示(自动化 + 完全磁盘访问权限)。
最小配置:
```json5
{
channels: {
imessage: {
enabled: true,
cliPath: "/usr/local/bin/imsg",
dbPath: "/Users/<you>/Library/Messages/chat.db",
},
},
}
```
## 它是什么
- 在 macOS 上由 `imsg` 支持的 iMessage 渠道。
- 确定性路由:回复始终发回 iMessage。
- 私信共享智能体的主会话;群组是隔离的(`agent:<agentId>:imessage:group:<chat_id>`)。
- 如果多参与者线程以 `is_group=false` 到达,你仍然可以通过 `chat_id` 使用 `channels.imessage.groups` 来隔离它(参见下方"类群组线程")。
## 配置写入
默认情况下iMessage 允许通过 `/config set|unset` 触发的配置更新写入(需要 `commands.config: true`)。
通过以下方式禁用:
```json5
{
channels: { imessage: { configWrites: false } },
}
```
## 要求
- macOS 且"信息"已登录。
- OpenClaw + `imsg` 需要完全磁盘访问权限(访问 Messages 数据库)。
- 发送时需要自动化权限。
- `channels.imessage.cliPath` 可以指向任何代理 stdin/stdout 的命令(例如,通过 SSH 连接到另一台 Mac 并运行 `imsg rpc` 的包装脚本)。
## 设置(快速路径)
1. 确保此 Mac 上的"信息"已登录。
2. 配置 iMessage 并启动 Gateway网关。
### 专用机器人 macOS 用户(用于隔离身份)
如果你希望机器人从一个**独立的 iMessage 身份**发送消息(并保持你的个人"信息"整洁),请使用专用的 Apple ID + 专用的 macOS 用户。
1. 创建一个专用的 Apple ID例如`my-cool-bot@icloud.com`)。
- Apple 可能需要手机号码进行验证/双重认证。
2. 创建一个 macOS 用户(例如:`openclawhome`)并登录。
3. 在该 macOS 用户中打开"信息"并使用机器人 Apple ID 登录 iMessage。
4. 启用远程登录(系统设置 → 通用 → 共享 → 远程登录)。
5. 安装 `imsg`
- `brew install steipete/tap/imsg`
6. 设置 SSH 使 `ssh <bot-macos-user>@localhost true` 无需密码即可工作。
7. 将 `channels.imessage.accounts.bot.cliPath` 指向一个以机器人用户身份运行 `imsg` 的 SSH 包装脚本。
首次运行注意事项:发送/接收可能需要在*机器人 macOS 用户*中进行 GUI 审批(自动化 + 完全磁盘访问权限)。如果 `imsg rpc` 看起来卡住或退出,请登录该用户(屏幕共享很有帮助),运行一次 `imsg chats --limit 1` / `imsg send ...`,批准提示,然后重试。
示例包装脚本(`chmod +x`)。将 `<bot-macos-user>` 替换为你的实际 macOS 用户名:
```bash
#!/usr/bin/env bash
set -euo pipefail
# 先运行一次交互式 SSH 以接受主机密钥:
# ssh <bot-macos-user>@localhost true
exec /usr/bin/ssh -o BatchMode=yes -o ConnectTimeout=5 -T <bot-macos-user>@localhost \
"/usr/local/bin/imsg" "$@"
```
示例配置:
```json5
{
channels: {
imessage: {
enabled: true,
accounts: {
bot: {
name: "Bot",
enabled: true,
cliPath: "/path/to/imsg-bot",
dbPath: "/Users/<bot-macos-user>/Library/Messages/chat.db",
},
},
},
},
}
```
对于单账户设置,使用扁平选项(`channels.imessage.cliPath`、`channels.imessage.dbPath`)而非 `accounts` 映射。
### 远程/SSH 变体(可选)
如果你想在另一台 Mac 上使用 iMessage`channels.imessage.cliPath` 设置为通过 SSH 在远程 macOS 主机上运行 `imsg` 的包装脚本。OpenClaw 只需要 stdio。
示例包装脚本:
```bash
#!/usr/bin/env bash
exec ssh -T gateway-host imsg "$@"
```
**远程附件:** 当 `cliPath` 通过 SSH 指向远程主机时Messages 数据库中的附件路径引用的是远程机器上的文件。OpenClaw 可以通过设置 `channels.imessage.remoteHost` 自动通过 SCP 获取这些文件:
```json5
{
channels: {
imessage: {
cliPath: "~/imsg-ssh", // 到远程 Mac 的 SSH 包装脚本
remoteHost: "user@gateway-host", // 用于 SCP 文件传输
includeAttachments: true,
},
},
}
```
如果未设置 `remoteHost`OpenClaw 会尝试通过解析你包装脚本中的 SSH 命令来自动检测。建议显式配置以确保可靠性。
#### 通过 Tailscale 连接远程 Mac示例
如果 Gateway网关运行在 Linux 主机/虚拟机上但 iMessage 必须运行在 Mac 上Tailscale 是最简单的桥接方案Gateway网关通过 tailnet 与 Mac 通信,通过 SSH 运行 `imsg`,并通过 SCP 传回附件。
架构:
```
┌──────────────────────────────┐ SSH (imsg rpc) ┌──────────────────────────┐
│ Gateway网关主机Linux/VM │──────────────────────────────────▶│ 装有 Messages + imsg 的 Mac │
│ - openclaw gateway │ SCP附件 │ - Messages 已登录 │
│ - channels.imessage.cliPath │◀──────────────────────────────────│ - 远程登录已启用 │
└──────────────────────────────┘ └──────────────────────────┘
│ Tailscale tailnet主机名或 100.x.y.z
user@gateway-host
```
具体配置示例Tailscale 主机名):
```json5
{
channels: {
imessage: {
enabled: true,
cliPath: "~/.openclaw/scripts/imsg-ssh",
remoteHost: "bot@mac-mini.tailnet-1234.ts.net",
includeAttachments: true,
dbPath: "/Users/bot/Library/Messages/chat.db",
},
},
}
```
示例包装脚本(`~/.openclaw/scripts/imsg-ssh`
```bash
#!/usr/bin/env bash
exec ssh -T bot@mac-mini.tailnet-1234.ts.net imsg "$@"
```
注意事项:
- 确保 Mac 已登录"信息",且远程登录已启用。
- 使用 SSH 密钥使 `ssh bot@mac-mini.tailnet-1234.ts.net` 无需提示即可工作。
- `remoteHost` 应与 SSH 目标匹配,以便 SCP 可以获取附件。
多账户支持:使用 `channels.imessage.accounts`,每个账户配置独立选项和可选的 `name`。共享模式请参阅 [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts)。不要提交 `~/.openclaw/openclaw.json`(它通常包含 token
## 访问控制(私信 + 群组)
私信:
- 默认:`channels.imessage.dmPolicy = "pairing"`。
- 未知发送者会收到配对码;在批准之前消息会被忽略(配对码 1 小时后过期)。
- 通过以下方式批准:
- `openclaw pairing list imessage`
- `openclaw pairing approve imessage <CODE>`
- 配对是 iMessage 私信的默认令牌交换方式。详情:[配对](/start/pairing)
群组:
- `channels.imessage.groupPolicy = open | allowlist | disabled`
- 当设置为 `allowlist` 时,`channels.imessage.groupAllowFrom` 控制谁可以在群组中触发。
- 提及门控使用 `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`),因为 iMessage 没有原生提及元数据。
- 多智能体覆盖:在 `agents.list[].groupChat.mentionPatterns` 上设置每个智能体的模式。
## 工作原理(行为)
- `imsg` 流式传输消息事件Gateway网关将其标准化为共享的渠道信封。
- 回复始终路由回同一个 chat id 或用户名。
## 类群组线程(`is_group=false`
一些 iMessage 线程可能有多个参与者,但由于"信息"存储聊天标识符的方式,仍然以 `is_group=false` 到达。
如果你在 `channels.imessage.groups` 下显式配置了一个 `chat_id`OpenClaw 会将该线程视为"群组",用于:
- 会话隔离(独立的 `agent:<agentId>:imessage:group:<chat_id>` 会话键)
- 群组允许列表/提及门控行为
示例:
```json5
{
channels: {
imessage: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: {
"42": { requireMention: false },
},
},
},
}
```
当你想为特定线程使用隔离的个性/模型时很有用(参见[多智能体路由](/concepts/multi-agent))。有关文件系统隔离,请参阅[沙箱](/gateway/sandboxing)。
## 媒体 + 限制
- 通过 `channels.imessage.includeAttachments` 可选接收附件。
- 媒体上限通过 `channels.imessage.mediaMaxMb` 设置。
## 限制
- 出站文本按 `channels.imessage.textChunkLimit` 分块(默认 4000
- 可选的换行分块:设置 `channels.imessage.chunkMode="newline"` 在按长度分块之前按空行(段落边界)分割。
- 媒体上传上限由 `channels.imessage.mediaMaxMb` 限制(默认 16
## 寻址 / 投递目标
推荐使用 `chat_id` 进行稳定路由:
- `chat_id:123`(推荐)
- `chat_guid:...`
- `chat_identifier:...`
- 直接用户名:`imessage:+1555` / `sms:+1555` / `user@example.com`
列出聊天:
```
imsg chats --limit 20
```
## 配置参考iMessage
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.imessage.enabled`:启用/禁用渠道启动。
- `channels.imessage.cliPath``imsg` 的路径。
- `channels.imessage.dbPath`Messages 数据库路径。
- `channels.imessage.remoteHost`:当 `cliPath` 指向远程 Mac 时用于 SCP 附件传输的 SSH 主机(例如 `user@gateway-host`)。未设置时从 SSH 包装脚本自动检测。
- `channels.imessage.service``imessage | sms | auto`。
- `channels.imessage.region`SMS 区域。
- `channels.imessage.dmPolicy``pairing | allowlist | open | disabled`默认pairing
- `channels.imessage.allowFrom`私信允许列表用户名、邮箱、E.164 号码或 `chat_id:*`)。`open` 需要 `"*"`。iMessage 没有用户名;使用用户名或聊天目标。
- `channels.imessage.groupPolicy``open | allowlist | disabled`默认allowlist
- `channels.imessage.groupAllowFrom`:群组发送者允许列表。
- `channels.imessage.historyLimit` / `channels.imessage.accounts.*.historyLimit`包含为上下文的最大群组消息数0 禁用)。
- `channels.imessage.dmHistoryLimit`:私信历史限制(用户回合数)。按用户覆盖:`channels.imessage.dms["<handle>"].historyLimit`。
- `channels.imessage.groups`:按群组默认值 + 允许列表(使用 `"*"` 设置全局默认值)。
- `channels.imessage.includeAttachments`:将附件接收到上下文中。
- `channels.imessage.mediaMaxMb`:入站/出站媒体上限MB
- `channels.imessage.textChunkLimit`:出站分块大小(字符)。
- `channels.imessage.chunkMode``length`(默认)或 `newline`,在按长度分块之前按空行(段落边界)分割。
相关全局选项:
- `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)。
- `messages.responsePrefix`

View file

@ -0,0 +1,50 @@
---
read_when:
- 你想为 OpenClaw 选择一个聊天渠道
- 你需要快速了解支持的消息平台
summary: OpenClaw 可连接的消息平台
title: 聊天渠道
x-i18n:
generated_at: "2026-02-01T19:21:22Z"
model: claude-opus-4-5
provider: pi
source_hash: 2632863def6dee97e0fa8b931762f0969174fd4fb22303a00dcd46527fe4a141
source_path: channels/index.md
workflow: 14
---
# 聊天渠道
OpenClaw 可以在你已经使用的任何聊天应用上与你对话。每个渠道通过 Gateway网关连接。所有渠道都支持文本媒体和回应功能因渠道而异。
## 支持的渠道
- [WhatsApp](/channels/whatsapp) — 最受欢迎;使用 Baileys 并需要二维码配对。
- [Telegram](/channels/telegram) — 通过 grammY 使用 Bot API支持群组。
- [Discord](/channels/discord) — Discord Bot API + Gateway网关支持服务器、频道和私信。
- [Slack](/channels/slack) — Bolt SDK工作区应用。
- [Google Chat](/channels/googlechat) — 通过 HTTP webhook 使用 Google Chat API 应用。
- [Mattermost](/channels/mattermost) — Bot API + WebSocket频道、群组、私信插件需单独安装
- [Signal](/channels/signal) — signal-cli注重隐私。
- [BlueBubbles](/channels/bluebubbles) — **推荐用于 iMessage**;使用 BlueBubbles macOS 服务器 REST API功能完整编辑、撤回、特效、回应、群组管理——编辑功能在 macOS 26 Tahoe 上目前不可用)。
- [iMessage](/channels/imessage) — 仅限 macOS通过 imsg 原生集成(旧版,新设置建议使用 BlueBubbles
- [Microsoft Teams](/channels/msteams) — Bot Framework企业支持插件需单独安装
- [LINE](/channels/line) — LINE Messaging API 机器人(插件,需单独安装)。
- [Nextcloud Talk](/channels/nextcloud-talk) — 通过 Nextcloud Talk 的自托管聊天(插件,需单独安装)。
- [Matrix](/channels/matrix) — Matrix 协议(插件,需单独安装)。
- [Nostr](/channels/nostr) — 通过 NIP-04 的去中心化私信(插件,需单独安装)。
- [Tlon](/channels/tlon) — 基于 Urbit 的通讯工具(插件,需单独安装)。
- [Twitch](/channels/twitch) — 通过 IRC 连接的 Twitch 聊天(插件,需单独安装)。
- [Zalo](/channels/zalo) — Zalo Bot API越南流行的通讯工具插件需单独安装
- [Zalo Personal](/channels/zalouser) — 通过二维码登录的 Zalo 个人账户(插件,需单独安装)。
- [WebChat](/web/webchat) — 通过 WebSocket 的 Gateway网关 WebChat UI。
## 注意事项
- 渠道可以同时运行;配置多个渠道后 OpenClaw 会按聊天路由。
- 最快的设置通常是 **Telegram**(简单的 bot token。WhatsApp 需要二维码配对并在磁盘上存储更多状态。
- 群组行为因渠道而异;参见[群组](/concepts/groups)。
- 私信配对和允许列表出于安全考虑强制执行;参见[安全](/gateway/security)。
- Telegram 内部实现:[grammY 说明](/channels/grammy)。
- 故障排除:[渠道故障排除](/channels/troubleshooting)。
- 模型提供商单独文档化;参见[模型提供商](/providers/models)。

180
docs/zh-CN/channels/line.md Normal file
View file

@ -0,0 +1,180 @@
---
read_when:
- 你想将 OpenClaw 连接到 LINE
- 你需要 LINE webhook + 凭据设置
- 你需要 LINE 特定的消息选项
summary: LINE Messaging API 插件设置、配置和使用
title: LINE
x-i18n:
generated_at: "2026-02-01T19:21:38Z"
model: claude-opus-4-5
provider: pi
source_hash: 8fbac126786f95b9454f3cc61906c2798393a8d7914e787d3755c020c7ab2da6
source_path: channels/line.md
workflow: 14
---
# LINE插件
LINE 通过 LINE Messaging API 连接到 OpenClaw。插件作为 Gateway网关上的 webhook 接收器运行,使用你的频道访问 token + 频道密钥进行认证。
状态通过插件支持。支持私信、群聊、媒体、位置、Flex 消息、模板消息和快速回复。不支持回应和线程。
## 需要插件
安装 LINE 插件:
```bash
openclaw plugins install @openclaw/line
```
本地检出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/line
```
## 设置
1. 创建 LINE Developers 账户并打开控制台:
https://developers.line.biz/console/
2. 创建(或选择)一个 Provider 并添加一个 **Messaging API** 频道。
3. 从频道设置中复制 **Channel access token****Channel secret**
4. 在 Messaging API 设置中启用 **Use webhook**
5. 将 webhook URL 设置为你的 Gateway网关端点需要 HTTPS
```
https://gateway-host/line/webhook
```
Gateway网关响应 LINE 的 webhook 验证GET和入站事件POST。如果你需要自定义路径请设置 `channels.line.webhookPath``channels.line.accounts.<id>.webhookPath` 并相应更新 URL。
## 配置
最小配置:
```json5
{
channels: {
line: {
enabled: true,
channelAccessToken: "LINE_CHANNEL_ACCESS_TOKEN",
channelSecret: "LINE_CHANNEL_SECRET",
dmPolicy: "pairing",
},
},
}
```
环境变量(仅默认账户):
- `LINE_CHANNEL_ACCESS_TOKEN`
- `LINE_CHANNEL_SECRET`
Token/密钥文件:
```json5
{
channels: {
line: {
tokenFile: "/path/to/line-token.txt",
secretFile: "/path/to/line-secret.txt",
},
},
}
```
多账户:
```json5
{
channels: {
line: {
accounts: {
marketing: {
channelAccessToken: "...",
channelSecret: "...",
webhookPath: "/line/marketing",
},
},
},
},
}
```
## 访问控制
私信默认需要配对。未知发送者会收到配对码,在批准之前其消息会被忽略。
```bash
openclaw pairing list line
openclaw pairing approve line <CODE>
```
允许列表和策略:
- `channels.line.dmPolicy``pairing | allowlist | open | disabled`
- `channels.line.allowFrom`:私信的允许 LINE 用户 ID 列表
- `channels.line.groupPolicy``allowlist | open | disabled`
- `channels.line.groupAllowFrom`:群组的允许 LINE 用户 ID 列表
- 按群组覆盖:`channels.line.groups.<groupId>.allowFrom`
LINE ID 区分大小写。有效的 ID 格式如下:
- 用户:`U` + 32 位十六进制字符
- 群组:`C` + 32 位十六进制字符
- 房间:`R` + 32 位十六进制字符
## 消息行为
- 文本在 5000 字符处分块。
- Markdown 格式会被去除;代码块和表格在可能时会转换为 Flex 卡片。
- 流式响应会被缓冲;智能体工作时 LINE 接收完整分块并显示加载动画。
- 媒体下载上限由 `channels.line.mediaMaxMb` 限制(默认 10
## 渠道数据(富消息)
使用 `channelData.line` 发送快速回复、位置、Flex 卡片或模板消息。
```json5
{
text: "Here you go",
channelData: {
line: {
quickReplies: ["Status", "Help"],
location: {
title: "Office",
address: "123 Main St",
latitude: 35.681236,
longitude: 139.767125,
},
flexMessage: {
altText: "Status card",
contents: {
/* Flex 负载 */
},
},
templateMessage: {
type: "confirm",
text: "Proceed?",
confirmLabel: "Yes",
confirmData: "yes",
cancelLabel: "No",
cancelData: "no",
},
},
},
}
```
LINE 插件还附带一个 `/card` 命令用于 Flex 消息预设:
```
/card info "Welcome" "Thanks for joining!"
```
## 故障排除
- **Webhook 验证失败:** 确保 webhook URL 为 HTTPS 且 `channelSecret` 与 LINE 控制台匹配。
- **没有入站事件:** 确认 webhook 路径与 `channels.line.webhookPath` 匹配且 Gateway网关可从 LINE 访问。
- **媒体下载错误:** 如果媒体超过默认限制,请增大 `channels.line.mediaMaxMb`

View file

@ -0,0 +1,63 @@
---
read_when:
- 添加或修改渠道位置解析
- 在智能体提示或工具中使用位置上下文字段
summary: 入站渠道位置解析Telegram + WhatsApp及上下文字段
title: 渠道位置解析
x-i18n:
generated_at: "2026-02-01T19:21:46Z"
model: claude-opus-4-5
provider: pi
source_hash: 5602ef105c3da7e47497bfed8fc343dd8d7f3c019ff7e423a08b25092c5a1837
source_path: channels/location.md
workflow: 14
---
# 渠道位置解析
OpenClaw 将聊天渠道中分享的位置标准化为:
- 附加到入站消息体的可读文本,以及
- 自动回复上下文负载中的结构化字段。
目前支持:
- **Telegram**(位置图钉 + 地点 + 实时位置)
- **WhatsApp**locationMessage + liveLocationMessage
- **Matrix**`m.location` 配合 `geo_uri`
## 文本格式
位置以友好的行格式呈现,不带括号:
- 图钉:
- `📍 48.858844, 2.294351 ±12m`
- 命名地点:
- `📍 Eiffel Tower — Champ de Mars, Paris (48.858844, 2.294351 ±12m)`
- 实时分享:
- `🛰 Live location: 48.858844, 2.294351 ±12m`
如果渠道包含标题/评论,会附加在下一行:
```
📍 48.858844, 2.294351 ±12m
Meet here
```
## 上下文字段
当存在位置信息时,以下字段会被添加到 `ctx` 中:
- `LocationLat`(数字)
- `LocationLon`(数字)
- `LocationAccuracy`(数字,米;可选)
- `LocationName`(字符串;可选)
- `LocationAddress`(字符串;可选)
- `LocationSource``pin | place | live`
- `LocationIsLive`(布尔值)
## 渠道说明
- **Telegram**:地点映射到 `LocationName/LocationAddress`;实时位置使用 `live_period`
- **WhatsApp**`locationMessage.comment` 和 `liveLocationMessage.caption` 作为标题行附加。
- **Matrix**`geo_uri` 解析为图钉位置;忽略海拔高度,`LocationIsLive` 始终为 false。

View file

@ -0,0 +1,221 @@
---
read_when:
- 开发 Matrix 渠道功能
summary: Matrix 支持状态、功能和配置
title: Matrix
x-i18n:
generated_at: "2026-02-01T19:22:24Z"
model: claude-opus-4-5
provider: pi
source_hash: b276b5263593c766e7be6549abbb27927177e7b51cfd297b4825965372513ee4
source_path: channels/matrix.md
workflow: 14
---
# Matrix插件
Matrix 是一个开放、去中心化的消息协议。OpenClaw 作为 Matrix **用户**连接到任何主服务器,因此你需要为机器人创建一个 Matrix 账户。登录后你可以直接私信机器人或邀请它加入房间Matrix 的"群组"。Beeper 也是一个可用的客户端选项,但它需要启用端到端加密。
状态:通过插件支持(@vector-im/matrix-bot-sdk。支持私信、房间、线程、媒体、回应、投票发送 + poll-start 转为文本)、位置和端到端加密(需要加密支持)。
## 需要插件
Matrix 作为插件发布,不包含在核心安装中。
通过 CLI 安装npm 注册表):
```bash
openclaw plugins install @openclaw/matrix
```
本地检出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/matrix
```
如果你在配置/新手引导期间选择了 Matrix 并检测到 git 检出OpenClaw 会自动提供本地安装路径。
详情:[插件](/plugin)
## 设置
1. 安装 Matrix 插件:
- 从 npm`openclaw plugins install @openclaw/matrix`
- 从本地检出:`openclaw plugins install ./extensions/matrix`
2. 在主服务器上创建 Matrix 账户:
- 在 [https://matrix.org/ecosystem/hosting/](https://matrix.org/ecosystem/hosting/) 浏览托管选项
- 或自行托管。
3. 获取机器人账户的访问 token
- 在你的主服务器上使用 Matrix 登录 API 配合 `curl`
```bash
curl --request POST \
--url https://matrix.example.org/_matrix/client/v3/login \
--header 'Content-Type: application/json' \
--data '{
"type": "m.login.password",
"identifier": {
"type": "m.id.user",
"user": "your-user-name"
},
"password": "your-password"
}'
```
- 将 `matrix.example.org` 替换为你的主服务器 URL。
- 或设置 `channels.matrix.userId` + `channels.matrix.password`OpenClaw 调用相同的登录端点,将访问 token 存储在 `~/.openclaw/credentials/matrix/credentials.json` 中,并在下次启动时重用。
4. 配置凭据:
- 环境变量:`MATRIX_HOMESERVER`、`MATRIX_ACCESS_TOKEN`(或 `MATRIX_USER_ID` + `MATRIX_PASSWORD`
- 或配置:`channels.matrix.*`
- 如果两者都设置了,配置优先。
- 使用访问 token 时:用户 ID 通过 `/whoami` 自动获取。
- 设置时,`channels.matrix.userId` 应为完整的 Matrix ID例如`@bot:example.org`)。
5. 重启 Gateway网关或完成新手引导
6. 从任何 Matrix 客户端Element、Beeper 等;参见 https://matrix.org/ecosystem/clients/与机器人开始私信或邀请它加入房间。Beeper 需要端到端加密,因此请设置 `channels.matrix.encryption: true` 并验证设备。
最小配置(访问 token用户 ID 自动获取):
```json5
{
channels: {
matrix: {
enabled: true,
homeserver: "https://matrix.example.org",
accessToken: "syt_***",
dm: { policy: "pairing" },
},
},
}
```
端到端加密配置(启用端到端加密):
```json5
{
channels: {
matrix: {
enabled: true,
homeserver: "https://matrix.example.org",
accessToken: "syt_***",
encryption: true,
dm: { policy: "pairing" },
},
},
}
```
## 加密(端到端加密)
端到端加密通过 Rust 加密 SDK **支持**
通过 `channels.matrix.encryption: true` 启用:
- 如果加密模块加载成功,加密房间会自动解密。
- 向加密房间发送时,出站媒体会被加密。
- 首次连接时OpenClaw 会从你的其他会话请求设备验证。
- 在另一个 Matrix 客户端Element 等)中验证设备以启用密钥共享。
- 如果加密模块无法加载端到端加密将被禁用且加密房间无法解密OpenClaw 会记录警告。
- 如果你看到缺少加密模块的错误(例如 `@matrix-org/matrix-sdk-crypto-nodejs-*`),请允许 `@matrix-org/matrix-sdk-crypto-nodejs` 的构建脚本并运行 `pnpm rebuild @matrix-org/matrix-sdk-crypto-nodejs` 或通过 `node node_modules/@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js` 获取二进制文件。
加密状态按账户 + 访问 token 存储在 `~/.openclaw/matrix/accounts/<account>/<homeserver>__<user>/<token-hash>/crypto/`SQLite 数据库)。同步状态存储在同一目录下的 `bot-storage.json` 中。如果访问 token设备发生变化会创建新的存储机器人必须重新验证才能在加密房间中使用。
**设备验证:**
启用端到端加密后,机器人会在启动时从你的其他会话请求验证。打开 Element或其他客户端并批准验证请求以建立信任。验证完成后机器人可以解密加密房间中的消息。
## 路由模型
- 回复始终发回 Matrix。
- 私信共享智能体的主会话;房间映射到群组会话。
## 访问控制(私信)
- 默认:`channels.matrix.dm.policy = "pairing"`。未知发送者会收到配对码。
- 通过以下方式批准:
- `openclaw pairing list matrix`
- `openclaw pairing approve matrix <CODE>`
- 公开私信:`channels.matrix.dm.policy="open"` 加上 `channels.matrix.dm.allowFrom=["*"]`
- `channels.matrix.dm.allowFrom` 接受用户 ID 或显示名称。向导在目录搜索可用时会将显示名称解析为用户 ID。
## 房间(群组)
- 默认:`channels.matrix.groupPolicy = "allowlist"`(提及门控)。使用 `channels.defaults.groupPolicy` 可在未设置时覆盖默认值。
- 使用 `channels.matrix.groups` 允许列表中的房间(房间 ID、别名或名称
```json5
{
channels: {
matrix: {
groupPolicy: "allowlist",
groups: {
"!roomId:example.org": { allow: true },
"#alias:example.org": { allow: true },
},
groupAllowFrom: ["@owner:example.org"],
},
},
}
```
- `requireMention: false` 启用该房间的自动回复。
- `groups."*"` 可以设置跨房间的提及门控默认值。
- `groupAllowFrom` 限制哪些发送者可以在房间中触发机器人(可选)。
- 按房间的 `users` 允许列表可以进一步限制特定房间内的发送者。
- 配置向导会提示输入房间允许列表(房间 ID、别名或名称并在可能时解析名称。
- 启动时OpenClaw 将允许列表中的房间/用户名称解析为 ID 并记录映射;未解析的条目保持原样。
- 邀请默认自动加入;通过 `channels.matrix.autoJoin``channels.matrix.autoJoinAllowlist` 控制。
- 要**不允许任何房间**,设置 `channels.matrix.groupPolicy: "disabled"`(或保持空的允许列表)。
- 旧版键:`channels.matrix.rooms`(与 `groups` 结构相同)。
## 线程
- 支持回复线程。
- `channels.matrix.threadReplies` 控制回复是否保持在线程中:
- `off`、`inbound`(默认)、`always`
- `channels.matrix.replyToMode` 控制不在线程中回复时的 reply-to 元数据:
- `off`(默认)、`first`、`all`
## 功能
| 功能 | 状态 |
| ---------- | ---------------------------------------------------------- |
| 私信 | ✅ 支持 |
| 房间 | ✅ 支持 |
| 线程 | ✅ 支持 |
| 媒体 | ✅ 支持 |
| 端到端加密 | ✅ 支持(需要加密模块) |
| 回应 | ✅ 支持(通过工具发送/读取) |
| 投票 | ✅ 支持发送;入站 poll start 转换为文本(响应/结束被忽略) |
| 位置 | ✅ 支持geo URI忽略海拔 |
| 原生命令 | ✅ 支持 |
## 配置参考Matrix
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.matrix.enabled`:启用/禁用渠道启动。
- `channels.matrix.homeserver`:主服务器 URL。
- `channels.matrix.userId`Matrix 用户 ID使用访问 token 时可选)。
- `channels.matrix.accessToken`:访问 token。
- `channels.matrix.password`登录密码token 会被存储)。
- `channels.matrix.deviceName`:设备显示名称。
- `channels.matrix.encryption`启用端到端加密默认false
- `channels.matrix.initialSyncLimit`:初始同步限制。
- `channels.matrix.threadReplies``off | inbound | always`默认inbound
- `channels.matrix.textChunkLimit`:出站文本分块大小(字符)。
- `channels.matrix.chunkMode``length`(默认)或 `newline`,在按长度分块之前按空行(段落边界)分割。
- `channels.matrix.dm.policy``pairing | allowlist | open | disabled`默认pairing
- `channels.matrix.dm.allowFrom`:私信允许列表(用户 ID 或显示名称)。`open` 需要 `"*"`。向导在可能时将名称解析为 ID。
- `channels.matrix.groupPolicy``allowlist | open | disabled`默认allowlist
- `channels.matrix.groupAllowFrom`:群组消息的允许发送者列表。
- `channels.matrix.allowlistOnly`:强制对私信 + 房间执行允许列表规则。
- `channels.matrix.groups`:群组允许列表 + 按房间设置映射。
- `channels.matrix.rooms`:旧版群组允许列表/配置。
- `channels.matrix.replyToMode`:线程/标签的 reply-to 模式。
- `channels.matrix.mediaMaxMb`:入站/出站媒体上限MB
- `channels.matrix.autoJoin`:邀请处理(`always | allowlist | off`默认always
- `channels.matrix.autoJoinAllowlist`:自动加入的允许房间 ID/别名。
- `channels.matrix.actions`按操作的工具门控reactions/messages/pins/memberInfo/channelInfo

View file

@ -0,0 +1,142 @@
---
read_when:
- 设置 Mattermost
- 调试 Mattermost 路由
summary: Mattermost 机器人设置和 OpenClaw 配置
title: Mattermost
x-i18n:
generated_at: "2026-02-01T19:22:40Z"
model: claude-opus-4-5
provider: pi
source_hash: 57fabe5eb0efbcb885f4178b317b2fa99a41daf609e3a471de2b44db9def4ad7
source_path: channels/mattermost.md
workflow: 14
---
# Mattermost插件
状态通过插件支持bot token + WebSocket 事件。支持频道、群组和私信。Mattermost 是一个可自托管的团队消息平台;有关产品详情和下载请访问官方网站 [mattermost.com](https://mattermost.com)。
## 需要插件
Mattermost 作为插件发布,不包含在核心安装中。
通过 CLI 安装npm 注册表):
```bash
openclaw plugins install @openclaw/mattermost
```
本地检出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/mattermost
```
如果你在配置/新手引导期间选择了 Mattermost 并检测到 git 检出OpenClaw 会自动提供本地安装路径。
详情:[插件](/plugin)
## 快速设置
1. 安装 Mattermost 插件。
2. 创建一个 Mattermost 机器人账户并复制 **bot token**
3. 复制 Mattermost **基础 URL**(例如 `https://chat.example.com`)。
4. 配置 OpenClaw 并启动 Gateway网关。
最小配置:
```json5
{
channels: {
mattermost: {
enabled: true,
botToken: "mm-token",
baseUrl: "https://chat.example.com",
dmPolicy: "pairing",
},
},
}
```
## 环境变量(默认账户)
如果你偏好使用环境变量,请在 Gateway网关主机上设置
- `MATTERMOST_BOT_TOKEN=...`
- `MATTERMOST_URL=https://chat.example.com`
环境变量仅适用于**默认**账户(`default`)。其他账户必须使用配置值。
## 聊天模式
Mattermost 自动响应私信。频道行为由 `chatmode` 控制:
- `oncall`(默认):仅在频道中被 @提及时响应
- `onmessage`:响应频道中的每条消息。
- `onchar`:当消息以触发前缀开头时响应。
配置示例:
```json5
{
channels: {
mattermost: {
chatmode: "onchar",
oncharPrefixes: [">", "!"],
},
},
}
```
注意事项:
- `onchar` 模式仍然响应明确的 @提及
- `channels.mattermost.requireMention` 对旧版配置仍然有效,但推荐使用 `chatmode`
## 访问控制(私信)
- 默认:`channels.mattermost.dmPolicy = "pairing"`(未知发送者会收到配对码)。
- 通过以下方式批准:
- `openclaw pairing list mattermost`
- `openclaw pairing approve mattermost <CODE>`
- 公开私信:`channels.mattermost.dmPolicy="open"` 加上 `channels.mattermost.allowFrom=["*"]`
## 频道(群组)
- 默认:`channels.mattermost.groupPolicy = "allowlist"`(提及门控)。
- 使用 `channels.mattermost.groupAllowFrom` 允许列表发送者(用户 ID 或 `@username`)。
- 开放频道:`channels.mattermost.groupPolicy="open"`(提及门控)。
## 出站投递目标
`openclaw message send` 或定时任务/webhook 中使用以下目标格式:
- `channel:<id>` 用于频道
- `user:<id>` 用于私信
- `@username` 用于私信(通过 Mattermost API 解析)
裸 ID 被视为频道。
## 多账户
Mattermost 支持在 `channels.mattermost.accounts` 下配置多个账户:
```json5
{
channels: {
mattermost: {
accounts: {
default: { name: "Primary", botToken: "mm-token", baseUrl: "https://chat.example.com" },
alerts: { name: "Alerts", botToken: "mm-token-2", baseUrl: "https://alerts.example.com" },
},
},
},
}
```
## 故障排除
- 频道中没有回复确保机器人已加入频道并提及它oncall 模式使用触发前缀onchar 模式),或设置 `chatmode: "onmessage"`
- 认证错误:检查 bot token、基础 URL 以及账户是否已启用。
- 多账户问题:环境变量仅适用于 `default` 账户。

View file

@ -0,0 +1,770 @@
---
read_when:
- 开发 Microsoft Teams 渠道功能
summary: Microsoft Teams 机器人支持状态、功能和配置
title: Microsoft Teams
x-i18n:
generated_at: "2026-02-01T19:26:12Z"
model: claude-opus-4-5
provider: pi
source_hash: 3d5641c578086f7569f42276d4ef2462200b9927ca3f505e6ee26806103eaa60
source_path: channels/msteams.md
workflow: 14
---
# Microsoft Teams插件
> "进入此处者,放弃一切希望。"
更新时间2026-01-21
状态:支持文本 + 私信附件;频道/群组文件发送需要 `sharePointSiteId` + Graph 权限(参见[在群聊中发送文件](#在群聊中发送文件))。投票通过 Adaptive Cards 发送。
## 需要插件
Microsoft Teams 作为插件发布,不包含在核心安装中。
**破坏性变更2026.1.15** Microsoft Teams 已从核心中移出。如果你使用它,必须安装插件。
原因说明:保持核心安装更轻量,并让 Microsoft Teams 依赖项可以独立更新。
通过 CLI 安装npm 注册表):
```bash
openclaw plugins install @openclaw/msteams
```
本地检出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/msteams
```
如果你在配置/新手引导期间选择了 Teams 并检测到 git 检出OpenClaw 会自动提供本地安装路径。
详情:[插件](/plugin)
## 快速设置(新手)
1. 安装 Microsoft Teams 插件。
2. 创建一个 **Azure Bot**App ID + 客户端密钥 + 租户 ID
3. 使用这些凭据配置 OpenClaw。
4. 通过公共 URL 或隧道暴露 `/api/messages`(默认端口 3978
5. 安装 Teams 应用包并启动 Gateway网关。
最小配置:
```json5
{
channels: {
msteams: {
enabled: true,
appId: "<APP_ID>",
appPassword: "<APP_PASSWORD>",
tenantId: "<TENANT_ID>",
webhook: { port: 3978, path: "/api/messages" },
},
},
}
```
注意:群聊默认被阻止(`channels.msteams.groupPolicy: "allowlist"`)。要允许群组回复,请设置 `channels.msteams.groupAllowFrom`(或使用 `groupPolicy: "open"` 允许任何成员,提及门控)。
## 目标
- 通过 Teams 私信、群聊或频道与 OpenClaw 对话。
- 保持路由确定性:回复始终发回消息到达的渠道。
- 默认使用安全的渠道行为(除非另行配置,否则需要提及)。
## 配置写入
默认情况下Microsoft Teams 允许通过 `/config set|unset` 触发的配置更新写入(需要 `commands.config: true`)。
通过以下方式禁用:
```json5
{
channels: { msteams: { configWrites: false } },
}
```
## 访问控制(私信 + 群组)
**私信访问**
- 默认:`channels.msteams.dmPolicy = "pairing"`。未知发送者在批准前会被忽略。
- `channels.msteams.allowFrom` 接受 AAD 对象 ID、UPN 或显示名称。当凭据允许时,向导通过 Microsoft Graph 将名称解析为 ID。
**群组访问**
- 默认:`channels.msteams.groupPolicy = "allowlist"`(被阻止,除非你添加 `groupAllowFrom`)。使用 `channels.defaults.groupPolicy` 可在未设置时覆盖默认值。
- `channels.msteams.groupAllowFrom` 控制哪些发送者可以在群聊/频道中触发(回退到 `channels.msteams.allowFrom`)。
- 设置 `groupPolicy: "open"` 可允许任何成员(默认仍需提及门控)。
- 要**不允许任何频道**,设置 `channels.msteams.groupPolicy: "disabled"`
示例:
```json5
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["user@org.com"],
},
},
}
```
**团队 + 频道允许列表**
- 通过在 `channels.msteams.teams` 下列出团队和频道来限定群组/频道回复范围。
- 键可以是团队 ID 或名称;频道键可以是会话 ID 或名称。
- 当 `groupPolicy="allowlist"` 且存在团队允许列表时,仅接受列出的团队/频道(提及门控)。
- 配置向导接受 `Team/Channel` 条目并为你存储。
- 启动时OpenClaw 将团队/频道和用户允许列表名称解析为 ID当 Graph 权限允许时)并记录映射;未解析的条目保持原样。
示例:
```json5
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"My Team": {
channels: {
General: { requireMention: true },
},
},
},
},
},
}
```
## 工作原理
1. 安装 Microsoft Teams 插件。
2. 创建一个 **Azure Bot**App ID + 密钥 + 租户 ID
3. 构建一个引用该机器人并包含下方 RSC 权限的 **Teams 应用包**
4. 将 Teams 应用上传/安装到团队(或私人范围用于私信)。
5. 在 `~/.openclaw/openclaw.json`(或环境变量)中配置 `msteams` 并启动 Gateway网关。
6. Gateway网关默认在 `/api/messages` 上监听 Bot Framework webhook 流量。
## Azure Bot 设置(前提条件)
在配置 OpenClaw 之前,你需要创建一个 Azure Bot 资源。
### 步骤 1创建 Azure Bot
1. 前往[创建 Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot)
2. 填写 **Basics** 标签页:
| 字段 | 值 |
| ------------------ | --------------------------------------------------- |
| **Bot handle** | 你的机器人名称,例如 `openclaw-msteams`(必须唯一) |
| **Subscription** | 选择你的 Azure 订阅 |
| **Resource group** | 新建或使用现有的 |
| **Pricing tier** | **Free** 用于开发/测试 |
| **Type of App** | **Single Tenant**(推荐 - 见下方说明) |
| **Creation type** | **Create new Microsoft App ID** |
> **弃用通知:** 2025-07-31 之后已弃用创建新的多租户机器人。新机器人请使用 **Single Tenant**
3. 点击 **Review + create****Create**(等待约 1-2 分钟)
### 步骤 2获取凭据
1. 前往你的 Azure Bot 资源 → **Configuration**
2. 复制 **Microsoft App ID** → 这是你的 `appId`
3. 点击 **Manage Password** → 进入应用注册
4. 在 **Certificates & secrets****New client secret** → 复制 **Value** → 这是你的 `appPassword`
5. 进入 **Overview** → 复制 **Directory (tenant) ID** → 这是你的 `tenantId`
### 步骤 3配置消息端点
1. 在 Azure Bot → **Configuration**
2. 将 **Messaging endpoint** 设置为你的 webhook URL
- 生产环境:`https://your-domain.com/api/messages`
- 本地开发:使用隧道(参见下方[本地开发](#本地开发隧道)
### 步骤 4启用 Teams 频道
1. 在 Azure Bot → **Channels**
2. 点击 **Microsoft Teams** → Configure → Save
3. 接受服务条款
## 本地开发(隧道)
Teams 无法访问 `localhost`。本地开发请使用隧道:
**方案 Angrok**
```bash
ngrok http 3978
# 复制 https URL例如 https://abc123.ngrok.io
# 将消息端点设置为https://abc123.ngrok.io/api/messages
```
**方案 BTailscale Funnel**
```bash
tailscale funnel 3978
# 使用你的 Tailscale funnel URL 作为消息端点
```
## Teams 开发者门户(替代方案)
除了手动创建清单 ZIP 外,你可以使用 [Teams 开发者门户](https://dev.teams.microsoft.com/apps)
1. 点击 **+ New app**
2. 填写基本信息(名称、描述、开发者信息)
3. 进入 **App features** → **Bot**
4. 选择 **Enter a bot ID manually** 并粘贴你的 Azure Bot App ID
5. 勾选范围:**Personal**、**Team**、**Group Chat**
6. 点击 **Distribute** → **Download app package**
7. 在 Teams 中:**Apps** → **Manage your apps****Upload a custom app** → 选择 ZIP
这通常比手动编辑 JSON 清单更简单。
## 测试机器人
**方案 AAzure Web Chat先验证 webhook**
1. 在 Azure 门户 → 你的 Azure Bot 资源 → **Test in Web Chat**
2. 发送一条消息 - 你应该看到回复
3. 这确认了你的 webhook 端点在 Teams 设置之前可以正常工作
**方案 BTeams安装应用后**
1. 安装 Teams 应用(旁加载或组织目录)
2. 在 Teams 中找到机器人并发送私信
3. 检查 Gateway网关日志中的传入活动
## 设置(最小纯文本)
1. **安装 Microsoft Teams 插件**
- 从 npm`openclaw plugins install @openclaw/msteams`
- 从本地检出:`openclaw plugins install ./extensions/msteams`
2. **机器人注册**
- 创建 Azure Bot见上方并记录
- App ID
- 客户端密钥App password
- 租户 ID单租户
3. **Teams 应用清单**
- 包含一个 `bot` 条目,其中 `botId = <App ID>`
- 范围:`personal`、`team`、`groupChat`。
- `supportsFiles: true`(个人范围文件处理所必需)。
- 添加 RSC 权限(见下方)。
- 创建图标:`outline.png`32x32`color.png`192x192
- 将三个文件打包在一起:`manifest.json`、`outline.png`、`color.png`。
4. **配置 OpenClaw**
```json
{
"msteams": {
"enabled": true,
"appId": "<APP_ID>",
"appPassword": "<APP_PASSWORD>",
"tenantId": "<TENANT_ID>",
"webhook": { "port": 3978, "path": "/api/messages" }
}
}
```
你也可以使用环境变量替代配置键:
- `MSTEAMS_APP_ID`
- `MSTEAMS_APP_PASSWORD`
- `MSTEAMS_TENANT_ID`
5. **机器人端点**
- 将 Azure Bot 消息端点设置为:
- `https://<host>:3978/api/messages`(或你选择的路径/端口)。
6. **运行 Gateway网关**
- 当插件已安装且 `msteams` 配置存在凭据时Teams 渠道会自动启动。
## 历史上下文
- `channels.msteams.historyLimit` 控制多少条最近的频道/群组消息被包含在提示中。
- 回退到 `messages.groupChat.historyLimit`。设置 `0` 可禁用(默认 50
- 私信历史可通过 `channels.msteams.dmHistoryLimit`(用户回合数)限制。按用户覆盖:`channels.msteams.dms["<user_id>"].historyLimit`。
## 当前 Teams RSC 权限(清单)
以下是我们 Teams 应用清单中**现有的 resourceSpecific 权限**。它们仅在安装了应用的团队/聊天中适用。
**频道(团队范围):**
- `ChannelMessage.Read.Group`Application- 无需 @提及即可接收所有频道消息
- `ChannelMessage.Send.Group`Application
- `Member.Read.Group`Application
- `Owner.Read.Group`Application
- `ChannelSettings.Read.Group`Application
- `TeamMember.Read.Group`Application
- `TeamSettings.Read.Group`Application
**群聊:**
- `ChatMessage.Read.Chat`Application- 无需 @提及即可接收所有群聊消息
## 示例 Teams 清单(已脱敏)
包含必需字段的最小有效示例。请替换 ID 和 URL。
```json
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.23/MicrosoftTeams.schema.json",
"manifestVersion": "1.23",
"version": "1.0.0",
"id": "00000000-0000-0000-0000-000000000000",
"name": { "short": "OpenClaw" },
"developer": {
"name": "Your Org",
"websiteUrl": "https://example.com",
"privacyUrl": "https://example.com/privacy",
"termsOfUseUrl": "https://example.com/terms"
},
"description": { "short": "OpenClaw in Teams", "full": "OpenClaw in Teams" },
"icons": { "outline": "outline.png", "color": "color.png" },
"accentColor": "#5B6DEF",
"bots": [
{
"botId": "11111111-1111-1111-1111-111111111111",
"scopes": ["personal", "team", "groupChat"],
"isNotificationOnly": false,
"supportsCalling": false,
"supportsVideo": false,
"supportsFiles": true
}
],
"webApplicationInfo": {
"id": "11111111-1111-1111-1111-111111111111"
},
"authorization": {
"permissions": {
"resourceSpecific": [
{ "name": "ChannelMessage.Read.Group", "type": "Application" },
{ "name": "ChannelMessage.Send.Group", "type": "Application" },
{ "name": "Member.Read.Group", "type": "Application" },
{ "name": "Owner.Read.Group", "type": "Application" },
{ "name": "ChannelSettings.Read.Group", "type": "Application" },
{ "name": "TeamMember.Read.Group", "type": "Application" },
{ "name": "TeamSettings.Read.Group", "type": "Application" },
{ "name": "ChatMessage.Read.Chat", "type": "Application" }
]
}
}
}
```
### 清单注意事项(必需字段)
- `bots[].botId` **必须**与 Azure Bot App ID 匹配。
- `webApplicationInfo.id` **必须**与 Azure Bot App ID 匹配。
- `bots[].scopes` 必须包含你计划使用的范围(`personal`、`team`、`groupChat`)。
- `bots[].supportsFiles: true` 是个人范围文件处理所必需的。
- `authorization.permissions.resourceSpecific` 必须包含频道读取/发送权限(如果你需要频道流量)。
### 更新现有应用
要更新已安装的 Teams 应用(例如添加 RSC 权限):
1. 使用新设置更新 `manifest.json`
2. **递增 `version` 字段**(例如 `1.0.0``1.1.0`
3. **重新打包**清单和图标(`manifest.json`、`outline.png`、`color.png`
4. 上传新的 zip
- **方案 ATeams 管理中心):** Teams 管理中心 → Teams apps → Manage apps → 找到你的应用 → Upload new version
- **方案 B旁加载** 在 Teams 中 → Apps → Manage your apps → Upload a custom app
5. **对于团队频道:** 在每个团队中重新安装应用以使新权限生效
6. **完全退出并重新启动 Teams**(不只是关闭窗口)以清除缓存的应用元数据
## 功能:仅 RSC vs Graph
### 仅使用 **Teams RSC**(已安装应用,无 Graph API 权限)
可用:
- 读取频道消息**文本**内容。
- 发送频道消息**文本**内容。
- 接收**个人(私信)**文件附件。
不可用:
- 频道/群组**图片或文件内容**(负载仅包含 HTML 占位符)。
- 下载存储在 SharePoint/OneDrive 中的附件。
- 读取消息历史(超出实时 webhook 事件范围)。
### 使用 **Teams RSC + Microsoft Graph Application 权限**
新增:
- 下载托管内容(粘贴到消息中的图片)。
- 下载存储在 SharePoint/OneDrive 中的文件附件。
- 通过 Graph 读取频道/聊天消息历史。
### RSC vs Graph API
| 功能 | RSC 权限 | Graph API |
| -------------- | ------------------ | --------------------------- |
| **实时消息** | 是(通过 webhook | 否(仅轮询) |
| **历史消息** | 否 | 是(可查询历史) |
| **设置复杂度** | 仅需应用清单 | 需要管理员同意 + token 流程 |
| **离线可用** | 否(必须运行中) | 是(可随时查询) |
**总结:** RSC 用于实时监听Graph API 用于历史访问。要补上离线期间错过的消息,你需要具有 `ChannelMessage.Read.All` 的 Graph API需要管理员同意
## 启用 Graph 的媒体 + 历史(频道所必需)
如果你需要**频道**中的图片/文件或想获取**消息历史**,必须启用 Microsoft Graph 权限并授予管理员同意。
1. 在 Entra IDAzure AD**应用注册**中,添加 Microsoft Graph **Application 权限**
- `ChannelMessage.Read.All`(频道附件 + 历史)
- `Chat.Read.All``ChatMessage.Read.All`(群聊)
2. 为租户**授予管理员同意**。
3. 递增 Teams 应用**清单版本**,重新上传,并在 **Teams 中重新安装应用**
4. **完全退出并重新启动 Teams** 以清除缓存的应用元数据。
## 已知限制
### Webhook 超时
Teams 通过 HTTP webhook 投递消息。如果处理时间过长(例如 LLM 响应缓慢),你可能会看到:
- Gateway网关超时
- Teams 重试消息(导致重复)
- 回复丢失
OpenClaw 通过快速返回并主动发送回复来处理此问题,但非常慢的响应仍可能导致问题。
### 格式
Teams markdown 比 Slack 或 Discord 更有限:
- 基本格式有效:**粗体**、_斜体_、`代码`、链接
- 复杂 markdown表格、嵌套列表可能无法正确渲染
- 支持 Adaptive Cards 用于投票和任意卡片发送(见下方)
## 配置
关键设置(共享渠道模式请参见 `/gateway/configuration`
- `channels.msteams.enabled`:启用/禁用渠道。
- `channels.msteams.appId`、`channels.msteams.appPassword`、`channels.msteams.tenantId`:机器人凭据。
- `channels.msteams.webhook.port`(默认 `3978`
- `channels.msteams.webhook.path`(默认 `/api/messages`
- `channels.msteams.dmPolicy``pairing | allowlist | open | disabled`默认pairing
- `channels.msteams.allowFrom`私信允许列表AAD 对象 ID、UPN 或显示名称)。当 Graph 访问可用时,向导在设置期间将名称解析为 ID。
- `channels.msteams.textChunkLimit`:出站文本分块大小。
- `channels.msteams.chunkMode``length`(默认)或 `newline`,在按长度分块之前按空行(段落边界)分割。
- `channels.msteams.mediaAllowHosts`:入站附件主机允许列表(默认为 Microsoft/Teams 域名)。
- `channels.msteams.requireMention`:在频道/群组中需要 @提及(默认 true
- `channels.msteams.replyStyle``thread | top-level`(参见[回复样式:线程 vs 帖子](#回复样式线程-vs-帖子))。
- `channels.msteams.teams.<teamId>.replyStyle`:按团队覆盖。
- `channels.msteams.teams.<teamId>.requireMention`:按团队覆盖。
- `channels.msteams.teams.<teamId>.tools`:按团队默认工具策略覆盖(`allow`/`deny`/`alsoAllow`),在频道覆盖缺失时使用。
- `channels.msteams.teams.<teamId>.toolsBySender`:按团队按发送者工具策略覆盖(支持 `"*"` 通配符)。
- `channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle`:按频道覆盖。
- `channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention`:按频道覆盖。
- `channels.msteams.teams.<teamId>.channels.<conversationId>.tools`:按频道工具策略覆盖(`allow`/`deny`/`alsoAllow`)。
- `channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender`:按频道按发送者工具策略覆盖(支持 `"*"` 通配符)。
- `channels.msteams.sharePointSiteId`:用于群聊/频道文件上传的 SharePoint 站点 ID参见[在群聊中发送文件](#在群聊中发送文件))。
## 路由与会话
- 会话键遵循标准智能体格式(参见 [/concepts/session](/concepts/session)
- 私信共享主会话(`agent:<agentId>:<mainKey>`)。
- 频道/群组消息使用会话 ID
- `agent:<agentId>:msteams:channel:<conversationId>`
- `agent:<agentId>:msteams:group:<conversationId>`
## 回复样式:线程 vs 帖子
Teams 最近在相同的底层数据模型上引入了两种频道 UI 样式:
| 样式 | 描述 | 推荐的 `replyStyle` |
| ----------------------- | ------------------------------ | ------------------- |
| **Posts**(经典) | 消息显示为卡片,下方有线程回复 | `thread`(默认) |
| **Threads**(类 Slack | 消息线性排列,更像 Slack | `top-level` |
**问题:** Teams API 不暴露频道使用哪种 UI 样式。如果你使用了错误的 `replyStyle`
- 在 Threads 样式的频道中使用 `thread` → 回复嵌套显示不自然
- 在 Posts 样式的频道中使用 `top-level` → 回复显示为独立的顶级帖子而非在线程中
**解决方案:** 根据频道的设置方式按频道配置 `replyStyle`
```json
{
"msteams": {
"replyStyle": "thread",
"teams": {
"19:abc...@thread.tacv2": {
"channels": {
"19:xyz...@thread.tacv2": {
"replyStyle": "top-level"
}
}
}
}
}
}
```
## 附件与图片
**当前限制:**
- **私信:** 图片和文件附件通过 Teams bot 文件 API 可用。
- **频道/群组:** 附件存储在 M365 存储SharePoint/OneDrive中。Webhook 负载仅包含 HTML 占位符,而非实际文件字节。**需要 Graph API 权限**才能下载频道附件。
没有 Graph 权限时包含图片的频道消息将仅作为纯文本接收机器人无法访问图片内容。默认情况下OpenClaw 仅从 Microsoft/Teams 主机名下载媒体。通过 `channels.msteams.mediaAllowHosts` 覆盖(使用 `["*"]` 允许任何主机)。
## 在群聊中发送文件
机器人可以使用 FileConsentCard 流程在私信中发送文件(内置)。然而,**在群聊/频道中发送文件**需要额外设置:
| 场景 | 文件发送方式 | 所需设置 |
| -------------------- | --------------------------------------- | ------------------------------------ |
| **私信** | FileConsentCard → 用户接受 → 机器人上传 | 开箱即用 |
| **群聊/频道** | 上传到 SharePoint → 分享链接 | 需要 `sharePointSiteId` + Graph 权限 |
| **图片(任何场景)** | Base64 编码内联 | 开箱即用 |
### 为什么群聊需要 SharePoint
机器人没有个人 OneDrive 驱动器(`/me/drive` Graph API 端点对应用程序标识不可用)。要在群聊/频道中发送文件,机器人上传到 **SharePoint 站点**并创建共享链接。
### 设置
1. 在 Entra IDAzure AD→ 应用注册中**添加 Graph API 权限**
- `Sites.ReadWrite.All`Application- 上传文件到 SharePoint
- `Chat.Read.All`Application- 可选,启用按用户共享链接
2. 为租户**授予管理员同意**。
3. **获取你的 SharePoint 站点 ID**
```bash
# 通过 Graph Explorer 或使用有效 token 的 curl
curl -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}"
# 示例:对于 "contoso.sharepoint.com/sites/BotFiles" 的站点
curl -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles"
# 响应包含:"id": "contoso.sharepoint.com,guid1,guid2"
```
4. **配置 OpenClaw**
```json5
{
channels: {
msteams: {
// ... 其他配置 ...
sharePointSiteId: "contoso.sharepoint.com,guid1,guid2",
},
},
}
```
### 共享行为
| 权限 | 共享行为 |
| --------------------------------------- | ------------------------------------------ |
| 仅 `Sites.ReadWrite.All` | 组织范围共享链接(组织中的任何人都可访问) |
| `Sites.ReadWrite.All` + `Chat.Read.All` | 按用户共享链接(仅聊天成员可访问) |
按用户共享更安全,因为只有聊天参与者可以访问文件。如果缺少 `Chat.Read.All` 权限,机器人回退到组织范围共享。
### 回退行为
| 场景 | 结果 |
| --------------------------------------- | ------------------------------------------ |
| 群聊 + 文件 + 已配置 `sharePointSiteId` | 上传到 SharePoint发送共享链接 |
| 群聊 + 文件 + 未配置 `sharePointSiteId` | 尝试 OneDrive 上传(可能失败),仅发送文本 |
| 个人聊天 + 文件 | FileConsentCard 流程(无需 SharePoint |
| 任何场景 + 图片 | Base64 编码内联(无需 SharePoint |
### 文件存储位置
上传的文件存储在已配置 SharePoint 站点默认文档库中的 `/OpenClawShared/` 文件夹。
## 投票Adaptive Cards
OpenClaw 通过 Adaptive Cards 发送 Teams 投票(没有原生 Teams 投票 API
- CLI`openclaw message poll --channel msteams --target conversation:<id> ...`
- 投票由 Gateway网关记录在 `~/.openclaw/msteams-polls.json` 中。
- Gateway网关必须保持在线以记录投票。
- 投票尚不会自动发布结果摘要(如需要请查看存储文件)。
## Adaptive Cards任意
使用 `message` 工具或 CLI 向 Teams 用户或会话发送任意 Adaptive Card JSON。
`card` 参数接受 Adaptive Card JSON 对象。提供 `card` 时,消息文本是可选的。
**智能体工具:**
```json
{
"action": "send",
"channel": "msteams",
"target": "user:<id>",
"card": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [{ "type": "TextBlock", "text": "Hello!" }]
}
}
```
**CLI**
```bash
openclaw message send --channel msteams \
--target "conversation:19:abc...@thread.tacv2" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}'
```
卡片 schema 和示例请参见 [Adaptive Cards 文档](https://adaptivecards.io/)。目标格式详情请参见下方[目标格式](#目标格式)。
## 目标格式
Microsoft Teams 目标使用前缀区分用户和会话:
| 目标类型 | 格式 | 示例 |
| ----------------- | -------------------------------- | ------------------------------------------------- |
| 用户(按 ID | `user:<aad-object-id>` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` |
| 用户(按名称) | `user:<display-name>` | `user:John Smith`(需要 Graph API |
| 群组/频道 | `conversation:<conversation-id>` | `conversation:19:abc123...@thread.tacv2` |
| 群组/频道(原始) | `<conversation-id>` | `19:abc123...@thread.tacv2`(如果包含 `@thread` |
**CLI 示例:**
```bash
# 按 ID 发送给用户
openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
# 按显示名称发送给用户(触发 Graph API 查找)
openclaw message send --channel msteams --target "user:John Smith" --message "Hello"
# 发送到群聊或频道
openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --message "Hello"
# 向会话发送 Adaptive Card
openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}'
```
**智能体工具示例:**
```json
{
"action": "send",
"channel": "msteams",
"target": "user:John Smith",
"message": "Hello!"
}
```
```json
{
"action": "send",
"channel": "msteams",
"target": "conversation:19:abc...@thread.tacv2",
"card": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [{ "type": "TextBlock", "text": "Hello" }]
}
}
```
注意:不带 `user:` 前缀时,名称默认解析为群组/团队。通过显示名称定位人员时请始终使用 `user:`
## 主动消息
- 主动消息仅在用户**已交互后**才可能,因为我们在那个时候存储会话引用。
- `dmPolicy` 和允许列表门控请参见 `/gateway/configuration`
## 团队和频道 ID常见陷阱
Teams URL 中的 `groupId` 查询参数**不是**用于配置的团队 ID。请从 URL 路径中提取 ID
**团队 URL**
```
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
└────────────────────────────┘
团队 IDURL 解码此部分)
```
**频道 URL**
```
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
└─────────────────────────┘
频道 IDURL 解码此部分)
```
**用于配置:**
- 团队 ID = `/team/` 后的路径段URL 解码后,例如 `19:Bk4j...@thread.tacv2`
- 频道 ID = `/channel/` 后的路径段URL 解码后)
- **忽略** `groupId` 查询参数
## 私有频道
机器人在私有频道中的支持有限:
| 功能 | 标准频道 | 私有频道 |
| ------------------- | -------- | ---------------- |
| 机器人安装 | 是 | 有限 |
| 实时消息webhook | 是 | 可能不可用 |
| RSC 权限 | 是 | 行为可能不同 |
| @提及 | 是 | 如果机器人可访问 |
| Graph API 历史 | 是 | 是(需要权限) |
**私有频道不可用时的变通方案:**
1. 使用标准频道进行机器人交互
2. 使用私信 - 用户始终可以直接给机器人发消息
3. 使用 Graph API 进行历史访问(需要 `ChannelMessage.Read.All`
## 故障排除
### 常见问题
- **频道中图片不显示:** Graph 权限或管理员同意缺失。重新安装 Teams 应用并完全退出/重新打开 Teams。
- **频道中没有响应:** 默认需要提及;设置 `channels.msteams.requireMention=false` 或按团队/频道配置。
- **版本不匹配Teams 仍显示旧清单):** 移除并重新添加应用,完全退出 Teams 以刷新。
- **Webhook 返回 401 Unauthorized** 在没有 Azure JWT 的情况下手动测试时这是预期的 - 表示端点可达但认证失败。使用 Azure Web Chat 进行正确测试。
### 清单上传错误
- **"Icon file cannot be empty"** 清单引用了 0 字节的图标文件。创建有效的 PNG 图标(`outline.png` 32x32`color.png` 192x192
- **"webApplicationInfo.Id already in use"** 应用仍安装在其他团队/聊天中。先找到并卸载它,或等待 5-10 分钟传播。
- **上传时显示"Something went wrong"** 改为通过 https://admin.teams.microsoft.com 上传,打开浏览器 DevToolsF12→ Network 标签页,检查响应体中的实际错误。
- **旁加载失败:** 尝试"Upload an app to your org's app catalog"而非"Upload a custom app" - 这通常可以绕过旁加载限制。
### RSC 权限不生效
1. 验证 `webApplicationInfo.id` 与你的机器人 App ID 完全匹配
2. 重新上传应用并在团队/聊天中重新安装
3. 检查你的组织管理员是否阻止了 RSC 权限
4. 确认你使用了正确的范围:`ChannelMessage.Read.Group` 用于团队,`ChatMessage.Read.Chat` 用于群聊
## 参考
- [创建 Azure Bot](https://learn.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration) - Azure Bot 设置指南
- [Teams 开发者门户](https://dev.teams.microsoft.com/apps) - 创建/管理 Teams 应用
- [Teams 应用清单 schema](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema)
- [使用 RSC 接收频道消息](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-messages-with-rsc)
- [RSC 权限参考](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent)
- [Teams bot 文件处理](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4)(频道/群组需要 Graph
- [主动消息](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages)

View file

@ -0,0 +1,141 @@
---
read_when:
- 开发 Nextcloud Talk 渠道功能
summary: Nextcloud Talk 支持状态、功能和配置
title: Nextcloud Talk
x-i18n:
generated_at: "2026-02-01T19:26:32Z"
model: claude-opus-4-5
provider: pi
source_hash: 21b7b9756c4356a76dc0f14c10e44ed74a284cf3badf87e2df75eb88d8a90c31
source_path: channels/nextcloud-talk.md
workflow: 14
---
# Nextcloud Talk插件
状态通过插件支持webhook 机器人)。支持私信、房间、回应和 markdown 消息。
## 需要插件
Nextcloud Talk 作为插件发布,不包含在核心安装中。
通过 CLI 安装npm 注册表):
```bash
openclaw plugins install @openclaw/nextcloud-talk
```
本地检出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/nextcloud-talk
```
如果你在配置/新手引导期间选择了 Nextcloud Talk 并检测到 git 检出OpenClaw 会自动提供本地安装路径。
详情:[插件](/plugin)
## 快速设置(新手)
1. 安装 Nextcloud Talk 插件。
2. 在你的 Nextcloud 服务器上创建一个机器人:
```bash
./occ talk:bot:install "OpenClaw" "<shared-secret>" "<webhook-url>" --feature reaction
```
3. 在目标房间设置中启用该机器人。
4. 配置 OpenClaw
- 配置:`channels.nextcloud-talk.baseUrl` + `channels.nextcloud-talk.botSecret`
- 或环境变量:`NEXTCLOUD_TALK_BOT_SECRET`(仅默认账户)
5. 重启 Gateway网关或完成新手引导
最小配置:
```json5
{
channels: {
"nextcloud-talk": {
enabled: true,
baseUrl: "https://cloud.example.com",
botSecret: "shared-secret",
dmPolicy: "pairing",
},
},
}
```
## 注意事项
- 机器人无法主动发起私信。用户必须先给机器人发消息。
- Webhook URL 必须能被 Gateway网关访问如果在代理后面请设置 `webhookPublicUrl`
- 机器人 API 不支持媒体上传;媒体以 URL 形式发送。
- Webhook 负载不区分私信和房间;设置 `apiUser` + `apiPassword` 以启用房间类型查询(否则私信会被视为房间)。
## 访问控制(私信)
- 默认:`channels.nextcloud-talk.dmPolicy = "pairing"`。未知发送者会收到配对码。
- 通过以下方式批准:
- `openclaw pairing list nextcloud-talk`
- `openclaw pairing approve nextcloud-talk <CODE>`
- 公开私信:`channels.nextcloud-talk.dmPolicy="open"` 加上 `channels.nextcloud-talk.allowFrom=["*"]`
## 房间(群组)
- 默认:`channels.nextcloud-talk.groupPolicy = "allowlist"`(提及门控)。
- 使用 `channels.nextcloud-talk.rooms` 允许列表中的房间:
```json5
{
channels: {
"nextcloud-talk": {
rooms: {
"room-token": { requireMention: true },
},
},
},
}
```
- 要不允许任何房间,保持允许列表为空或设置 `channels.nextcloud-talk.groupPolicy="disabled"`
## 功能
| 功能 | 状态 |
| -------- | ------ |
| 私信 | 支持 |
| 房间 | 支持 |
| 线程 | 不支持 |
| 媒体 | 仅 URL |
| 回应 | 支持 |
| 原生命令 | 不支持 |
## 配置参考Nextcloud Talk
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.nextcloud-talk.enabled`:启用/禁用渠道启动。
- `channels.nextcloud-talk.baseUrl`Nextcloud 实例 URL。
- `channels.nextcloud-talk.botSecret`:机器人共享密钥。
- `channels.nextcloud-talk.botSecretFile`:密钥文件路径。
- `channels.nextcloud-talk.apiUser`:用于房间查询的 API 用户(私信检测)。
- `channels.nextcloud-talk.apiPassword`:用于房间查询的 API/应用密码。
- `channels.nextcloud-talk.apiPasswordFile`API 密码文件路径。
- `channels.nextcloud-talk.webhookPort`webhook 监听端口默认8788
- `channels.nextcloud-talk.webhookHost`webhook 主机默认0.0.0.0)。
- `channels.nextcloud-talk.webhookPath`webhook 路径(默认:/nextcloud-talk-webhook
- `channels.nextcloud-talk.webhookPublicUrl`:外部可达的 webhook URL。
- `channels.nextcloud-talk.dmPolicy``pairing | allowlist | open | disabled`。
- `channels.nextcloud-talk.allowFrom`:私信允许列表(用户 ID。`open` 需要 `"*"`
- `channels.nextcloud-talk.groupPolicy``allowlist | open | disabled`。
- `channels.nextcloud-talk.groupAllowFrom`:群组允许列表(用户 ID
- `channels.nextcloud-talk.rooms`:按房间设置和允许列表。
- `channels.nextcloud-talk.historyLimit`群组历史限制0 禁用)。
- `channels.nextcloud-talk.dmHistoryLimit`私信历史限制0 禁用)。
- `channels.nextcloud-talk.dms`按私信覆盖historyLimit
- `channels.nextcloud-talk.textChunkLimit`:出站文本分块大小(字符)。
- `channels.nextcloud-talk.chunkMode``length`(默认)或 `newline`,在按长度分块之前按空行(段落边界)分割。
- `channels.nextcloud-talk.blockStreaming`:禁用此渠道的分块流式传输。
- `channels.nextcloud-talk.blockStreamingCoalesce`:分块流式传输合并调优。
- `channels.nextcloud-talk.mediaMaxMb`入站媒体上限MB

View file

@ -0,0 +1,240 @@
---
read_when:
- 你想让 OpenClaw 通过 Nostr 接收私信
- 你正在设置去中心化消息
summary: 通过 NIP-04 加密消息的 Nostr 私信渠道
title: Nostr
x-i18n:
generated_at: "2026-02-01T19:26:55Z"
model: claude-opus-4-5
provider: pi
source_hash: 6b9fe4c74bf5e7c0f59bbaa129ec5270fd29a248551a8a9a7dde6cff8fb46111
source_path: channels/nostr.md
workflow: 14
---
# Nostr
**状态:** 可选插件(默认禁用)。
Nostr 是一个去中心化的社交网络协议。此渠道使 OpenClaw 能够通过 NIP-04 接收和回复加密私信(私信)。
## 安装(按需)
### 新手引导(推荐)
- 新手引导向导(`openclaw onboard`)和 `openclaw channels add` 会列出可选的渠道插件。
- 选择 Nostr 时会提示你按需安装插件。
安装默认行为:
- **开发渠道 + 可用 git 检出:** 使用本地插件路径。
- **稳定版/测试版:** 从 npm 下载。
你始终可以在提示中覆盖此选择。
### 手动安装
```bash
openclaw plugins install @openclaw/nostr
```
使用本地检出(开发工作流):
```bash
openclaw plugins install --link <path-to-openclaw>/extensions/nostr
```
安装或启用插件后请重启 Gateway网关。
## 快速设置
1. 生成 Nostr 密钥对(如需要):
```bash
# 使用 nak
nak key generate
```
2. 添加到配置:
```json
{
"channels": {
"nostr": {
"privateKey": "${NOSTR_PRIVATE_KEY}"
}
}
}
```
3. 导出密钥:
```bash
export NOSTR_PRIVATE_KEY="nsec1..."
```
4. 重启 Gateway网关。
## 配置参考
| 键 | 类型 | 默认值 | 描述 |
| ------------ | -------- | ------------------------------------------- | --------------------------- |
| `privateKey` | string | 必填 | `nsec` 或十六进制格式的私钥 |
| `relays` | string[] | `['wss://relay.damus.io', 'wss://nos.lol']` | 中继 URLWebSocket |
| `dmPolicy` | string | `pairing` | 私信访问策略 |
| `allowFrom` | string[] | `[]` | 允许的发送者公钥 |
| `enabled` | boolean | `true` | 启用/禁用渠道 |
| `name` | string | - | 显示名称 |
| `profile` | object | - | NIP-01 个人资料元数据 |
## 个人资料元数据
个人资料数据作为 NIP-01 `kind:0` 事件发布。你可以从控制 UIChannels -> Nostr -> Profile管理它或直接在配置中设置。
示例:
```json
{
"channels": {
"nostr": {
"privateKey": "${NOSTR_PRIVATE_KEY}",
"profile": {
"name": "openclaw",
"displayName": "OpenClaw",
"about": "Personal assistant DM bot",
"picture": "https://example.com/avatar.png",
"banner": "https://example.com/banner.png",
"website": "https://example.com",
"nip05": "openclaw@example.com",
"lud16": "openclaw@example.com"
}
}
}
}
```
注意事项:
- 个人资料 URL 必须使用 `https://`
- 从中继导入会合并字段并保留本地覆盖。
## 访问控制
### 私信策略
- **pairing**(默认):未知发送者会收到配对码。
- **allowlist**:只有 `allowFrom` 中的公钥可以发私信。
- **open**:公开入站私信(需要 `allowFrom: ["*"]`)。
- **disabled**:忽略入站私信。
### 允许列表示例
```json
{
"channels": {
"nostr": {
"privateKey": "${NOSTR_PRIVATE_KEY}",
"dmPolicy": "allowlist",
"allowFrom": ["npub1abc...", "npub1xyz..."]
}
}
}
```
## 密钥格式
接受的格式:
- **私钥:** `nsec...` 或 64 字符十六进制
- **公钥(`allowFrom`** `npub...` 或十六进制
## 中继
默认值:`relay.damus.io` 和 `nos.lol`
```json
{
"channels": {
"nostr": {
"privateKey": "${NOSTR_PRIVATE_KEY}",
"relays": ["wss://relay.damus.io", "wss://relay.primal.net", "wss://nostr.wine"]
}
}
}
```
建议:
- 使用 2-3 个中继以实现冗余。
- 避免使用过多中继(延迟、重复)。
- 付费中继可以提高可靠性。
- 本地中继适用于测试(`ws://localhost:7777`)。
## 协议支持
| NIP | 状态 | 描述 |
| ------ | ------ | ----------------------------- |
| NIP-01 | 支持 | 基本事件格式 + 个人资料元数据 |
| NIP-04 | 支持 | 加密私信(`kind:4` |
| NIP-17 | 计划中 | Gift-wrapped 私信 |
| NIP-44 | 计划中 | 版本化加密 |
## 测试
### 本地中继
```bash
# 启动 strfry
docker run -p 7777:7777 ghcr.io/hoytech/strfry
```
```json
{
"channels": {
"nostr": {
"privateKey": "${NOSTR_PRIVATE_KEY}",
"relays": ["ws://localhost:7777"]
}
}
}
```
### 手动测试
1. 从日志中记下机器人公钥npub
2. 打开一个 Nostr 客户端Damus、Amethyst 等)。
3. 私信机器人公钥。
4. 验证回复。
## 故障排除
### 无法收到消息
- 验证私钥是否有效。
- 确保中继 URL 可达并使用 `wss://`(本地使用 `ws://`)。
- 确认 `enabled` 未设为 `false`
- 检查 Gateway网关日志中的中继连接错误。
### 无法发送回复
- 检查中继是否接受写入。
- 验证出站连接。
- 注意中继速率限制。
### 重复回复
- 使用多个中继时属于预期行为。
- 消息按事件 ID 去重;只有第一次投递会触发回复。
## 安全
- 绝不提交私钥。
- 使用环境变量存储密钥。
- 生产机器人请考虑使用 `allowlist`
## 限制MVP
- 仅支持私信(无群聊)。
- 不支持媒体附件。
- 仅支持 NIP-04计划支持 NIP-17 gift-wrap

View file

@ -0,0 +1,209 @@
---
read_when:
- 设置 Signal 支持
- 调试 Signal 收发
summary: 通过 signal-cliJSON-RPC + SSE实现 Signal 支持、设置和号码模型
title: Signal
x-i18n:
generated_at: "2026-02-01T19:27:25Z"
model: claude-opus-4-5
provider: pi
source_hash: ca4de8b3685017f54a959e3e2699357ab40b3e4e68574bd7fb5739e4679e7d8a
source_path: channels/signal.md
workflow: 14
---
# Signalsignal-cli
状态:外部 CLI 集成。Gateway网关通过 HTTP JSON-RPC + SSE 与 `signal-cli` 通信。
## 快速设置(新手)
1. 为机器人使用一个**单独的 Signal 号码**(推荐)。
2. 安装 `signal-cli`(需要 Java
3. 链接机器人设备并启动守护进程:
- `signal-cli link -n "OpenClaw"`
4. 配置 OpenClaw 并启动 Gateway网关。
最小配置:
```json5
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
```
## 它是什么
- 通过 `signal-cli` 的 Signal 渠道(非嵌入式 libsignal
- 确定性路由:回复始终发回 Signal。
- 私信共享智能体的主会话;群组是隔离的(`agent:<agentId>:signal:group:<groupId>`)。
## 配置写入
默认情况下Signal 允许通过 `/config set|unset` 触发的配置更新写入(需要 `commands.config: true`)。
通过以下方式禁用:
```json5
{
channels: { signal: { configWrites: false } },
}
```
## 号码模型(重要)
- Gateway网关连接到一个 **Signal 设备**`signal-cli` 账户)。
- 如果你在**个人 Signal 账户**上运行机器人,它会忽略你自己的消息(循环保护)。
- 要实现"我给机器人发消息它回复我",请使用一个**单独的机器人号码**。
## 设置(快速路径)
1. 安装 `signal-cli`(需要 Java
2. 链接机器人账户:
- `signal-cli link -n "OpenClaw"` 然后在 Signal 中扫描二维码。
3. 配置 Signal 并启动 Gateway网关。
示例:
```json5
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
```
多账户支持:使用 `channels.signal.accounts`,每个账户配置独立选项和可选的 `name`。共享模式请参阅 [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts)。
## 外部守护进程模式httpUrl
如果你想自行管理 `signal-cli`JVM 冷启动慢、容器初始化或共享 CPU可以单独运行守护进程并将 OpenClaw 指向它:
```json5
{
channels: {
signal: {
httpUrl: "http://127.0.0.1:8080",
autoStart: false,
},
},
}
```
这会跳过 OpenClaw 内部的自动启动和启动等待。当自动启动较慢时,请设置 `channels.signal.startupTimeoutMs`
## 访问控制(私信 + 群组)
私信:
- 默认:`channels.signal.dmPolicy = "pairing"`。
- 未知发送者会收到配对码;在批准之前消息会被忽略(配对码 1 小时后过期)。
- 通过以下方式批准:
- `openclaw pairing list signal`
- `openclaw pairing approve signal <CODE>`
- 配对是 Signal 私信的默认令牌交换方式。详情:[配对](/start/pairing)
- 仅 UUID 的发送者(来自 `sourceUuid`)以 `uuid:<id>` 形式存储在 `channels.signal.allowFrom` 中。
群组:
- `channels.signal.groupPolicy = open | allowlist | disabled`
- 当设置为 `allowlist` 时,`channels.signal.groupAllowFrom` 控制谁可以在群组中触发。
## 工作原理(行为)
- `signal-cli` 作为守护进程运行Gateway网关通过 SSE 读取事件。
- 入站消息被标准化为共享的渠道信封。
- 回复始终路由回同一个号码或群组。
## 媒体 + 限制
- 出站文本按 `channels.signal.textChunkLimit` 分块(默认 4000
- 可选的换行分块:设置 `channels.signal.chunkMode="newline"` 在按长度分块之前按空行(段落边界)分割。
- 支持附件(从 `signal-cli` 获取 base64
- 默认媒体上限:`channels.signal.mediaMaxMb`(默认 8
- 使用 `channels.signal.ignoreAttachments` 跳过媒体下载。
- 群组历史上下文使用 `channels.signal.historyLimit`(或 `channels.signal.accounts.*.historyLimit`),回退到 `messages.groupChat.historyLimit`。设置 `0` 可禁用(默认 50
## 输入指示 + 已读回执
- **输入指示**OpenClaw 通过 `signal-cli sendTyping` 发送输入信号,并在回复运行期间刷新。
- **已读回执**:当 `channels.signal.sendReadReceipts` 为 true 时OpenClaw 为允许的私信转发已读回执。
- signal-cli 不暴露群组的已读回执。
## 回应message 工具)
- 使用 `message action=react` 配合 `channel=signal`
- 目标:发送者 E.164 或 UUID使用配对输出中的 `uuid:<id>`;裸 UUID 也可以)。
- `messageId` 是你要回应的消息的 Signal 时间戳。
- 群组回应需要 `targetAuthor``targetAuthorUuid`
示例:
```
message action=react channel=signal target=uuid:123e4567-e89b-12d3-a456-426614174000 messageId=1737630212345 emoji=🔥
message action=react channel=signal target=+15551234567 messageId=1737630212345 emoji=🔥 remove=true
message action=react channel=signal target=signal:group:<groupId> targetAuthor=uuid:<sender-uuid> messageId=1737630212345 emoji=✅
```
配置:
- `channels.signal.actions.reactions`:启用/禁用回应操作(默认 true
- `channels.signal.reactionLevel``off | ack | minimal | extensive`。
- `off`/`ack` 禁用智能体回应message 工具 `react` 会报错)。
- `minimal`/`extensive` 启用智能体回应并设置引导级别。
- 按账户覆盖:`channels.signal.accounts.<id>.actions.reactions`、`channels.signal.accounts.<id>.reactionLevel`。
## 投递目标CLI/定时任务)
- 私信:`signal:+15551234567`(或纯 E.164)。
- UUID 私信:`uuid:<id>`(或裸 UUID
- 群组:`signal:group:<groupId>`。
- 用户名:`username:<name>`(如果你的 Signal 账户支持)。
## 配置参考Signal
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.signal.enabled`:启用/禁用渠道启动。
- `channels.signal.account`:机器人账户的 E.164。
- `channels.signal.cliPath``signal-cli` 的路径。
- `channels.signal.httpUrl`:完整守护进程 URL覆盖 host/port
- `channels.signal.httpHost`、`channels.signal.httpPort`:守护进程绑定(默认 127.0.0.1:8080
- `channels.signal.autoStart`:自动启动守护进程(未设置 `httpUrl` 时默认 true
- `channels.signal.startupTimeoutMs`:启动等待超时,单位毫秒(上限 120000
- `channels.signal.receiveMode``on-start | manual`。
- `channels.signal.ignoreAttachments`:跳过附件下载。
- `channels.signal.ignoreStories`:忽略来自守护进程的动态。
- `channels.signal.sendReadReceipts`:转发已读回执。
- `channels.signal.dmPolicy``pairing | allowlist | open | disabled`默认pairing
- `channels.signal.allowFrom`私信允许列表E.164 或 `uuid:<id>`)。`open` 需要 `"*"`。Signal 没有用户名;使用电话/UUID 标识。
- `channels.signal.groupPolicy``open | allowlist | disabled`默认allowlist
- `channels.signal.groupAllowFrom`:群组发送者允许列表。
- `channels.signal.historyLimit`包含为上下文的最大群组消息数0 禁用)。
- `channels.signal.dmHistoryLimit`:私信历史限制(用户回合数)。按用户覆盖:`channels.signal.dms["<phone_or_uuid>"].historyLimit`。
- `channels.signal.textChunkLimit`:出站分块大小(字符)。
- `channels.signal.chunkMode``length`(默认)或 `newline`,在按长度分块之前按空行(段落边界)分割。
- `channels.signal.mediaMaxMb`:入站/出站媒体上限MB
相关全局选项:
- `agents.list[].groupChat.mentionPatterns`Signal 不支持原生提及)。
- `messages.groupChat.mentionPatterns`(全局回退)。
- `messages.responsePrefix`

View file

@ -0,0 +1,530 @@
---
read_when: 设置 Slack 或调试 Slack Socket/HTTP 模式
summary: Slack 的 Socket 或 HTTP webhook 模式设置
title: Slack
x-i18n:
generated_at: "2026-02-01T19:29:15Z"
model: claude-opus-4-5
provider: pi
source_hash: 703b4b4333bebfef26b64710ba452bdfc3e7d2115048d4e552e8659425b3609b
source_path: channels/slack.md
workflow: 14
---
# Slack
## Socket 模式(默认)
### 快速设置(新手)
1. 创建一个 Slack 应用并启用 **Socket Mode**
2. 创建一个 **App Token**`xapp-...`)和 **Bot Token**`xoxb-...`)。
3. 为 OpenClaw 设置 token 并启动 Gateway网关。
最小配置:
```json5
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-...",
},
},
}
```
### 设置
1. 在 https://api.slack.com/apps 创建 Slack 应用(从头开始)。
2. **Socket Mode** → 开启。然后进入 **Basic Information****App-Level Tokens****Generate Token and Scopes**,使用范围 `connections:write`。复制 **App Token**`xapp-...`)。
3. **OAuth & Permissions** → 添加 bot token 范围(使用下方清单)。点击 **Install to Workspace**。复制 **Bot User OAuth Token**`xoxb-...`)。
4. 可选:**OAuth & Permissions** → 添加 **User Token Scopes**(参见下方只读列表)。重新安装应用并复制 **User OAuth Token**`xoxp-...`)。
5. **Event Subscriptions** → 启用事件并订阅:
- `message.*`(包括编辑/删除/线程广播)
- `app_mention`
- `reaction_added`、`reaction_removed`
- `member_joined_channel`、`member_left_channel`
- `channel_rename`
- `pin_added`、`pin_removed`
6. 邀请机器人加入你希望它读取的频道。
7. Slash Commands → 如果你使用 `channels.slack.slashCommand`,创建 `/openclaw`。如果你启用原生命令,为每个内置命令添加一个斜杠命令(名称与 `/help` 列表相同。Slack 的原生命令默认关闭,除非你设置 `channels.slack.commands.native: true`(全局 `commands.native``"auto"`Slack 下默认关闭)。
8. App Home → 启用 **Messages Tab** 以便用户可以给机器人发私信。
使用下方清单以保持范围和事件同步。
多账户支持:使用 `channels.slack.accounts`,每个账户配置独立 token 和可选的 `name`。共享模式请参阅 [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts)。
### OpenClaw 配置(最小)
通过环境变量设置 token推荐
- `SLACK_APP_TOKEN=xapp-...`
- `SLACK_BOT_TOKEN=xoxb-...`
或通过配置:
```json5
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-...",
},
},
}
```
### 用户 token可选
OpenClaw 可以使用 Slack 用户 token`xoxp-...`)进行读取操作(历史记录、置顶、回应、表情、成员信息)。默认保持只读:有用户 token 时读取操作优先使用它,写入仍使用 bot token除非你明确选择。即使设置了 `userTokenReadOnly: false`,当 bot token 可用时写入操作仍优先使用它。
用户 token 在配置文件中设置(不支持环境变量)。多账户时设置 `channels.slack.accounts.<id>.userToken`
同时使用 bot + app + user token 的示例:
```json5
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-...",
userToken: "xoxp-...",
},
},
}
```
显式设置 userTokenReadOnly 的示例(允许用户 token 写入):
```json5
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-...",
userToken: "xoxp-...",
userTokenReadOnly: false,
},
},
}
```
#### Token 使用
- 读取操作(历史记录、回应列表、置顶列表、表情列表、成员信息、搜索)在配置了用户 token 时优先使用,否则使用 bot token。
- 写入操作(发送/编辑/删除消息、添加/移除回应、置顶/取消置顶、文件上传)默认使用 bot token。如果 `userTokenReadOnly: false` 且没有 bot token 可用OpenClaw 回退到用户 token。
### 历史上下文
- `channels.slack.historyLimit`(或 `channels.slack.accounts.*.historyLimit`)控制多少条最近的频道/群组消息被包含在提示中。
- 回退到 `messages.groupChat.historyLimit`。设置 `0` 可禁用(默认 50
## HTTP 模式Events API
当你的 Gateway网关可通过 HTTPS 被 Slack 访问时使用 HTTP webhook 模式适用于服务器部署。HTTP 模式使用 Events API + Interactivity + Slash Commands共享请求 URL。
### 设置
1. 创建 Slack 应用并**禁用 Socket Mode**(如果你只使用 HTTP 则可选)。
2. **Basic Information** → 复制 **Signing Secret**
3. **OAuth & Permissions** → 安装应用并复制 **Bot User OAuth Token**`xoxb-...`)。
4. **Event Subscriptions** → 启用事件并将 **Request URL** 设置为你的 Gateway网关 webhook 路径(默认 `/slack/events`)。
5. **Interactivity & Shortcuts** → 启用并设置相同的 **Request URL**
6. **Slash Commands** → 为你的命令设置相同的 **Request URL**
示例请求 URL
`https://gateway-host/slack/events`
### OpenClaw 配置(最小)
```json5
{
channels: {
slack: {
enabled: true,
mode: "http",
botToken: "xoxb-...",
signingSecret: "your-signing-secret",
webhookPath: "/slack/events",
},
},
}
```
多账户 HTTP 模式:设置 `channels.slack.accounts.<id>.mode = "http"` 并为每个账户提供唯一的 `webhookPath`,以便每个 Slack 应用可以指向自己的 URL。
### 清单(可选)
使用此 Slack 应用清单可快速创建应用(根据需要调整名称/命令)。如果你计划配置用户 token请包含用户范围。
```json
{
"display_information": {
"name": "OpenClaw",
"description": "Slack connector for OpenClaw"
},
"features": {
"bot_user": {
"display_name": "OpenClaw",
"always_online": false
},
"app_home": {
"messages_tab_enabled": true,
"messages_tab_read_only_enabled": false
},
"slash_commands": [
{
"command": "/openclaw",
"description": "Send a message to OpenClaw",
"should_escape": false
}
]
},
"oauth_config": {
"scopes": {
"bot": [
"chat:write",
"channels:history",
"channels:read",
"groups:history",
"groups:read",
"groups:write",
"im:history",
"im:read",
"im:write",
"mpim:history",
"mpim:read",
"mpim:write",
"users:read",
"app_mentions:read",
"reactions:read",
"reactions:write",
"pins:read",
"pins:write",
"emoji:read",
"commands",
"files:read",
"files:write"
],
"user": [
"channels:history",
"channels:read",
"groups:history",
"groups:read",
"im:history",
"im:read",
"mpim:history",
"mpim:read",
"users:read",
"reactions:read",
"pins:read",
"emoji:read",
"search:read"
]
}
},
"settings": {
"socket_mode_enabled": true,
"event_subscriptions": {
"bot_events": [
"app_mention",
"message.channels",
"message.groups",
"message.im",
"message.mpim",
"reaction_added",
"reaction_removed",
"member_joined_channel",
"member_left_channel",
"channel_rename",
"pin_added",
"pin_removed"
]
}
}
}
```
如果你启用原生命令,为你想暴露的每个命令添加一个 `slash_commands` 条目(匹配 `/help` 列表)。通过 `channels.slack.commands.native` 覆盖。
## 范围(当前 vs 可选)
Slack 的 Conversations API 按类型设定范围你只需要你实际使用的会话类型channels、groups、im、mpim对应的范围。概览请参见 https://docs.slack.dev/apis/web-api/using-the-conversations-api/。
### Bot token 范围(必需)
- `chat:write`(通过 `chat.postMessage` 发送/更新/删除消息)
https://docs.slack.dev/reference/methods/chat.postMessage
- `im:write`(通过 `conversations.open` 打开用户私信)
https://docs.slack.dev/reference/methods/conversations.open
- `channels:history`、`groups:history`、`im:history`、`mpim:history`
https://docs.slack.dev/reference/methods/conversations.history
- `channels:read`、`groups:read`、`im:read`、`mpim:read`
https://docs.slack.dev/reference/methods/conversations.info
- `users:read`(用户查找)
https://docs.slack.dev/reference/methods/users.info
- `reactions:read`、`reactions:write``reactions.get` / `reactions.add`
https://docs.slack.dev/reference/methods/reactions.get
https://docs.slack.dev/reference/methods/reactions.add
- `pins:read`、`pins:write``pins.list` / `pins.add` / `pins.remove`
https://docs.slack.dev/reference/scopes/pins.read
https://docs.slack.dev/reference/scopes/pins.write
- `emoji:read``emoji.list`
https://docs.slack.dev/reference/scopes/emoji.read
- `files:write`(通过 `files.uploadV2` 上传)
https://docs.slack.dev/messaging/working-with-files/#upload
### 用户 token 范围(可选,默认只读)
如果你配置了 `channels.slack.userToken`,请在 **User Token Scopes** 下添加这些。
- `channels:history`、`groups:history`、`im:history`、`mpim:history`
- `channels:read`、`groups:read`、`im:read`、`mpim:read`
- `users:read`
- `reactions:read`
- `pins:read`
- `emoji:read`
- `search:read`
### 目前不需要(但未来可能)
- `mpim:write`(仅在我们添加群组私信打开/私信开始功能时需要,通过 `conversations.open`
- `groups:write`(仅在我们添加私有频道管理时需要:创建/重命名/邀请/归档)
- `chat:write.public`(仅在我们想向机器人未加入的频道发帖时需要)
https://docs.slack.dev/reference/scopes/chat.write.public
- `users:read.email`(仅在我们需要从 `users.info` 获取邮箱字段时需要)
https://docs.slack.dev/changelog/2017-04-narrowing-email-access
- `files:read`(仅在我们开始列出/读取文件元数据时需要)
## 配置
Slack 仅使用 Socket Mode无 HTTP webhook 服务器)。提供两个 token
```json
{
"slack": {
"enabled": true,
"botToken": "xoxb-...",
"appToken": "xapp-...",
"groupPolicy": "allowlist",
"dm": {
"enabled": true,
"policy": "pairing",
"allowFrom": ["U123", "U456", "*"],
"groupEnabled": false,
"groupChannels": ["G123"],
"replyToMode": "all"
},
"channels": {
"C123": { "allow": true, "requireMention": true },
"#general": {
"allow": true,
"requireMention": true,
"users": ["U123"],
"skills": ["search", "docs"],
"systemPrompt": "Keep answers short."
}
},
"reactionNotifications": "own",
"reactionAllowlist": ["U123"],
"replyToMode": "off",
"actions": {
"reactions": true,
"messages": true,
"pins": true,
"memberInfo": true,
"emojiList": true
},
"slashCommand": {
"enabled": true,
"name": "openclaw",
"sessionPrefix": "slack:slash",
"ephemeral": true
},
"textChunkLimit": 4000,
"mediaMaxMb": 20
}
}
```
Token 也可以通过环境变量提供:
- `SLACK_BOT_TOKEN`
- `SLACK_APP_TOKEN`
确认回应由 `messages.ackReaction` + `messages.ackReactionScope` 全局控制。使用 `messages.removeAckAfterReply` 在机器人回复后清除确认回应。
## 限制
- 出站文本按 `channels.slack.textChunkLimit` 分块(默认 4000
- 可选的换行分块:设置 `channels.slack.chunkMode="newline"` 在按长度分块之前按空行(段落边界)分割。
- 媒体上传上限由 `channels.slack.mediaMaxMb` 限制(默认 20
## 回复线程
默认情况下OpenClaw 在主频道中回复。使用 `channels.slack.replyToMode` 控制自动线程行为:
| 模式 | 行为 |
| ------- | ------------------------------------------------------------------------------------------------ |
| `off` | **默认。** 在主频道回复。仅在触发消息已在线程中时才在线程中回复。 |
| `first` | 第一条回复进入线程(在触发消息下方),后续回复进入主频道。适用于保持上下文可见同时避免线程杂乱。 |
| `all` | 所有回复都进入线程。保持对话集中但可能降低可见性。 |
该模式同时适用于自动回复和智能体工具调用(`slack sendMessage`)。
### 按聊天类型设置线程
你可以通过设置 `channels.slack.replyToModeByChatType` 为不同聊天类型配置不同的线程行为:
```json5
{
channels: {
slack: {
replyToMode: "off", // 频道默认
replyToModeByChatType: {
direct: "all", // 私信始终使用线程
group: "first", // 群组私信/MPIM 第一条回复使用线程
},
},
},
}
```
支持的聊天类型:
- `direct`一对一私信Slack `im`
- `group`:群组私信 / MPIMSlack `mpim`
- `channel`:标准频道(公共/私有)
优先级:
1. `replyToModeByChatType.<chatType>`
2. `replyToMode`
3. 提供商默认值(`off`
旧版 `channels.slack.dm.replyToMode` 在未设置聊天类型覆盖时仍作为 `direct` 的回退值。
示例:
仅私信使用线程:
```json5
{
channels: {
slack: {
replyToMode: "off",
replyToModeByChatType: { direct: "all" },
},
},
}
```
群组私信使用线程但频道保持在根级:
```json5
{
channels: {
slack: {
replyToMode: "off",
replyToModeByChatType: { group: "first" },
},
},
}
```
频道使用线程,私信保持在根级:
```json5
{
channels: {
slack: {
replyToMode: "first",
replyToModeByChatType: { direct: "off", group: "off" },
},
},
}
```
### 手动线程标签
对于精细控制,在智能体回复中使用以下标签:
- `[[reply_to_current]]` — 回复触发消息(开始/继续线程)。
- `[[reply_to:<id>]]` — 回复特定消息 ID。
## 会话 + 路由
- 私信共享 `main` 会话(与 WhatsApp/Telegram 类似)。
- 频道映射到 `agent:<agentId>:slack:channel:<channelId>` 会话。
- 斜杠命令使用 `agent:<agentId>:slack:slash:<userId>` 会话(前缀可通过 `channels.slack.slashCommand.sessionPrefix` 配置)。
- 如果 Slack 不提供 `channel_type`OpenClaw 从频道 ID 前缀(`D`、`C`、`G`)推断并默认为 `channel` 以保持会话键稳定。
- 原生命令注册使用 `commands.native`(全局默认 `"auto"` → Slack 关闭),可通过 `channels.slack.commands.native` 按工作区覆盖。文本命令需要独立的 `/...` 消息,可通过 `commands.text: false` 禁用。Slack 斜杠命令在 Slack 应用中管理,不会自动移除。使用 `commands.useAccessGroups: false` 可绕过命令的访问组检查。
- 完整命令列表 + 配置:[斜杠命令](/tools/slash-commands)
## 私信安全(配对)
- 默认:`channels.slack.dm.policy="pairing"` — 未知私信发送者会收到配对码1 小时后过期)。
- 通过 `openclaw pairing approve slack <code>` 批准。
- 要允许任何人:设置 `channels.slack.dm.policy="open"``channels.slack.dm.allowFrom=["*"]`
- `channels.slack.dm.allowFrom` 接受用户 ID、@用户名或邮箱(启动时当 token 允许时解析)。向导在设置期间当 token 允许时接受用户名并将其解析为 ID。
## 群组策略
- `channels.slack.groupPolicy` 控制频道处理方式(`open|disabled|allowlist`)。
- `allowlist` 需要频道列在 `channels.slack.channels` 中。
- 如果你只设置了 `SLACK_BOT_TOKEN`/`SLACK_APP_TOKEN` 且从未创建 `channels.slack` 部分,运行时默认将 `groupPolicy` 设为 `open`。添加 `channels.slack.groupPolicy`、`channels.defaults.groupPolicy` 或频道允许列表来锁定它。
- 配置向导接受 `#channel` 名称并在可能时将其解析为 ID公共 + 私有);如果存在多个匹配,优先选择活跃频道。
- 启动时OpenClaw 将允许列表中的频道/用户名称解析为 ID当 token 允许时)并记录映射;未解析的条目保持原样。
- 要**不允许任何频道**,设置 `channels.slack.groupPolicy: "disabled"`(或保持空的允许列表)。
频道选项(`channels.slack.channels.<id>` 或 `channels.slack.channels.<name>`
- `allow`:当 `groupPolicy="allowlist"` 时允许/拒绝频道。
- `requireMention`:频道的提及门控。
- `tools`:可选的按频道工具策略覆盖(`allow`/`deny`/`alsoAllow`)。
- `toolsBySender`:可选的频道内按发送者工具策略覆盖(键为发送者 ID/@用户名/邮箱;支持 `"*"` 通配符)。
- `allowBots`允许此频道中机器人发送的消息默认false
- `users`:可选的按频道用户允许列表。
- `skills`Skills 过滤器(省略 = 所有 Skills空 = 无)。
- `systemPrompt`:频道的额外系统提示(与主题/目的合并)。
- `enabled`:设置 `false` 可禁用频道。
## 投递目标
在定时任务/CLI 发送中使用:
- `user:<id>` 用于私信
- `channel:<id>` 用于频道
## 工具操作
Slack 工具操作可通过 `channels.slack.actions.*` 控制:
| 操作组 | 默认值 | 说明 |
| ---------- | ------ | ------------------- |
| reactions | 启用 | 添加回应 + 列出回应 |
| messages | 启用 | 读取/发送/编辑/删除 |
| pins | 启用 | 置顶/取消置顶/列出 |
| memberInfo | 启用 | 成员信息 |
| emojiList | 启用 | 自定义表情列表 |
## 安全注意事项
- 写入操作默认使用 bot token以便状态变更操作保持在应用机器人权限和身份范围内。
- 设置 `userTokenReadOnly: false` 允许在 bot token 不可用时使用用户 token 进行写入操作,这意味着操作以安装用户的访问权限运行。请将用户 token 视为高权限凭据,并严格设置操作门控和允许列表。
- 如果你启用用户 token 写入,请确保用户 token 包含你预期的写入范围(`chat:write`、`reactions:write`、`pins:write`、`files:write`),否则这些操作会失败。
## 注意事项
- 提及门控通过 `channels.slack.channels` 控制(将 `requireMention` 设为 `true``agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)也算作提及。
- 多智能体覆盖:在 `agents.list[].groupChat.mentionPatterns` 上设置每个智能体的模式。
- 回应通知遵循 `channels.slack.reactionNotifications`(使用 `reactionAllowlist` 配合 `allowlist` 模式)。
- 机器人发送的消息默认被忽略;通过 `channels.slack.allowBots``channels.slack.channels.<id>.allowBots` 启用。
- 警告:如果你允许回复其他机器人(`channels.slack.allowBots=true` 或 `channels.slack.channels.<id>.allowBots=true`),请使用 `requireMention`、`channels.slack.channels.<id>.users` 允许列表和/或在 `AGENTS.md``SOUL.md` 中设置明确的防护规则来防止机器人之间的回复循环。
- Slack 工具的回应移除语义请参见 [/tools/reactions](/tools/reactions)。
- 在权限允许且未超过大小限制时,附件会被下载到媒体存储。

View file

@ -0,0 +1,755 @@
---
read_when:
- 开发 Telegram 功能或 webhook 时
summary: Telegram 机器人支持状态、功能与配置
title: Telegram
x-i18n:
generated_at: "2026-02-01T19:54:11Z"
model: claude-opus-4-5
provider: pi
source_hash: 63198fce8c29a1020590d6a3ca142314b30c35d50317b878bf1fb1bfd8d54747
source_path: channels/telegram.md
workflow: 14
---
# Telegram (Bot API)
状态:通过 grammY 实现的机器人私聊 + 群组功能已可用于生产环境。默认使用长轮询webhook 可选。
## 快速设置(新手)
1. 通过 **@BotFather**[直达链接](https://t.me/BotFather))创建机器人。确认用户名确实是 `@BotFather`,然后复制令牌。
2. 设置令牌:
- 环境变量:`TELEGRAM_BOT_TOKEN=...`
- 或配置:`channels.telegram.botToken: "..."`。
- 如果两者都设置了,配置优先(环境变量回退仅适用于默认账户)。
3. 启动 Gateway网关。
4. 私聊访问默认为配对模式;首次联系时需批准配对码。
最小配置:
```json5
{
channels: {
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing",
},
},
}
```
## 简介
- 由 Gateway网关管理的 Telegram Bot API 渠道。
- 确定性路由:回复始终发回 Telegram模型不会选择渠道。
- 私聊共享智能体的主会话;群组保持隔离(`agent:<agentId>:telegram:group:<chatId>`)。
## 设置(快速路径)
### 1创建机器人令牌BotFather
1. 打开 Telegram**@BotFather**[直达链接](https://t.me/BotFather))对话。确认用户名确实是 `@BotFather`
2. 运行 `/newbot`,然后按提示操作(名称 + 以 `bot` 结尾的用户名)。
3. 复制令牌并安全保存。
可选的 BotFather 设置:
- `/setjoingroups` — 允许/禁止将机器人添加到群组。
- `/setprivacy` — 控制机器人是否能看到所有群组消息。
### 2配置令牌环境变量或配置
示例:
```json5
{
channels: {
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing",
groups: { "*": { requireMention: true } },
},
},
}
```
环境变量选项:`TELEGRAM_BOT_TOKEN=...`(适用于默认账户)。
如果环境变量和配置都设置了,配置优先。
多账户支持:使用 `channels.telegram.accounts`,为每个账户设置令牌和可选的 `name`。请参阅 [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts) 了解通用模式。
3. 启动 Gateway网关。当令牌被解析后配置优先环境变量回退Telegram 即启动。
4. 私聊访问默认为配对模式。机器人首次被联系时需批准配对码。
5. 对于群组:添加机器人,决定隐私/管理员行为(见下文),然后设置 `channels.telegram.groups` 来控制提及门控 + 白名单。
## 令牌 + 隐私 + 权限Telegram 端)
### 令牌创建BotFather
- `/newbot` 创建机器人并返回令牌(请保密)。
- 如果令牌泄露,通过 @BotFather 撤销/重新生成令牌并更新配置。
### 群组消息可见性(隐私模式)
Telegram 机器人默认启用**隐私模式**,这会限制它们能接收到的群组消息。
如果你的机器人必须看到*所有*群组消息,有两种选择:
- 使用 `/setprivacy` 禁用隐私模式,**或者**
- 将机器人设为群组**管理员**(管理员机器人可以接收所有消息)。
**注意:** 切换隐私模式后Telegram 要求将机器人从每个群组中移除并重新添加,
更改才能生效。
### 群组权限(管理员权限)
管理员状态在群组内设置Telegram 界面)。管理员机器人始终能接收所有
群组消息,因此如果需要完全可见性,请使用管理员身份。
## 工作原理(行为)
- 入站消息被规范化为共享渠道信封,包含回复上下文和媒体占位符。
- 群组回复默认需要提及(原生 @提及或 `agents.list[].groupChat.mentionPatterns` / `messages.groupChat.mentionPatterns`)。
- 多智能体覆盖:在 `agents.list[].groupChat.mentionPatterns` 上设置每个智能体的模式。
- 回复始终路由回同一个 Telegram 聊天。
- 长轮询使用 grammY runner按聊天排序总体并发受 `agents.defaults.maxConcurrent` 限制。
- Telegram Bot API 不支持已读回执;没有 `sendReadReceipts` 选项。
## 草稿流式传输
OpenClaw 可以使用 `sendMessageDraft` 在 Telegram 私聊中流式传输部分回复。
要求:
- 在 @BotFather 中为机器人启用话题模式(论坛话题模式)。
- 仅限私聊话题Telegram 在入站消息中包含 `message_thread_id`)。
- `channels.telegram.streamMode` 未设为 `"off"`(默认:`"partial"``"block"` 启用分块草稿更新)。
草稿流式传输仅适用于私聊Telegram 在群组或频道中不支持此功能。
## 格式化Telegram HTML
- 出站 Telegram 文本使用 `parse_mode: "HTML"`Telegram 支持的标签子集)。
- 类 Markdown 输入被渲染为 **Telegram 安全的 HTML**(粗体/斜体/删除线/代码/链接);块级元素被扁平化为带换行符/项目符号的文本。
- 来自模型的原始 HTML 会被转义,以避免 Telegram 解析错误。
- 如果 Telegram 拒绝 HTML 负载OpenClaw 会以纯文本重试同一条消息。
## 命令(原生 + 自定义)
OpenClaw 在启动时将原生命令(如 `/status`、`/reset`、`/model`)注册到 Telegram 的机器人菜单。
你可以通过配置向菜单添加自定义命令:
```json5
{
channels: {
telegram: {
customCommands: [
{ command: "backup", description: "Git backup" },
{ command: "generate", description: "Create an image" },
],
},
},
}
```
## 故障排除
- 日志中出现 `setMyCommands failed` 通常意味着到 `api.telegram.org` 的出站 HTTPS/DNS 被阻止。
- 如果看到 `sendMessage``sendChatAction` 失败,请检查 IPv6 路由和 DNS。
更多帮助:[渠道故障排除](/channels/troubleshooting)。
注意:
- 自定义命令**仅为菜单条目**;除非你在其他地方处理它们,否则 OpenClaw 不会实现它们。
- 命令名称会被规范化(去除前导 `/`,转为小写),且必须匹配 `a-z`、`0-9`、`_`132 个字符)。
- 自定义命令**不能覆盖原生命令**。冲突会被忽略并记录到日志。
- 如果 `commands.native` 被禁用,则只注册自定义命令(如果没有自定义命令则清空)。
## 限制
- 出站文本按 `channels.telegram.textChunkLimit` 分块(默认 4000
- 可选的换行分块:设置 `channels.telegram.chunkMode="newline"` 以在空行(段落边界)处拆分,然后再按长度分块。
- 媒体下载/上传受 `channels.telegram.mediaMaxMb` 限制(默认 5
- Telegram Bot API 请求在 `channels.telegram.timeoutSeconds` 后超时(通过 grammY 默认 500。设置更低的值以避免长时间挂起。
- 群组历史上下文使用 `channels.telegram.historyLimit`(或 `channels.telegram.accounts.*.historyLimit`),回退到 `messages.groupChat.historyLimit`。设为 `0` 以禁用(默认 50
- 私聊历史可通过 `channels.telegram.dmHistoryLimit`(用户轮次)限制。按用户覆盖:`channels.telegram.dms["<user_id>"].historyLimit`。
## 群组激活模式
默认情况下,机器人在群组中只响应提及(`@botname` 或 `agents.list[].groupChat.mentionPatterns` 中的模式)。要更改此行为:
### 通过配置(推荐)
```json5
{
channels: {
telegram: {
groups: {
"-1001234567890": { requireMention: false }, // 在此群组中始终回复
},
},
},
}
```
**重要:** 设置 `channels.telegram.groups` 会创建一个**白名单** - 只有列出的群组(或 `"*"`)会被接受。
论坛话题继承其父群组配置allowFrom、requireMention、skills、prompts除非你在 `channels.telegram.groups.<groupId>.topics.<topicId>` 下添加每个话题的覆盖。
允许所有群组且始终回复:
```json5
{
channels: {
telegram: {
groups: {
"*": { requireMention: false }, // 所有群组,始终回复
},
},
},
}
```
保持所有群组仅提及时回复(默认行为):
```json5
{
channels: {
telegram: {
groups: {
"*": { requireMention: true }, // 或完全省略 groups
},
},
},
}
```
### 通过命令(会话级别)
在群组中发送:
- `/activation always` - 回复所有消息
- `/activation mention` - 需要提及(默认)
**注意:** 命令仅更新会话状态。要在重启后保持行为,请使用配置。
### 获取群组聊天 ID
将群组中的任意消息转发给 Telegram 上的 `@userinfobot``@getidsbot`,即可看到聊天 ID负数`-1001234567890`)。
**提示:** 要获取你自己的用户 ID私聊机器人它会回复你的用户 ID配对消息或者在命令启用后使用 `/whoami`
**隐私提示:** `@userinfobot` 是第三方机器人。如果你更注重隐私,可以将机器人添加到群组,发送一条消息,然后使用 `openclaw logs --follow` 读取 `chat.id`,或使用 Bot API 的 `getUpdates`
## 配置写入
默认情况下Telegram 允许写入由渠道事件或 `/config set|unset` 触发的配置更新。
以下情况会发生配置写入:
- 群组升级为超级群组时Telegram 发出 `migrate_to_chat_id`(聊天 ID 变更。OpenClaw 可以自动迁移 `channels.telegram.groups`
- 你在 Telegram 聊天中运行 `/config set``/config unset`(需要 `commands.config: true`)。
禁用方式:
```json5
{
channels: { telegram: { configWrites: false } },
}
```
## 话题(论坛超级群组)
Telegram 论坛话题在每条消息中包含 `message_thread_id`。OpenClaw
- 将 `:topic:<threadId>` 追加到 Telegram 群组会话键,使每个话题相互隔离。
- 发送输入指示器和回复时携带 `message_thread_id`,确保回复留在话题内。
- 通用话题thread id `1`)比较特殊:消息发送时省略 `message_thread_id`Telegram 会拒绝),但输入指示器仍包含它。
- 在模板上下文中暴露 `MessageThreadId` + `IsForum`,用于路由/模板。
- 话题级配置可在 `channels.telegram.groups.<chatId>.topics.<threadId>` 下设置skills、白名单、自动回复、系统提示词、禁用
- 话题配置继承群组设置requireMention、白名单、skills、提示词、enabled除非按话题覆盖。
私聊在某些边缘情况下可能包含 `message_thread_id`。OpenClaw 保持私聊会话键不变,但在存在 thread id 时仍将其用于回复/草稿流式传输。
## 内联按钮
Telegram 支持带回调按钮的内联键盘。
```json5
{
channels: {
telegram: {
capabilities: {
inlineButtons: "allowlist",
},
},
},
}
```
按账户配置:
```json5
{
channels: {
telegram: {
accounts: {
main: {
capabilities: {
inlineButtons: "allowlist",
},
},
},
},
},
}
```
作用域:
- `off` — 禁用内联按钮
- `dm` — 仅私聊(群组目标被阻止)
- `group` — 仅群组(私聊目标被阻止)
- `all` — 私聊 + 群组
- `allowlist` — 私聊 + 群组,但仅限 `allowFrom`/`groupAllowFrom` 允许的发送者(与控制命令规则相同)
默认值:`allowlist`。
旧版:`capabilities: ["inlineButtons"]` = `inlineButtons: "all"`
### 发送按钮
使用消息工具的 `buttons` 参数:
```json5
{
action: "send",
channel: "telegram",
to: "123456789",
message: "Choose an option:",
buttons: [
[
{ text: "Yes", callback_data: "yes" },
{ text: "No", callback_data: "no" },
],
[{ text: "Cancel", callback_data: "cancel" }],
],
}
```
当用户点击按钮时,回调数据会以以下格式作为消息发送回智能体:
`callback_data: value`
### 配置选项
Telegram 功能可在两个层级配置(上面展示了对象形式;旧版字符串数组仍受支持):
- `channels.telegram.capabilities`:全局默认功能配置,应用于所有 Telegram 账户,除非被覆盖。
- `channels.telegram.accounts.<account>.capabilities`:按账户的功能配置,覆盖该账户的全局默认值。
当所有 Telegram 机器人/账户应具有相同行为时,使用全局设置。当不同机器人需要不同行为时,使用按账户配置(例如,一个账户只处理私聊,另一个允许在群组中使用)。
## 访问控制(私聊 + 群组)
### 私聊访问
- 默认:`channels.telegram.dmPolicy = "pairing"`。未知发送者会收到配对码;消息在批准前被忽略(配对码 1 小时后过期)。
- 批准方式:
- `openclaw pairing list telegram`
- `openclaw pairing approve telegram <CODE>`
- 配对是 Telegram 私聊使用的默认令牌交换方式。详情:[配对](/start/pairing)
- `channels.telegram.allowFrom` 接受数字用户 ID推荐`@username` 条目。这**不是**机器人用户名;请使用人类发送者的 ID。向导接受 `@username` 并在可能时将其解析为数字 ID。
#### 查找你的 Telegram 用户 ID
更安全的方式(无需第三方机器人):
1. 启动 Gateway网关并私聊你的机器人。
2. 运行 `openclaw logs --follow` 并查找 `from.id`
替代方式(官方 Bot API
1. 私聊你的机器人。
2. 使用你的机器人令牌获取更新,并读取 `message.from.id`
```bash
curl "https://api.telegram.org/bot<bot_token>/getUpdates"
```
第三方方式(隐私性较低):
- 私聊 `@userinfobot``@getidsbot` 并使用返回的用户 ID。
### 群组访问
两个独立的控制:
**1. 允许哪些群组**(通过 `channels.telegram.groups` 的群组白名单):
- 没有 `groups` 配置 = 允许所有群组
- 有 `groups` 配置 = 只允许列出的群组或 `"*"`
- 示例:`"groups": { "-1001234567890": {}, "*": {} }` 允许所有群组
**2. 允许哪些发送者**(通过 `channels.telegram.groupPolicy` 的发送者过滤):
- `"open"` = 允许的群组中所有发送者都可以发消息
- `"allowlist"` = 只有 `channels.telegram.groupAllowFrom` 中的发送者可以发消息
- `"disabled"` = 完全不接受群组消息
默认为 `groupPolicy: "allowlist"`(除非添加 `groupAllowFrom`,否则被阻止)。
大多数用户需要:`groupPolicy: "allowlist"` + `groupAllowFrom` + 在 `channels.telegram.groups` 中列出特定群组
## 长轮询 vs webhook
- 默认:长轮询(不需要公网 URL
- Webhook 模式:设置 `channels.telegram.webhookUrl``channels.telegram.webhookSecret`(可选 `channels.telegram.webhookPath`)。
- 本地监听器绑定到 `0.0.0.0:8787`,默认服务 `POST /telegram-webhook`
- 如果你的公网 URL 不同,请使用反向代理并将 `channels.telegram.webhookUrl` 指向公网端点。
## 回复线程
Telegram 通过标签支持可选的线程回复:
- `[[reply_to_current]]` -- 回复触发消息。
- `[[reply_to:<id>]]` -- 回复特定消息 ID。
通过 `channels.telegram.replyToMode` 控制:
- `first`(默认)、`all`、`off`。
## 音频消息(语音 vs 文件)
Telegram 区分**语音消息**(圆形气泡)和**音频文件**(元数据卡片)。
OpenClaw 默认使用音频文件以保持向后兼容。
要在智能体回复中强制使用语音消息气泡,在回复中的任意位置包含此标签:
- `[[audio_as_voice]]` — 以语音消息而非文件形式发送音频。
该标签会从发送的文本中移除。其他渠道会忽略此标签。
对于消息工具发送,设置 `asVoice: true` 并附带兼容语音的音频 `media` URL
(当有 media 时 `message` 为可选):
```json5
{
action: "send",
channel: "telegram",
to: "123456789",
media: "https://example.com/voice.ogg",
asVoice: true,
}
```
## 贴纸
OpenClaw 支持接收和发送 Telegram 贴纸,并带有智能缓存。
### 接收贴纸
当用户发送贴纸时OpenClaw 根据贴纸类型进行处理:
- **静态贴纸WEBP** 下载并通过视觉能力处理。贴纸在消息内容中显示为 `<media:sticker>` 占位符。
- **动态贴纸TGS** 跳过(不支持 Lottie 格式处理)。
- **视频贴纸WEBM** 跳过(不支持视频格式处理)。
接收贴纸时可用的模板上下文字段:
- `Sticker` — 包含以下属性的对象:
- `emoji` — 与贴纸关联的表情
- `setName` — 贴纸集名称
- `fileId` — Telegram 文件 ID可用于发回同一贴纸
- `fileUniqueId` — 用于缓存查找的稳定 ID
- `cachedDescription` — 可用时的缓存视觉描述
### 贴纸缓存
贴纸通过 AI 的视觉能力处理以生成描述。由于相同的贴纸经常被重复发送OpenClaw 会缓存这些描述以避免冗余的 API 调用。
**工作原理:**
1. **首次遇到:** 贴纸图像被发送给 AI 进行视觉分析。AI 生成描述(例如"一只卡通猫热情地挥手")。
2. **缓存存储:** 描述与贴纸的文件 ID、表情和集合名称一起保存。
3. **后续遇到:** 再次看到同一贴纸时,直接使用缓存的描述,不再将图像发送给 AI。
**缓存位置:** `~/.openclaw/telegram/sticker-cache.json`
**缓存条目格式:**
```json
{
"fileId": "CAACAgIAAxkBAAI...",
"fileUniqueId": "AgADBAADb6cxG2Y",
"emoji": "👋",
"setName": "CoolCats",
"description": "A cartoon cat waving enthusiastically",
"cachedAt": "2026-01-15T10:30:00.000Z"
}
```
**优势:**
- 通过避免对同一贴纸重复调用视觉能力来降低 API 成本
- 缓存贴纸的响应速度更快(无视觉处理延迟)
- 支持基于缓存描述的贴纸搜索功能
缓存在接收贴纸时自动填充,无需手动管理。
### 发送贴纸
智能体可以使用 `sticker``sticker-search` 动作发送和搜索贴纸。这些功能默认禁用,必须在配置中启用:
```json5
{
channels: {
telegram: {
actions: {
sticker: true,
},
},
},
}
```
**发送贴纸:**
```json5
{
action: "sticker",
channel: "telegram",
to: "123456789",
fileId: "CAACAgIAAxkBAAI...",
}
```
参数:
- `fileId`(必填)— 贴纸的 Telegram 文件 ID。可从接收贴纸时的 `Sticker.fileId` 获取,或从 `sticker-search` 结果获取。
- `replyTo`(可选)— 要回复的消息 ID。
- `threadId`(可选)— 论坛话题的消息线程 ID。
**搜索贴纸:**
智能体可以通过描述、表情或集合名称搜索缓存的贴纸:
```json5
{
action: "sticker-search",
channel: "telegram",
query: "cat waving",
limit: 5,
}
```
从缓存返回匹配的贴纸:
```json5
{
ok: true,
count: 2,
stickers: [
{
fileId: "CAACAgIAAxkBAAI...",
emoji: "👋",
description: "A cartoon cat waving enthusiastically",
setName: "CoolCats",
},
],
}
```
搜索使用跨描述文本、表情字符和集合名称的模糊匹配。
**带线程的示例:**
```json5
{
action: "sticker",
channel: "telegram",
to: "-1001234567890",
fileId: "CAACAgIAAxkBAAI...",
replyTo: 42,
threadId: 123,
}
```
## 流式传输(草稿)
Telegram 可以在智能体生成回复时流式传输**草稿气泡**。
OpenClaw 使用 Bot API 的 `sendMessageDraft`(非真实消息),然后将
最终回复作为普通消息发送。
要求Telegram Bot API 9.3+
- **启用话题的私聊**(机器人的论坛话题模式)。
- 入站消息必须包含 `message_thread_id`(私聊话题线程)。
- 群组/超级群组/频道中的流式传输会被忽略。
配置:
- `channels.telegram.streamMode: "off" | "partial" | "block"`(默认:`partial`
- `partial`:用最新的流式文本更新草稿气泡。
- `block`:以更大的块更新草稿气泡(分块)。
- `off`:禁用草稿流式传输。
- 可选(仅适用于 `streamMode: "block"`
- `channels.telegram.draftChunk: { minChars?, maxChars?, breakPreference? }`
- 默认值:`minChars: 200`、`maxChars: 800`、`breakPreference: "paragraph"`(受 `channels.telegram.textChunkLimit` 限制)。
注意:草稿流式传输与**分块流式传输**(渠道消息)不同。
分块流式传输默认关闭,如果你想要提前的 Telegram 消息而非草稿更新,需要设置 `channels.telegram.blockStreaming: true`
推理流式传输(仅 Telegram
- `/reasoning stream` 在回复生成时将推理过程流式传输到草稿气泡中,然后发送不包含推理过程的最终答案。
- 如果 `channels.telegram.streamMode``off`,推理流式传输将被禁用。
更多上下文:[流式传输 + 分块](/concepts/streaming)。
## 重试策略
出站 Telegram API 调用在遇到瞬态网络/429 错误时会以指数退避和抖动进行重试。通过 `channels.telegram.retry` 配置。参见[重试策略](/concepts/retry)。
## 智能体工具(消息 + 表情回应)
- 工具:`telegram``sendMessage` 动作(`to`、`content`,可选 `mediaUrl`、`replyToMessageId`、`messageThreadId`)。
- 工具:`telegram``react` 动作(`chatId`、`messageId`、`emoji`)。
- 工具:`telegram``deleteMessage` 动作(`chatId`、`messageId`)。
- 表情回应移除语义:参见 [/tools/reactions](/tools/reactions)。
- 工具门控:`channels.telegram.actions.reactions`、`channels.telegram.actions.sendMessage`、`channels.telegram.actions.deleteMessage`(默认:启用),以及 `channels.telegram.actions.sticker`(默认:禁用)。
## 表情回应通知
**表情回应的工作原理:**
Telegram 表情回应作为**独立的 `message_reaction` 事件**到达而非消息负载中的属性。当用户添加表情回应时OpenClaw
1. 从 Telegram API 接收 `message_reaction` 更新
2. 将其转换为**系统事件**,格式为:`"Telegram reaction added: {emoji} by {user} on msg {id}"`
3. 使用与常规消息**相同的会话键**将系统事件入队
4. 当该对话中的下一条消息到达时,系统事件被排出并添加到智能体上下文的前面
智能体将表情回应视为对话历史中的**系统通知**,而非消息元数据。
**配置:**
- `channels.telegram.reactionNotifications`:控制哪些表情回应触发通知
- `"off"` — 忽略所有表情回应
- `"own"` — 当用户对机器人消息做出表情回应时通知(尽力而为;内存中)(默认)
- `"all"` — 对所有表情回应进行通知
- `channels.telegram.reactionLevel`:控制智能体的表情回应能力
- `"off"` — 智能体不能对消息做表情回应
- `"ack"` — 机器人发送确认表情回应(处理时显示 👀)(默认)
- `"minimal"` — 智能体可以少量使用表情回应(指导原则:每 5-10 次交流 1 次)
- `"extensive"` — 智能体可以在适当时大量使用表情回应
**论坛群组:** 论坛群组中的表情回应包含 `message_thread_id`,使用如 `agent:main:telegram:group:{chatId}:topic:{threadId}` 的会话键。这确保同一话题中的表情回应和消息保持在一起。
**示例配置:**
```json5
{
channels: {
telegram: {
reactionNotifications: "all", // 查看所有表情回应
reactionLevel: "minimal", // 智能体可以少量使用表情回应
},
},
}
```
**要求:**
- Telegram 机器人必须在 `allowed_updates` 中显式请求 `message_reaction`(由 OpenClaw 自动配置)
- 对于 webhook 模式,表情回应包含在 webhook 的 `allowed_updates`
- 对于轮询模式,表情回应包含在 `getUpdates``allowed_updates`
## 投递目标CLI/定时任务)
- 使用聊天 ID`123456789`)或用户名(`@name`)作为目标。
- 示例:`openclaw message send --channel telegram --target 123456789 --message "hi"`。
## 故障排除
**机器人在群组中不响应非提及消息:**
- 如果你设置了 `channels.telegram.groups.*.requireMention=false`Telegram 的 Bot API **隐私模式**必须被禁用。
- BotFather`/setprivacy` → **Disable**(然后从群组中移除并重新添加机器人)
- `openclaw channels status` 在配置期望接收非提及群组消息时会显示警告。
- `openclaw channels status --probe` 可以额外检查显式数字群组 ID 的成员资格(无法审计通配符 `"*"` 规则)。
- 快速测试:`/activation always`(仅会话级别;持久化请使用配置)
**机器人完全看不到群组消息:**
- 如果设置了 `channels.telegram.groups`,群组必须被列出或使用 `"*"`
- 在 @BotFather 中检查隐私设置 → "Group Privacy" 应为 **OFF**
- 确认机器人确实是成员(而非只是没有读取权限的管理员)
- 检查 Gateway网关日志`openclaw logs --follow`(查找 "skipping group message"
**机器人响应提及但不响应 `/activation always`**
- `/activation` 命令更新会话状态但不会持久化到配置
- 要持久化行为,将群组添加到 `channels.telegram.groups` 并设置 `requireMention: false`
**`/status` 等命令不工作:**
- 确保你的 Telegram 用户 ID 已授权(通过配对或 `channels.telegram.allowFrom`
- 即使在 `groupPolicy: "open"` 的群组中,命令也需要授权
**长轮询在 Node 22+ 上立即中止(通常涉及代理/自定义 fetch**
- Node 22+ 对 `AbortSignal` 实例更严格;外部信号可能会立即中止 `fetch` 调用。
- 升级到规范化 abort 信号的 OpenClaw 版本,或在 Node 20 上运行 Gateway网关直到可以升级。
**机器人启动后静默停止响应(或日志中出现 `HttpError: Network request ... failed`**
- 某些主机优先将 `api.telegram.org` 解析为 IPv6。如果你的服务器没有可用的 IPv6 出口grammY 可能会卡在仅 IPv6 的请求上。
- 修复方法:启用 IPv6 出口**或者**强制 `api.telegram.org` 使用 IPv4 解析(例如,使用 IPv4 A 记录添加 `/etc/hosts` 条目,或在操作系统 DNS 栈中优先使用 IPv4然后重启 Gateway网关。
- 快速检查:`dig +short api.telegram.org A` 和 `dig +short api.telegram.org AAAA` 确认 DNS 返回的内容。
## 配置参考Telegram
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.telegram.enabled`:启用/禁用渠道启动。
- `channels.telegram.botToken`机器人令牌BotFather
- `channels.telegram.tokenFile`:从文件路径读取令牌。
- `channels.telegram.dmPolicy``pairing | allowlist | open | disabled`默认pairing
- `channels.telegram.allowFrom`私聊白名单ID/用户名)。`open` 需要 `"*"`
- `channels.telegram.groupPolicy``open | allowlist | disabled`默认allowlist
- `channels.telegram.groupAllowFrom`群组发送者白名单ID/用户名)。
- `channels.telegram.groups`:按群组的默认设置 + 白名单(使用 `"*"` 作为全局默认)。
- `channels.telegram.groups.<id>.requireMention`:提及门控默认值。
- `channels.telegram.groups.<id>.skills`Skills 过滤(省略 = 所有 Skills空 = 无 Skills
- `channels.telegram.groups.<id>.allowFrom`:按群组的发送者白名单覆盖。
- `channels.telegram.groups.<id>.systemPrompt`:群组的额外系统提示词。
- `channels.telegram.groups.<id>.enabled`:设为 `false` 时禁用该群组。
- `channels.telegram.groups.<id>.topics.<threadId>.*`:按话题覆盖(与群组字段相同)。
- `channels.telegram.groups.<id>.topics.<threadId>.requireMention`:按话题的提及门控覆盖。
- `channels.telegram.capabilities.inlineButtons``off | dm | group | all | allowlist`默认allowlist
- `channels.telegram.accounts.<account>.capabilities.inlineButtons`:按账户覆盖。
- `channels.telegram.replyToMode``off | first | all`(默认:`first`)。
- `channels.telegram.textChunkLimit`:出站分块大小(字符数)。
- `channels.telegram.chunkMode``length`(默认)或 `newline`,在空行(段落边界)处拆分后再按长度分块。
- `channels.telegram.linkPreview`切换出站消息的链接预览默认true
- `channels.telegram.streamMode``off | partial | block`(草稿流式传输)。
- `channels.telegram.mediaMaxMb`:入站/出站媒体上限MB
- `channels.telegram.retry`:出站 Telegram API 调用的重试策略attempts、minDelayMs、maxDelayMs、jitter
- `channels.telegram.network.autoSelectFamily`:覆盖 Node 的 autoSelectFamilytrue=启用false=禁用)。在 Node 22 上默认禁用以避免 Happy Eyeballs 超时。
- `channels.telegram.proxy`Bot API 调用的代理 URLSOCKS/HTTP
- `channels.telegram.webhookUrl`:启用 webhook 模式(需要 `channels.telegram.webhookSecret`)。
- `channels.telegram.webhookSecret`webhook 密钥(设置 webhookUrl 时必填)。
- `channels.telegram.webhookPath`:本地 webhook 路径(默认 `/telegram-webhook`)。
- `channels.telegram.actions.reactions`Telegram 工具表情回应门控。
- `channels.telegram.actions.sendMessage`Telegram 工具消息发送门控。
- `channels.telegram.actions.deleteMessage`Telegram 工具消息删除门控。
- `channels.telegram.actions.sticker`Telegram 贴纸动作门控 — 发送和搜索默认false
- `channels.telegram.reactionNotifications``off | own | all` — 控制哪些表情回应触发系统事件(未设置时默认:`own`)。
- `channels.telegram.reactionLevel``off | ack | minimal | extensive` — 控制智能体的表情回应能力(未设置时默认:`minimal`)。
相关全局选项:
- `agents.list[].groupChat.mentionPatterns`(提及门控模式)。
- `messages.groupChat.mentionPatterns`(全局回退)。
- `commands.native`(默认为 `"auto"` → Telegram/Discord 启用Slack 禁用)、`commands.text`、`commands.useAccessGroups`(命令行为)。通过 `channels.telegram.commands.native` 覆盖。
- `messages.responsePrefix`、`messages.ackReaction`、`messages.ackReactionScope`、`messages.removeAckAfterReply`。

138
docs/zh-CN/channels/tlon.md Normal file
View file

@ -0,0 +1,138 @@
---
read_when:
- 开发 Tlon/Urbit 渠道功能时
summary: Tlon/Urbit 支持状态、功能和配置
title: Tlon
x-i18n:
generated_at: "2026-02-01T19:58:15Z"
model: claude-opus-4-5
provider: pi
source_hash: 19d7ffe23e82239fd2a2e35913e0d52c809b2c2b939dd39184e6c27a539ed97d
source_path: channels/tlon.md
workflow: 14
---
# Tlon插件
Tlon 是一个基于 Urbit 构建的去中心化通讯工具。OpenClaw 连接到你的 Urbit ship可以
回复私信和群聊消息。群聊回复默认需要 @ 提及,并可通过白名单进一步限制。
状态:通过插件支持。支持私信、群组提及、线程回复和纯文本媒体回退
URL 附加到标题)。不支持反应、投票和原生媒体上传。
## 需要插件
Tlon 以插件形式提供,不包含在核心安装包中。
通过 CLI 安装npm 注册表):
```bash
openclaw plugins install @openclaw/tlon
```
本地签出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/tlon
```
详情:[插件](/plugin)
## 设置
1. 安装 Tlon 插件。
2. 获取你的 ship URL 和登录代码。
3. 配置 `channels.tlon`
4. 重启 Gateway网关。
5. 向机器人发送私信或在群组渠道中提及它。
最小配置(单账户):
```json5
{
channels: {
tlon: {
enabled: true,
ship: "~sampel-palnet",
url: "https://your-ship-host",
code: "lidlut-tabwed-pillex-ridrup",
},
},
}
```
## 群组渠道
默认启用自动发现。你也可以手动固定渠道:
```json5
{
channels: {
tlon: {
groupChannels: ["chat/~host-ship/general", "chat/~host-ship/support"],
},
},
}
```
禁用自动发现:
```json5
{
channels: {
tlon: {
autoDiscoverChannels: false,
},
},
}
```
## 访问控制
私信白名单(为空 = 允许所有):
```json5
{
channels: {
tlon: {
dmAllowlist: ["~zod", "~nec"],
},
},
}
```
群组授权(默认为受限模式):
```json5
{
channels: {
tlon: {
defaultAuthorizedShips: ["~zod"],
authorization: {
channelRules: {
"chat/~host-ship/general": {
mode: "restricted",
allowedShips: ["~zod", "~nec"],
},
"chat/~host-ship/announcements": {
mode: "open",
},
},
},
},
},
}
```
## 投递目标CLI/定时任务)
`openclaw message send` 或定时投递配合使用:
- 私信:`~sampel-palnet` 或 `dm/~sampel-palnet`
- 群组:`chat/~host-ship/channel` 或 `group:~host-ship/channel`
## 备注
- 群聊回复需要提及(例如 `~your-bot-ship`)才会响应。
- 线程回复如果收到的消息在线程中OpenClaw 会在线程内回复。
- 媒体:`sendMedia` 回退为文本 + URL不支持原生上传

View file

@ -0,0 +1,36 @@
---
read_when:
- 渠道已连接但消息无法流通
- 排查渠道配置错误(意图、权限、隐私模式)
summary: 渠道专属故障排除快捷指南Discord/Telegram/WhatsApp
title: 渠道故障排除
x-i18n:
generated_at: "2026-02-01T19:58:09Z"
model: claude-opus-4-5
provider: pi
source_hash: 6542ee86b3e50929caeaab127642d135dfbc0d8a44876ec2df0fff15bf57cd63
source_path: channels/troubleshooting.md
workflow: 14
---
# 渠道故障排除
首先运行:
```bash
openclaw doctor
openclaw channels status --probe
```
`channels status --probe` 会在检测到常见渠道配置错误时输出警告,并包含小型实时检查(凭据、部分权限/成员资格)。
## 渠道
- Discord[/channels/discord#troubleshooting](/channels/discord#troubleshooting)
- Telegram[/channels/telegram#troubleshooting](/channels/telegram#troubleshooting)
- WhatsApp[/channels/whatsapp#troubleshooting-quick](/channels/whatsapp#troubleshooting-quick)
## Telegram 快速修复
- 日志显示 `HttpError: Network request for 'sendMessage' failed``sendChatAction` → 检查 IPv6 DNS。如果 `api.telegram.org` 优先解析为 IPv6 而主机缺少 IPv6 出站连接,请强制使用 IPv4 或启用 IPv6。参见 [/channels/telegram#troubleshooting](/channels/telegram#troubleshooting)。
- 日志显示 `setMyCommands failed` → 检查到 `api.telegram.org` 的出站 HTTPS 和 DNS 可达性(常见于限制严格的 VPS 或代理环境)。

View file

@ -0,0 +1,384 @@
---
read_when:
- 为 OpenClaw 设置 Twitch 聊天集成
summary: Twitch 聊天机器人配置与设置
title: Twitch
x-i18n:
generated_at: "2026-02-01T19:58:38Z"
model: claude-opus-4-5
provider: pi
source_hash: aa7d60444e7f7e5dd7d02ce21527089058e024b8f427aeedf9e200a2818eb007
source_path: channels/twitch.md
workflow: 14
---
# Twitch插件
通过 IRC 连接支持 Twitch 聊天。OpenClaw 以 Twitch 用户(机器人账号)身份连接,在频道中接收和发送消息。
## 需要插件
Twitch 以插件形式提供,未包含在核心安装中。
通过 CLInpm 注册表)安装:
```bash
openclaw plugins install @openclaw/twitch
```
本地签出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/twitch
```
详情:[插件](/plugin)
## 快速设置(入门)
1. 为机器人创建一个专用 Twitch 账号(或使用现有账号)。
2. 生成凭证:[Twitch Token Generator](https://twitchtokengenerator.com/)
- 选择 **Bot Token**
- 确认已勾选 `chat:read``chat:write` 权限范围
- 复制 **Client ID** 和 **Access Token**
3. 查找你的 Twitch 用户 IDhttps://www.streamweasels.com/tools/convert-twitch-username-to-user-id/
4. 配置令牌:
- 环境变量:`OPENCLAW_TWITCH_ACCESS_TOKEN=...`(仅限默认账号)
- 或配置文件:`channels.twitch.accessToken`
- 如果两者都设置了,配置文件优先(环境变量回退仅适用于默认账号)。
5. 启动 Gateway网关。
**⚠️ 重要:** 添加访问控制(`allowFrom` 或 `allowedRoles`)以防止未授权用户触发机器人。`requireMention` 默认为 `true`
最小配置:
```json5
{
channels: {
twitch: {
enabled: true,
username: "openclaw", // 机器人的 Twitch 账号
accessToken: "oauth:abc123...", // OAuth Access Token或使用 OPENCLAW_TWITCH_ACCESS_TOKEN 环境变量)
clientId: "xyz789...", // 从 Token Generator 获取的 Client ID
channel: "vevisk", // 要加入的 Twitch 频道聊天室(必填)
allowFrom: ["123456789"], // (推荐)仅限你的 Twitch 用户 ID - 从 https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/ 获取
},
},
}
```
## 工作原理
- 由 Gateway网关拥有的 Twitch 渠道。
- 确定性路由:回复始终返回到 Twitch。
- 每个账号映射到一个隔离的会话键 `agent:<agentId>:twitch:<accountName>`
- `username` 是机器人的账号(用于认证),`channel` 是要加入的聊天室。
## 设置(详细)
### 生成凭证
使用 [Twitch Token Generator](https://twitchtokengenerator.com/)
- 选择 **Bot Token**
- 确认已勾选 `chat:read``chat:write` 权限范围
- 复制 **Client ID** 和 **Access Token**
无需手动注册应用。令牌在数小时后过期。
### 配置机器人
**环境变量(仅限默认账号):**
```bash
OPENCLAW_TWITCH_ACCESS_TOKEN=oauth:abc123...
```
**或配置文件:**
```json5
{
channels: {
twitch: {
enabled: true,
username: "openclaw",
accessToken: "oauth:abc123...",
clientId: "xyz789...",
channel: "vevisk",
},
},
}
```
如果环境变量和配置文件都设置了,配置文件优先。
### 访问控制(推荐)
```json5
{
channels: {
twitch: {
allowFrom: ["123456789"], // (推荐)仅限你的 Twitch 用户 ID
allowedRoles: ["moderator"], // 或按角色限制
},
},
}
```
**可用角色:** `"moderator"`、`"owner"`、`"vip"`、`"subscriber"`、`"all"`。
**为什么使用用户 ID** 用户名可以更改,存在冒充风险。用户 ID 是永久的。
查找你的 Twitch 用户 IDhttps://www.streamweasels.com/tools/convert-twitch-username-%20to-user-id/(将 Twitch 用户名转换为 ID
## 令牌刷新(可选)
从 [Twitch Token Generator](https://twitchtokengenerator.com/) 获取的令牌无法自动刷新——过期后需重新生成。
如需自动刷新令牌,请在 [Twitch Developer Console](https://dev.twitch.tv/console) 创建你自己的 Twitch 应用,并添加到配置中:
```json5
{
channels: {
twitch: {
clientSecret: "your_client_secret",
refreshToken: "your_refresh_token",
},
},
}
```
机器人会在令牌过期前自动刷新,并记录刷新事件。
## 多账号支持
使用 `channels.twitch.accounts` 配置每个账号的令牌。参见 [`gateway/configuration`](/gateway/configuration) 了解通用模式。
示例(一个机器人账号加入两个频道):
```json5
{
channels: {
twitch: {
accounts: {
channel1: {
username: "openclaw",
accessToken: "oauth:abc123...",
clientId: "xyz789...",
channel: "vevisk",
},
channel2: {
username: "openclaw",
accessToken: "oauth:def456...",
clientId: "uvw012...",
channel: "secondchannel",
},
},
},
},
}
```
**注意:** 每个账号需要自己的令牌(每个频道一个令牌)。
## 访问控制
### 基于角色的限制
```json5
{
channels: {
twitch: {
accounts: {
default: {
allowedRoles: ["moderator", "vip"],
},
},
},
},
}
```
### 按用户 ID 设置允许列表(最安全)
```json5
{
channels: {
twitch: {
accounts: {
default: {
allowFrom: ["123456789", "987654321"],
},
},
},
},
}
```
### 组合允许列表 + 角色
`allowFrom` 中的用户可绕过角色检查:
```json5
{
channels: {
twitch: {
accounts: {
default: {
allowFrom: ["123456789"],
allowedRoles: ["moderator"],
},
},
},
},
}
```
### 禁用 @提及要求
默认情况下,`requireMention` 为 `true`。要禁用并响应所有消息:
```json5
{
channels: {
twitch: {
accounts: {
default: {
requireMention: false,
},
},
},
},
}
```
## 故障排除
首先,运行诊断命令:
```bash
openclaw doctor
openclaw channels status --probe
```
### 机器人不响应消息
**检查访问控制:** 临时设置 `allowedRoles: ["all"]` 进行测试。
**检查机器人是否在频道中:** 机器人必须加入 `channel` 中指定的频道。
### 令牌问题
**"Failed to connect" 或认证错误:**
- 确认 `accessToken` 是 OAuth 访问令牌值(通常以 `oauth:` 前缀开头)
- 检查令牌是否具有 `chat:read``chat:write` 权限范围
- 如果使用令牌刷新,确认已设置 `clientSecret``refreshToken`
### 令牌刷新不工作
**检查日志中的刷新事件:**
```
Using env token source for mybot
Access token refreshed for user 123456 (expires in 14400s)
```
如果看到 "token refresh disabled (no refresh token)"
- 确保已提供 `clientSecret`
- 确保已提供 `refreshToken`
## 配置
**账号配置:**
- `username` - 机器人用户名
- `accessToken` - 具有 `chat:read``chat:write` 权限的 OAuth 访问令牌
- `clientId` - Twitch Client ID来自 Token Generator 或你的应用)
- `channel` - 要加入的频道(必填)
- `enabled` - 启用此账号(默认:`true`
- `clientSecret` - 可选:用于自动刷新令牌
- `refreshToken` - 可选:用于自动刷新令牌
- `expiresIn` - 令牌过期时间(秒)
- `obtainmentTimestamp` - 令牌获取时间戳
- `allowFrom` - 用户 ID 允许列表
- `allowedRoles` - 基于角色的访问控制(`"moderator" | "owner" | "vip" | "subscriber" | "all"`
- `requireMention` - 要求 @提及(默认:`true`
**提供商选项:**
- `channels.twitch.enabled` - 启用/禁用渠道启动
- `channels.twitch.username` - 机器人用户名(简化单账号配置)
- `channels.twitch.accessToken` - OAuth 访问令牌(简化单账号配置)
- `channels.twitch.clientId` - Twitch Client ID简化单账号配置
- `channels.twitch.channel` - 要加入的频道(简化单账号配置)
- `channels.twitch.accounts.<accountName>` - 多账号配置(上述所有账号字段)
完整示例:
```json5
{
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"],
},
},
},
},
}
```
## 工具操作
智能体可以调用 `twitch` 执行以下操作:
- `send` - 向频道发送消息
示例:
```json5
{
action: "twitch",
params: {
message: "Hello Twitch!",
to: "#mychannel",
},
}
```
## 安全与运维
- **将令牌视为密码** - 切勿将令牌提交到 git
- **使用自动令牌刷新** 用于长时间运行的机器人
- **使用用户 ID 允许列表** 而非用户名进行访问控制
- **监控日志** 关注令牌刷新事件和连接状态
- **最小化令牌权限范围** - 仅请求 `chat:read``chat:write`
- **如遇问题**:确认没有其他进程占用会话后,重启 Gateway网关
## 限制
- 每条消息最多 **500 个字符**(按词边界自动分块)
- 分块前会移除 Markdown 格式
- 无速率限制(使用 Twitch 内置的速率限制)

View file

@ -0,0 +1,410 @@
---
read_when:
- 处理 WhatsApp/网页渠道行为或收件箱路由时
summary: WhatsApp网页渠道集成登录、收件箱、回复、媒体和运维
title: WhatsApp
x-i18n:
generated_at: "2026-02-01T20:00:02Z"
model: claude-opus-4-5
provider: pi
source_hash: 44fd88f8e269284999e5a5a52b230edae6e6f978528dd298d6a5603d03c0c38d
source_path: channels/whatsapp.md
workflow: 14
---
# WhatsApp网页渠道
状态:仅支持通过 Baileys 的 WhatsApp Web。Gateway网关拥有会话。
## 快速设置(入门)
1. 如果可能,使用**单独的手机号码**(推荐)。
2. 在 `~/.openclaw/openclaw.json` 中配置 WhatsApp。
3. 运行 `openclaw channels login` 扫描二维码(已关联设备)。
4. 启动 Gateway网关。
最小配置:
```json5
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"],
},
},
}
```
## 目标
- 单个 Gateway网关进程中支持多个 WhatsApp 账号(多账号)。
- 确定性路由:回复返回到 WhatsApp无模型路由。
- 模型获得足够的上下文以理解引用回复。
## 配置写入
默认情况下WhatsApp 允许通过 `/config set|unset` 触发配置更新写入(需要 `commands.config: true`)。
禁用方式:
```json5
{
channels: { whatsapp: { configWrites: false } },
}
```
## 架构(职责划分)
- **Gateway网关** 拥有 Baileys socket 和收件箱循环。
- **CLI / macOS 应用** 与 Gateway网关通信不直接使用 Baileys。
- **活跃监听器** 是出站发送的必要条件;否则发送会快速失败。
## 获取手机号码(两种模式)
WhatsApp 需要真实的手机号码进行验证。VoIP 和虚拟号码通常会被屏蔽。在 WhatsApp 上运行 OpenClaw 有两种支持的方式:
### 专用号码(推荐)
为 OpenClaw 使用**单独的手机号码**。最佳用户体验,干净的路由,无自聊天问题。理想设置:**备用/旧 Android 手机 + eSIM**。保持 Wi-Fi 和充电连接,通过二维码关联。
**WhatsApp Business** 你可以在同一设备上使用不同号码的 WhatsApp Business。非常适合将个人 WhatsApp 分开 — 安装 WhatsApp Business 并在其中注册 OpenClaw 号码。
**示例配置(专用号码,单用户允许列表):**
```json5
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"],
},
},
}
```
**配对模式(可选):**
如果你想使用配对而非允许列表,将 `channels.whatsapp.dmPolicy` 设置为 `pairing`。未知发送者会收到配对码;通过以下命令批准:
`openclaw pairing approve whatsapp <code>`
### 个人号码(备选方案)
快速备选方案:在**你自己的号码**上运行 OpenClaw。给自己发消息WhatsApp "给自己发消息")进行测试,避免打扰联系人。在设置和实验期间,需要在主手机上读取验证码。**必须启用自聊天模式。**
当向导询问你的个人 WhatsApp 号码时,输入你将用来发消息的手机号(所有者/发送者),而不是助手号码。
**示例配置(个人号码,自聊天):**
```json
{
"whatsapp": {
"selfChatMode": true,
"dmPolicy": "allowlist",
"allowFrom": ["+15551234567"]
}
}
```
当设置了 `messages.responsePrefix` 时,自聊天回复默认使用 `[{identity.name}]`(否则为 `[openclaw]`)。
如果 `messages.responsePrefix` 未设置,则使用默认值。显式设置可自定义或禁用前缀(使用 `""` 来移除)。
### 号码获取技巧
- **本国 eSIM**,来自你所在国家的移动运营商(最可靠)
- 奥地利:[hot.at](https://www.hot.at)
- 英国:[giffgaff](https://www.giffgaff.com) — 免费 SIM 卡,无合约
- **预付费 SIM 卡** — 便宜,只需接收一条验证短信
**避免使用:** TextNow、Google Voice、大多数"免费短信"服务 — WhatsApp 会积极屏蔽这些号码。
**提示:** 该号码只需接收一条验证短信。之后WhatsApp Web 会话通过 `creds.json` 持久保存。
## 为什么不用 Twilio
- 早期 OpenClaw 版本支持 Twilio 的 WhatsApp Business 集成。
- WhatsApp Business 号码不适合个人助手。
- Meta 强制执行 24 小时回复窗口;如果你在过去 24 小时内没有回复,商业号码无法发起新消息。
- 高频或"频繁"使用会触发激进的封禁,因为商业账号不适合发送大量个人助手消息。
- 结果:投递不可靠且频繁被封禁,因此已移除支持。
## 登录 + 凭证
- 登录命令:`openclaw channels login`(通过已关联设备扫描二维码)。
- 多账号登录:`openclaw channels login --account <id>``<id>` = `accountId`)。
- 默认账号(省略 `--account` 时):如果存在则为 `default`,否则为第一个已配置的账号 ID排序后
- 凭证存储在 `~/.openclaw/credentials/whatsapp/<accountId>/creds.json`
- 备份副本位于 `creds.json.bak`(损坏时恢复)。
- 旧版兼容:早期安装将 Baileys 文件直接存储在 `~/.openclaw/credentials/`
- 注销:`openclaw channels logout`(或 `--account <id>`)删除 WhatsApp 认证状态(但保留共享的 `oauth.json`)。
- 已注销的 socket => 错误提示重新关联。
## 入站流程(私聊 + 群聊)
- WhatsApp 事件来自 `messages.upsert`Baileys
- 收件箱监听器在关闭时解除绑定,以避免在测试/重启中累积事件处理器。
- 状态/广播聊天被忽略。
- 私聊使用 E.164 格式;群聊使用群组 JID。
- **私聊策略**`channels.whatsapp.dmPolicy` 控制私聊访问(默认:`pairing`)。
- 配对:未知发送者会收到配对码(通过 `openclaw pairing approve whatsapp <code>` 批准;码在 1 小时后过期)。
- 开放:需要 `channels.whatsapp.allowFrom` 包含 `"*"`
- 你关联的 WhatsApp 号码被隐式信任,因此自消息跳过 `channels.whatsapp.dmPolicy``channels.whatsapp.allowFrom` 检查。
### 个人号码模式(备选方案)
如果你在**个人 WhatsApp 号码**上运行 OpenClaw启用 `channels.whatsapp.selfChatMode`(参见上方示例配置)。
行为:
- 出站私聊消息不会触发配对回复(防止骚扰联系人)。
- 入站未知发送者仍遵循 `channels.whatsapp.dmPolicy`
- 自聊天模式allowFrom 包含你的号码)避免自动已读回执并忽略提及 JID。
- 非自聊天私聊会发送已读回执。
## 已读回执
默认情况下Gateway网关会在接受入站 WhatsApp 消息后将其标记为已读(蓝色对勾)。
全局禁用:
```json5
{
channels: { whatsapp: { sendReadReceipts: false } },
}
```
按账号禁用:
```json5
{
channels: {
whatsapp: {
accounts: {
personal: { sendReadReceipts: false },
},
},
},
}
```
备注:
- 自聊天模式始终跳过已读回执。
## WhatsApp 常见问题:发送消息 + 配对
**关联 WhatsApp 后OpenClaw 会给随机联系人发消息吗?**
不会。默认私聊策略是**配对**,因此未知发送者只会收到配对码,其消息**不会被处理**。OpenClaw 只回复收到的聊天,或你显式触发的发送(智能体/CLI
**WhatsApp 上的配对是如何工作的?**
配对是针对未知发送者的私聊门控:
- 新发送者的首条私聊消息会返回一个短码(消息不会被处理)。
- 通过以下命令批准:`openclaw pairing approve whatsapp <code>`(用 `openclaw pairing list whatsapp` 列出)。
- 码在 1 小时后过期;每个渠道的待处理请求上限为 3 个。
**多人可以在同一个 WhatsApp 号码上使用不同的 OpenClaw 实例吗?**
可以,通过 `bindings` 将每个发送者路由到不同的智能体peer `kind: "dm"`,发送者 E.164 如 `+15551234567`)。回复仍然来自**同一个 WhatsApp 账号**,且私聊会折叠到每个智能体的主会话,因此请使用**每人一个智能体**。私聊访问控制(`dmPolicy`/`allowFrom`)在每个 WhatsApp 账号级别是全局的。参见[多智能体路由](/concepts/multi-agent)。
**为什么向导要询问我的手机号码?**
向导使用它来设置你的**允许列表/所有者**,以便允许你自己的私聊消息。它不用于自动发送。如果你在个人 WhatsApp 号码上运行,使用相同的号码并启用 `channels.whatsapp.selfChatMode`
## 消息标准化(模型看到的内容)
- `Body` 是当前消息正文及其信封。
- 引用回复上下文**始终附加**
```
[Replying to +1555 id:ABC123]
<quoted text or <media:...>>
[/Replying]
```
- 回复元数据也会设置:
- `ReplyToId` = stanzaId
- `ReplyToBody` = 引用正文或媒体占位符
- `ReplyToSender` = E.164(已知时)
- 纯媒体入站消息使用占位符:
- `<media:image|video|audio|document|sticker>`
## 群聊
- 群聊映射到 `agent:<agentId>:whatsapp:group:<jid>` 会话。
- 群聊策略:`channels.whatsapp.groupPolicy = open|disabled|allowlist`(默认 `allowlist`)。
- 激活模式:
- `mention`(默认):需要 @提及或正则匹配
- `always`:始终触发。
- `/activation mention|always` 仅限所有者且必须作为独立消息发送。
- 所有者 = `channels.whatsapp.allowFrom`(未设置时为自身 E.164)。
- **历史注入**(仅待处理):
- 最近*未处理*的消息(默认 50 条)插入在:
`[Chat messages since your last reply - for context]`(已在会话中的消息不会被重复注入)
- 当前消息位于:
`[Current message - respond to this]`
- 发送者后缀附加:`[from: Name (+E164)]`
- 群聊元数据缓存 5 分钟(主题 + 参与者)。
## 回复投递(线程)
- WhatsApp Web 发送标准消息(当前 Gateway网关中无引用回复线程
- 此渠道忽略回复标签。
## 确认反应(收到消息时自动反应)
WhatsApp 可以在收到消息时立即自动发送表情反应,在机器人生成回复之前。这为用户提供即时反馈,表明其消息已收到。
**配置:**
```json
{
"whatsapp": {
"ackReaction": {
"emoji": "👀",
"direct": true,
"group": "mentions"
}
}
}
```
**选项:**
- `emoji`(字符串):用于确认的表情(例如 "👀"、"✅"、"📨")。为空或省略 = 功能禁用。
- `direct`(布尔值,默认:`true`):在私聊/私信 中发送反应。
- `group`(字符串,默认:`"mentions"`):群聊行为:
- `"always"`:对所有群聊消息做出反应(即使没有 @提及
- `"mentions"`:仅在机器人被 @提及时做出反应
- `"never"`:从不在群聊中做出反应
**按账号覆盖:**
```json
{
"whatsapp": {
"accounts": {
"work": {
"ackReaction": {
"emoji": "✅",
"direct": false,
"group": "always"
}
}
}
}
}
```
**行为说明:**
- 反应在收到消息时**立即**发送,在输入指示器或机器人回复之前。
- 在 `requireMention: false`激活模式always的群组中`group: "mentions"` 会对所有消息做出反应(不仅仅是 @提及)。
- 即发即忘:反应失败会被记录但不会阻止机器人回复。
- 群聊反应会自动包含参与者 JID。
- WhatsApp 忽略 `messages.ackReaction`;请改用 `channels.whatsapp.ackReaction`
## 智能体工具(反应)
- 工具:`whatsapp`,使用 `react` 动作(`chatJid`、`messageId`、`emoji`,可选 `remove`)。
- 可选:`participant`(群聊发送者)、`fromMe`(对自己的消息做出反应)、`accountId`(多账号)。
- 反应移除语义:参见 [/tools/reactions](/tools/reactions)。
- 工具门控:`channels.whatsapp.actions.reactions`(默认:启用)。
## 限制
- 出站文本按 `channels.whatsapp.textChunkLimit` 分块(默认 4000
- 可选换行分块:设置 `channels.whatsapp.chunkMode="newline"` 在空行(段落边界)处分割,再进行长度分块。
- 入站媒体保存受 `channels.whatsapp.mediaMaxMb` 限制(默认 50 MB
- 出站媒体项受 `agents.defaults.mediaMaxMb` 限制(默认 5 MB
## 出站发送(文本 + 媒体)
- 使用活跃的网页监听器;如果 Gateway网关未运行则报错。
- 文本分块:每条消息最大 4k可通过 `channels.whatsapp.textChunkLimit` 配置,可选 `channels.whatsapp.chunkMode`)。
- 媒体:
- 支持图片/视频/音频/文档。
- 音频以 PTT 发送;`audio/ogg` => `audio/ogg; codecs=opus`
- 仅第一个媒体项带字幕。
- 媒体获取支持 HTTP(S) 和本地路径。
- 动态 GIFWhatsApp 期望带 `gifPlayback: true` 的 MP4 以实现内联循环播放。
- CLI`openclaw message send --media <mp4> --gif-playback`
- Gateway网关`send` 参数包含 `gifPlayback: true`
## 语音消息PTT 音频)
WhatsApp 以**语音消息**PTT 气泡)发送音频。
- 最佳效果OGG/Opus。OpenClaw 将 `audio/ogg` 重写为 `audio/ogg; codecs=opus`
- WhatsApp 忽略 `[[audio_as_voice]]`(音频已作为语音消息发送)。
## 媒体限制 + 优化
- 默认出站上限5 MB每个媒体项
- 覆盖:`agents.defaults.mediaMaxMb`。
- 图片会自动优化为 JPEG 以控制在上限内(缩放 + 质量扫描)。
- 超大媒体 => 错误;媒体回复回退为文本警告。
## 心跳
- **Gateway网关心跳** 记录连接健康状态(`web.heartbeatSeconds`,默认 60 秒)。
- **智能体心跳** 可按智能体配置(`agents.list[].heartbeat`)或通过
`agents.defaults.heartbeat` 全局配置(未设置每智能体条目时的回退)。
- 使用配置的心跳提示(默认:`Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.`+ `HEARTBEAT_OK` 跳过行为。
- 投递默认到最后使用的渠道(或已配置的目标)。
## 重连行为
- 退避策略:`web.reconnect`
- `initialMs`、`maxMs`、`factor`、`jitter`、`maxAttempts`。
- 如果达到 maxAttempts网页监控停止降级
- 已注销 => 停止并要求重新关联。
## 配置速查表
- `channels.whatsapp.dmPolicy`私聊策略pairing/allowlist/open/disabled
- `channels.whatsapp.selfChatMode`(同号设置;机器人使用你的个人 WhatsApp 号码)。
- `channels.whatsapp.allowFrom`私聊允许列表。WhatsApp 使用 E.164 手机号码(无用户名)。
- `channels.whatsapp.mediaMaxMb`(入站媒体保存上限)。
- `channels.whatsapp.ackReaction`(消息收到时的自动反应:`{emoji, direct, group}`)。
- `channels.whatsapp.accounts.<accountId>.*`(按账号设置 + 可选 `authDir`)。
- `channels.whatsapp.accounts.<accountId>.mediaMaxMb`(按账号入站媒体上限)。
- `channels.whatsapp.accounts.<accountId>.ackReaction`(按账号确认反应覆盖)。
- `channels.whatsapp.groupAllowFrom`(群聊发送者允许列表)。
- `channels.whatsapp.groupPolicy`(群聊策略)。
- `channels.whatsapp.historyLimit` / `channels.whatsapp.accounts.<accountId>.historyLimit`(群聊历史上下文;`0` 禁用)。
- `channels.whatsapp.dmHistoryLimit`(私聊历史限制,按用户轮数)。按用户覆盖:`channels.whatsapp.dms["<phone>"].historyLimit`。
- `channels.whatsapp.groups`(群聊允许列表 + 提及门控默认值;使用 `"*"` 允许全部)
- `channels.whatsapp.actions.reactions`WhatsApp 工具反应门控)。
- `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`
- `messages.groupChat.historyLimit`
- `channels.whatsapp.messagePrefix`(入站前缀;按账号:`channels.whatsapp.accounts.<accountId>.messagePrefix`;已弃用:`messages.messagePrefix`
- `messages.responsePrefix`(出站前缀)
- `agents.defaults.mediaMaxMb`
- `agents.defaults.heartbeat.every`
- `agents.defaults.heartbeat.model`(可选覆盖)
- `agents.defaults.heartbeat.target`
- `agents.defaults.heartbeat.to`
- `agents.defaults.heartbeat.session`
- `agents.list[].heartbeat.*`(按智能体覆盖)
- `session.*`scope、idle、store、mainKey
- `web.enabled`(为 false 时禁用渠道启动)
- `web.heartbeatSeconds`
- `web.reconnect.*`
## 日志 + 故障排除
- 子系统:`whatsapp/inbound`、`whatsapp/outbound`、`web-heartbeat`、`web-reconnect`。
- 日志文件:`/tmp/openclaw/openclaw-YYYY-MM-DD.log`(可配置)。
- 故障排除指南:[Gateway网关故障排除](/gateway/troubleshooting)。
## 故障排除(快速)
**未关联 / 需要二维码登录**
- 症状:`channels status` 显示 `linked: false` 或警告"未关联"。
- 修复:在 Gateway网关主机上运行 `openclaw channels login` 并扫描二维码WhatsApp → 设置 → 已关联设备)。
**已关联但断开连接 / 重连循环**
- 症状:`channels status` 显示 `running, disconnected` 或警告"已关联但断开连接"。
- 修复:`openclaw doctor`(或重启 Gateway网关。如果问题持续通过 `channels login` 重新关联并检查 `openclaw logs --follow`
**Bun 运行时**
- **不推荐**使用 Bun。WhatsAppBaileys和 Telegram 在 Bun 上不稳定。
请使用 **Node** 运行 Gateway网关。参见入门指南运行时说明。

196
docs/zh-CN/channels/zalo.md Normal file
View file

@ -0,0 +1,196 @@
---
read_when:
- 处理 Zalo 功能或 webhook 时
summary: Zalo 机器人支持状态、功能和配置
title: Zalo
x-i18n:
generated_at: "2026-02-01T19:58:32Z"
model: claude-opus-4-5
provider: pi
source_hash: 0311d932349f96412b712970b5d37329b91929bf3020536edf3ca0ff464373c0
source_path: channels/zalo.md
workflow: 14
---
# Zalo (Bot API)
状态:实验性。仅支持私信;根据 Zalo 文档,群组功能即将推出。
## 需要插件
Zalo 以插件形式提供,不包含在核心安装中。
- 通过 CLI 安装:`openclaw plugins install @openclaw/zalo`
- 或在新手引导中选择 **Zalo** 并确认安装提示
- 详情:[插件](/plugin)
## 快速设置(新手)
1. 安装 Zalo 插件:
- 从源码检出安装:`openclaw plugins install ./extensions/zalo`
- 从 npm 安装(如已发布):`openclaw plugins install @openclaw/zalo`
- 或在新手引导中选择 **Zalo** 并确认安装提示
2. 设置令牌:
- 环境变量:`ZALO_BOT_TOKEN=...`
- 或配置:`channels.zalo.botToken: "..."`。
3. 重启 Gateway网关或完成新手引导
4. 私信访问默认使用配对模式;首次联系时需批准配对码。
最小配置:
```json5
{
channels: {
zalo: {
enabled: true,
botToken: "12345689:abc-xyz",
dmPolicy: "pairing",
},
},
}
```
## 简介
Zalo 是一款面向越南市场的即时通讯应用;其 Bot API 允许 Gateway网关运行一个用于一对一对话的机器人。
它非常适合需要将消息确定性路由回 Zalo 的客服或通知场景。
- 由 Gateway网关管理的 Zalo Bot API 渠道。
- 确定性路由:回复始终返回 Zalo模型不会选择渠道。
- 私信共享智能体的主会话。
- 群组尚不支持Zalo 文档标注"即将推出")。
## 设置(快速路径)
### 1) 创建机器人令牌Zalo Bot Platform
1. 前往 **https://bot.zaloplatforms.com** 并登录。
2. 创建新机器人并配置其设置。
3. 复制机器人令牌(格式:`12345689:abc-xyz`)。
### 2) 配置令牌(环境变量或配置文件)
示例:
```json5
{
channels: {
zalo: {
enabled: true,
botToken: "12345689:abc-xyz",
dmPolicy: "pairing",
},
},
}
```
环境变量选项:`ZALO_BOT_TOKEN=...`(仅适用于默认账户)。
多账户支持:使用 `channels.zalo.accounts`,为每个账户配置令牌和可选的 `name`
3. 重启 Gateway网关。当令牌被解析通过环境变量或配置Zalo 将启动。
4. 私信访问默认使用配对模式。机器人首次被联系时,请批准配对码。
## 工作原理(行为)
- 入站消息被标准化为共享渠道信封,并包含媒体占位符。
- 回复始终路由回同一个 Zalo 聊天。
- 默认使用长轮询;可通过 `channels.zalo.webhookUrl` 启用 webhook 模式。
## 限制
- 出站文本按 2000 字符分块Zalo API 限制)。
- 媒体下载/上传受 `channels.zalo.mediaMaxMb` 限制(默认 5
- 由于 2000 字符限制导致流式传输意义不大,默认禁用流式传输。
## 访问控制(私信)
### 私信访问
- 默认:`channels.zalo.dmPolicy = "pairing"`。未知发送者会收到配对码;消息在批准前将被忽略(配对码 1 小时后过期)。
- 批准方式:
- `openclaw pairing list zalo`
- `openclaw pairing approve zalo <CODE>`
- 配对是默认的令牌交换方式。详情:[配对](/start/pairing)
- `channels.zalo.allowFrom` 接受数字用户 ID不支持用户名查找
## 长轮询与 webhook
- 默认:长轮询(无需公网 URL
- Webhook 模式:设置 `channels.zalo.webhookUrl``channels.zalo.webhookSecret`
- Webhook 密钥必须为 8-256 个字符。
- Webhook URL 必须使用 HTTPS。
- Zalo 通过 `X-Bot-Api-Secret-Token` 请求头发送事件以进行验证。
- Gateway网关 HTTP 在 `channels.zalo.webhookPath` 处理 webhook 请求(默认为 webhook URL 路径)。
**注意:** 根据 Zalo API 文档getUpdates轮询和 webhook 互斥。
## 支持的消息类型
- **文本消息**:完全支持,按 2000 字符分块。
- **图片消息**:下载并处理入站图片;通过 `sendPhoto` 发送图片。
- **贴纸**:已记录但未完全处理(无智能体响应)。
- **不支持的类型**:已记录(例如来自受保护用户的消息)。
## 功能
| 功能 | 状态 |
| ------------ | ----------------------------- |
| 私信 | ✅ 支持 |
| 群组 | ❌ 即将推出(根据 Zalo 文档) |
| 媒体(图片) | ✅ 支持 |
| 表情回应 | ❌ 不支持 |
| 话题 | ❌ 不支持 |
| 投票 | ❌ 不支持 |
| 原生命令 | ❌ 不支持 |
| 流式传输 | ⚠️ 已禁用2000 字符限制) |
## 投递目标CLI/定时任务)
- 使用聊天 ID 作为目标。
- 示例:`openclaw message send --channel zalo --target 123456789 --message "hi"`。
## 故障排除
**机器人无响应:**
- 检查令牌是否有效:`openclaw channels status --probe`
- 验证发送者是否已批准(配对或 allowFrom
- 检查 Gateway网关日志`openclaw logs --follow`
**Webhook 未收到事件:**
- 确保 webhook URL 使用 HTTPS
- 验证密钥令牌为 8-256 个字符
- 确认 Gateway网关 HTTP 端点在配置的路径上可达
- 检查 getUpdates 轮询是否未在运行(两者互斥)
## 配置参考Zalo
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.zalo.enabled`:启用/禁用渠道启动。
- `channels.zalo.botToken`:来自 Zalo Bot Platform 的机器人令牌。
- `channels.zalo.tokenFile`:从文件路径读取令牌。
- `channels.zalo.dmPolicy``pairing | allowlist | open | disabled`默认pairing
- `channels.zalo.allowFrom`:私信允许列表(用户 ID。`open` 需要 `"*"`。向导会要求输入数字 ID。
- `channels.zalo.mediaMaxMb`:入站/出站媒体大小上限MB默认 5
- `channels.zalo.webhookUrl`:启用 webhook 模式(需要 HTTPS
- `channels.zalo.webhookSecret`webhook 密钥8-256 个字符)。
- `channels.zalo.webhookPath`Gateway网关 HTTP 服务器上的 webhook 路径。
- `channels.zalo.proxy`API 请求的代理 URL。
多账户选项:
- `channels.zalo.accounts.<id>.botToken`:每个账户的令牌。
- `channels.zalo.accounts.<id>.tokenFile`:每个账户的令牌文件。
- `channels.zalo.accounts.<id>.name`:显示名称。
- `channels.zalo.accounts.<id>.enabled`:启用/禁用账户。
- `channels.zalo.accounts.<id>.dmPolicy`:每个账户的私信策略。
- `channels.zalo.accounts.<id>.allowFrom`:每个账户的允许列表。
- `channels.zalo.accounts.<id>.webhookUrl`:每个账户的 webhook URL。
- `channels.zalo.accounts.<id>.webhookSecret`:每个账户的 webhook 密钥。
- `channels.zalo.accounts.<id>.webhookPath`:每个账户的 webhook 路径。
- `channels.zalo.accounts.<id>.proxy`:每个账户的代理 URL。

View file

@ -0,0 +1,147 @@
---
read_when:
- 为 OpenClaw 设置 Zalo Personal
- 调试 Zalo Personal 登录或消息流
summary: 通过 zca-cli二维码登录支持 Zalo 个人账号,功能与配置说明
title: Zalo Personal
x-i18n:
generated_at: "2026-02-01T19:58:27Z"
model: claude-opus-4-5
provider: pi
source_hash: 2a249728d556e5cc52274627bdaf390fa10e815afa04f4497feb57a2a0cb9261
source_path: channels/zalouser.md
workflow: 14
---
# Zalo Personal非官方
状态:实验性。此集成通过 `zca-cli` 自动化操作一个**个人 Zalo 账号**。
> **警告:** 这是一个非官方集成,可能导致账号被暂停或封禁。使用风险自负。
## 需要安装插件
Zalo Personal 以插件形式提供,不包含在核心安装包中。
- 通过 CLI 安装:`openclaw plugins install @openclaw/zalouser`
- 或从源码检出安装:`openclaw plugins install ./extensions/zalouser`
- 详情:[插件](/plugin)
## 前置条件zca-cli
Gateway网关所在机器必须在 `PATH` 中包含 `zca` 可执行文件。
- 验证:`zca --version`
- 如果缺失,请安装 zca-cli参见 `extensions/zalouser/README.md` 或上游 zca-cli 文档)。
## 快速设置(入门)
1. 安装插件(见上文)。
2. 登录(二维码方式,在 Gateway网关机器上操作
- `openclaw channels login --channel zalouser`
- 使用 Zalo 手机应用扫描终端中的二维码。
3. 启用渠道:
```json5
{
channels: {
zalouser: {
enabled: true,
dmPolicy: "pairing",
},
},
}
```
4. 重启 Gateway网关或完成新手引导
5. 私信访问默认为配对模式;首次联系时需批准配对码。
## 功能说明
- 使用 `zca listen` 接收入站消息。
- 使用 `zca msg ...` 发送回复(文本/媒体/链接)。
- 专为 Zalo Bot API 不可用时的"个人账号"使用场景设计。
## 命名说明
渠道 ID 为 `zalouser`,以明确表示这是对**个人 Zalo 用户账号**的自动化操作(非官方)。我们将 `zalo` 保留给未来可能的官方 Zalo API 集成。
## 查找 ID通讯录
使用通讯录 CLI 发现联系人/群组及其 ID
```bash
openclaw directory self --channel zalouser
openclaw directory peers list --channel zalouser --query "name"
openclaw directory groups list --channel zalouser --query "work"
```
## 限制
- 出站文本按约 2000 字符分块Zalo 客户端限制)。
- 流式传输默认被禁用。
## 访问控制(私信)
`channels.zalouser.dmPolicy` 支持:`pairing | allowlist | open | disabled`(默认:`pairing`)。
`channels.zalouser.allowFrom` 接受用户 ID 或名称。向导在可用时通过 `zca friend find` 将名称解析为 ID。
通过以下方式批准:
- `openclaw pairing list zalouser`
- `openclaw pairing approve zalouser <code>`
## 群组访问(可选)
- 默认:`channels.zalouser.groupPolicy = "open"`(允许群组)。未设置时使用 `channels.defaults.groupPolicy` 覆盖默认值。
- 通过允许列表进行限制:
- `channels.zalouser.groupPolicy = "allowlist"`
- `channels.zalouser.groups`(键为群组 ID 或名称)
- 禁止所有群组:`channels.zalouser.groupPolicy = "disabled"`。
- 配置向导可以提示设置群组允许列表。
- 启动时OpenClaw 会将允许列表中的群组/用户名称解析为 ID 并记录映射关系;未解析的条目保持原样。
示例:
```json5
{
channels: {
zalouser: {
groupPolicy: "allowlist",
groups: {
"123456789": { allow: true },
"Work Chat": { allow: true },
},
},
},
}
```
## 多账号
账号映射到 zca 配置文件。示例:
```json5
{
channels: {
zalouser: {
enabled: true,
defaultAccount: "default",
accounts: {
work: { enabled: true, profile: "work" },
},
},
},
}
```
## 故障排除
**找不到 `zca`**
- 安装 zca-cli 并确保 Gateway网关进程的 `PATH` 中包含该命令。
**登录状态无法保持:**
- `openclaw channels status --probe`
- 重新登录:`openclaw channels logout --channel zalouser && openclaw channels login --channel zalouser`

173
docs/zh-CN/cli/acp.md Normal file
View file

@ -0,0 +1,173 @@
---
read_when:
- 设置基于 ACP 的 IDE 集成
- 调试 ACP 会话到 Gateway网关的路由
summary: 运行用于 IDE 集成的 ACP 桥接
title: acp
x-i18n:
generated_at: "2026-02-01T19:58:33Z"
model: claude-opus-4-5
provider: pi
source_hash: 0c09844297da250bc1a558423e7e534d6b6be9045de12d797c07ecd64a0c63ed
source_path: cli/acp.md
workflow: 14
---
# acp
运行与 OpenClaw Gateway网关通信的 ACPAgent Client Protocol桥接。
此命令通过 stdio 使用 ACP 协议与 IDE 通信,并通过 WebSocket 将提示转发到 Gateway网关。它将 ACP 会话映射到 Gateway网关会话密钥。
## 用法
```bash
openclaw acp
# 远程 Gateway网关
openclaw acp --url wss://gateway-host:18789 --token <token>
# 附加到现有会话密钥
openclaw acp --session agent:main:main
# 通过标签附加(必须已存在)
openclaw acp --session-label "support inbox"
# 在第一个提示之前重置会话密钥
openclaw acp --session agent:main:main --reset-session
```
## ACP 客户端(调试)
使用内置 ACP 客户端在无需 IDE 的情况下对桥接进行安装完整性检查。
它会启动 ACP 桥接并允许你交互式地输入提示。
```bash
openclaw acp client
# 将启动的桥接指向远程 Gateway网关
openclaw acp client --server-args --url wss://gateway-host:18789 --token <token>
# 覆盖服务器命令默认openclaw
openclaw acp client --server "node" --server-args openclaw.mjs acp --url ws://127.0.0.1:19001
```
## 如何使用
当 IDE或其他客户端使用 Agent Client Protocol 并且你希望它驱动 OpenClaw Gateway网关会话时请使用 ACP。
1. 确保 Gateway网关正在运行本地或远程
2. 配置 Gateway网关目标通过配置文件或标志
3. 将你的 IDE 配置为通过 stdio 运行 `openclaw acp`
示例配置(持久化):
```bash
openclaw config set gateway.remote.url wss://gateway-host:18789
openclaw config set gateway.remote.token <token>
```
示例直接运行(不写入配置):
```bash
openclaw acp --url wss://gateway-host:18789 --token <token>
```
## 选择智能体
ACP 不直接选择智能体。它通过 Gateway网关会话密钥进行路由。
使用智能体作用域的会话密钥来指定特定智能体:
```bash
openclaw acp --session agent:main:main
openclaw acp --session agent:design:main
openclaw acp --session agent:qa:bug-123
```
每个 ACP 会话映射到单个 Gateway网关会话密钥。一个智能体可以有多个会话除非你覆盖密钥或标签否则 ACP 默认使用隔离的 `acp:<uuid>` 会话。
## Zed 编辑器设置
`~/.config/zed/settings.json` 中添加自定义 ACP 智能体(或使用 Zed 的设置界面):
```json
{
"agent_servers": {
"OpenClaw ACP": {
"type": "custom",
"command": "openclaw",
"args": ["acp"],
"env": {}
}
}
}
```
要指定特定的 Gateway网关或智能体
```json
{
"agent_servers": {
"OpenClaw ACP": {
"type": "custom",
"command": "openclaw",
"args": [
"acp",
"--url",
"wss://gateway-host:18789",
"--token",
"<token>",
"--session",
"agent:design:main"
],
"env": {}
}
}
}
```
在 Zed 中,打开 Agent 面板并选择 "OpenClaw ACP" 来开始一个对话线程。
## 会话映射
默认情况下ACP 会话会获得一个带有 `acp:` 前缀的隔离 Gateway网关会话密钥。
要复用已知会话,请传递会话密钥或标签:
- `--session <key>`:使用特定的 Gateway网关会话密钥。
- `--session-label <label>`:通过标签解析现有会话。
- `--reset-session`:为该密钥生成新的会话 ID相同密钥新的对话记录
如果你的 ACP 客户端支持元数据,你可以按会话进行覆盖:
```json
{
"_meta": {
"sessionKey": "agent:main:main",
"sessionLabel": "support inbox",
"resetSession": true
}
}
```
了解更多关于会话密钥的信息,请参阅 [/concepts/session](/concepts/session)。
## 选项
- `--url <url>`Gateway网关 WebSocket URL配置后默认使用 gateway.remote.url
- `--token <token>`Gateway网关认证令牌。
- `--password <password>`Gateway网关认证密码。
- `--session <key>`:默认会话密钥。
- `--session-label <label>`:要解析的默认会话标签。
- `--require-existing`:如果会话密钥/标签不存在则失败。
- `--reset-session`:在首次使用前重置会话密钥。
- `--no-prefix-cwd`:不在提示前添加工作目录前缀。
- `--verbose, -v`:将详细日志输出到 stderr。
### `acp client` 选项
- `--cwd <dir>`ACP 会话的工作目录。
- `--server <command>`ACP 服务器命令(默认:`openclaw`)。
- `--server-args <args...>`:传递给 ACP 服务器的额外参数。
- `--server-verbose`:启用 ACP 服务器的详细日志。
- `--verbose, -v`:详细客户端日志。

31
docs/zh-CN/cli/agent.md Normal file
View file

@ -0,0 +1,31 @@
---
read_when:
- 你想从脚本中运行一次智能体轮次(可选择投递回复)
summary: "`openclaw agent` 的 CLI 参考(通过 Gateway网关发送一次智能体轮次"
title: agent
x-i18n:
generated_at: "2026-02-01T19:58:31Z"
model: claude-opus-4-5
provider: pi
source_hash: dcf12fb94e207c68645f58235792596d65afecf8216b8f9ab3acb01e03b50a33
source_path: cli/agent.md
workflow: 14
---
# `openclaw agent`
通过 Gateway网关运行一次智能体轮次使用 `--local` 进行嵌入式运行)。
使用 `--agent <id>` 直接指定一个已配置的智能体。
相关内容:
- 智能体发送工具:[智能体发送](/tools/agent-send)
## 示例
```bash
openclaw agent --to +15555550123 --message "status update" --deliver
openclaw agent --agent ops --message "Summarize logs"
openclaw agent --session-id 1234 --message "Summarize inbox" --thinking medium
openclaw agent --agent ops --message "Generate report" --deliver --reply-channel slack --reply-to "#reports"
```

82
docs/zh-CN/cli/agents.md Normal file
View file

@ -0,0 +1,82 @@
---
read_when:
- 你需要多个隔离的智能体(工作区 + 路由 + 认证)
summary: "`openclaw agents` 的 CLI 参考(列出/添加/删除/设置身份)"
title: agents
x-i18n:
generated_at: "2026-02-01T19:58:38Z"
model: claude-opus-4-5
provider: pi
source_hash: 30556d81636a9ad8972573cc6b498e620fd266e1dfb16eef3f61096ea62f9896
source_path: cli/agents.md
workflow: 14
---
# `openclaw agents`
管理隔离的智能体(工作区 + 认证 + 路由)。
相关内容:
- 多智能体路由:[多智能体路由](/concepts/multi-agent)
- 智能体工作区:[智能体工作区](/concepts/agent-workspace)
## 示例
```bash
openclaw agents list
openclaw agents add work --workspace ~/.openclaw/workspace-work
openclaw agents set-identity --workspace ~/.openclaw/workspace --from-identity
openclaw agents set-identity --agent main --avatar avatars/openclaw.png
openclaw agents delete work
```
## 身份文件
每个智能体工作区可以在工作区根目录包含一个 `IDENTITY.md`
- 示例路径:`~/.openclaw/workspace/IDENTITY.md`
- `set-identity --from-identity` 从工作区根目录读取(或从显式指定的 `--identity-file` 读取)
头像路径相对于工作区根目录解析。
## 设置身份
`set-identity` 将字段写入 `agents.list[].identity`
- `name`
- `theme`
- `emoji`
- `avatar`工作区相对路径、http(s) URL 或 data URI
`IDENTITY.md` 加载:
```bash
openclaw agents set-identity --workspace ~/.openclaw/workspace --from-identity
```
显式覆盖字段:
```bash
openclaw agents set-identity --agent main --name "OpenClaw" --emoji "🦞" --avatar avatars/openclaw.png
```
配置示例:
```json5
{
agents: {
list: [
{
id: "main",
identity: {
name: "OpenClaw",
theme: "space lobster",
emoji: "🦞",
avatar: "avatars/openclaw.png",
},
},
],
},
}
```

View file

@ -0,0 +1,57 @@
---
read_when:
- 你想通过 CLI 编辑执行审批
- 你需要管理 Gateway网关或节点主机上的允许列表
summary: "`openclaw approvals` 的 CLI 参考(用于 Gateway网关或节点主机的执行审批"
title: approvals
x-i18n:
generated_at: "2026-02-01T19:58:39Z"
model: claude-opus-4-5
provider: pi
source_hash: 4329cdaaec2c5f5d619415b6431196512d4834dc1ccd7363576f03dd9b845130
source_path: cli/approvals.md
workflow: 14
---
# `openclaw approvals`
管理**本地主机**、**Gateway网关主机**或**节点主机**的执行审批。
默认情况下,命令针对磁盘上的本地审批文件。使用 `--gateway` 针对 Gateway网关或使用 `--node` 针对特定节点。
相关内容:
- 执行审批:[执行审批](/tools/exec-approvals)
- 节点:[节点](/nodes)
## 常用命令
```bash
openclaw approvals get
openclaw approvals get --node <id|name|ip>
openclaw approvals get --gateway
```
## 从文件替换审批
```bash
openclaw approvals set --file ./exec-approvals.json
openclaw approvals set --node <id|name|ip> --file ./exec-approvals.json
openclaw approvals set --gateway --file ./exec-approvals.json
```
## 允许列表辅助命令
```bash
openclaw approvals allowlist add "~/Projects/**/bin/rg"
openclaw approvals allowlist add --agent main --node <id|name|ip> "/usr/bin/uptime"
openclaw approvals allowlist add --agent "*" "/usr/bin/uname"
openclaw approvals allowlist remove "~/Projects/**/bin/rg"
```
## 注意事项
- `--node` 使用与 `openclaw nodes` 相同的解析器id、名称、ip 或 id 前缀)。
- `--agent` 默认为 `"*"`,即适用于所有智能体。
- 节点主机必须公布 `system.execApprovals.get/set`macOS 应用或无头节点主机)。
- 审批文件按主机存储在 `~/.openclaw/exec-approvals.json`

114
docs/zh-CN/cli/browser.md Normal file
View file

@ -0,0 +1,114 @@
---
read_when:
- 使用 `openclaw browser` 并需要常见任务的示例
- 想要通过节点主机控制运行在另一台机器上的浏览器
- 想要使用 Chrome 扩展中继(通过工具栏按钮附加/分离)
summary: "`openclaw browser` 的 CLI 参考(配置文件、标签页、操作、扩展中继)"
title: browser
x-i18n:
generated_at: "2026-02-01T19:58:45Z"
model: claude-opus-4-5
provider: pi
source_hash: af35adfd68726fd519c704d046451effd330458c2b8305e713137fb07b2571fd
source_path: cli/browser.md
workflow: 14
---
# `openclaw browser`
管理 OpenClaw 的浏览器控制服务器并执行浏览器操作(标签页、快照、截图、导航、点击、输入)。
相关内容:
- 浏览器工具 + API[浏览器工具](/tools/browser)
- Chrome 扩展中继:[Chrome 扩展](/tools/chrome-extension)
## 常用标志
- `--url <gatewayWsUrl>`Gateway网关 WebSocket URL默认使用配置值
- `--token <token>`Gateway网关令牌如需要
- `--timeout <ms>`:请求超时时间(毫秒)。
- `--browser-profile <name>`:选择浏览器配置文件(默认使用配置值)。
- `--json`:机器可读输出(在支持的情况下)。
## 快速开始(本地)
```bash
openclaw browser --browser-profile chrome tabs
openclaw browser --browser-profile openclaw start
openclaw browser --browser-profile openclaw open https://example.com
openclaw browser --browser-profile openclaw snapshot
```
## 配置文件
配置文件是命名的浏览器路由配置。实际使用中:
- `openclaw`:启动/附加到一个专用的 OpenClaw 管理的 Chrome 实例(隔离的用户数据目录)。
- `chrome`:通过 Chrome 扩展中继控制你现有的 Chrome 标签页。
```bash
openclaw browser profiles
openclaw browser create-profile --name work --color "#FF5A36"
openclaw browser delete-profile --name work
```
使用特定配置文件:
```bash
openclaw browser --browser-profile work tabs
```
## 标签页
```bash
openclaw browser tabs
openclaw browser open https://docs.openclaw.ai
openclaw browser focus <targetId>
openclaw browser close <targetId>
```
## 快照 / 截图 / 操作
快照:
```bash
openclaw browser snapshot
```
截图:
```bash
openclaw browser screenshot
```
导航/点击/输入(基于引用的 UI 自动化):
```bash
openclaw browser navigate https://example.com
openclaw browser click <ref>
openclaw browser type <ref> "hello"
```
## Chrome 扩展中继(通过工具栏按钮附加)
此模式允许智能体控制你手动附加的现有 Chrome 标签页(不会自动附加)。
将未打包的扩展安装到稳定路径:
```bash
openclaw browser extension install
openclaw browser extension path
```
然后在 Chrome 中 → `chrome://extensions` → 启用"开发者模式" → "加载已解压的扩展程序" → 选择打印出的文件夹。
完整指南:[Chrome 扩展](/tools/chrome-extension)
## 远程浏览器控制(节点主机代理)
如果 Gateway网关与浏览器运行在不同的机器上请在安装了 Chrome/Brave/Edge/Chromium 的机器上运行**节点主机**。Gateway网关会将浏览器操作代理到该节点无需单独的浏览器控制服务器
使用 `gateway.nodes.browser.mode` 控制自动路由,使用 `gateway.nodes.browser.node` 在多个节点连接时固定到特定节点。
安全性 + 远程设置:[浏览器工具](/tools/browser)、[远程访问](/gateway/remote)、[Tailscale](/gateway/tailscale)、[安全](/gateway/security)

View file

@ -0,0 +1,86 @@
---
read_when:
- 你想添加/移除渠道账号WhatsApp/Telegram/Discord/Google Chat/Slack/Mattermost插件/Signal/iMessage
- 你想检查渠道状态或查看渠道日志
summary: "`openclaw channels` 的 CLI 参考(账号、状态、登录/登出、日志)"
title: channels
x-i18n:
generated_at: "2026-02-01T19:58:48Z"
model: claude-opus-4-5
provider: pi
source_hash: 16ab1642f247bfa96e8e08dfeb1eedfccb148f40d91099f5423f971df2b54e20
source_path: cli/channels.md
workflow: 14
---
# `openclaw channels`
管理 Gateway网关上的聊天渠道账号及其运行时状态。
相关文档:
- 渠道指南:[渠道](/channels/index)
- Gateway网关配置[配置](/gateway/configuration)
## 常用命令
```bash
openclaw channels list
openclaw channels status
openclaw channels capabilities
openclaw channels capabilities --channel discord --target channel:123
openclaw channels resolve --channel slack "#general" "@jane"
openclaw channels logs --channel all
```
## 添加/移除账号
```bash
openclaw channels add --channel telegram --token <bot-token>
openclaw channels remove --channel telegram --delete
```
提示:`openclaw channels add --help` 可查看各渠道的专用参数token、app token、signal-cli 路径等)。
## 登录/登出(交互式)
```bash
openclaw channels login --channel whatsapp
openclaw channels logout --channel whatsapp
```
## 故障排除
- 运行 `openclaw status --deep` 进行全面探测。
- 使用 `openclaw doctor` 获取引导式修复。
- `openclaw channels list` 输出 `Claude: HTTP 403 ... user:profile` → 用量快照需要 `user:profile` 权限范围。使用 `--no-usage`,或提供 claude.ai 会话密钥(`CLAUDE_WEB_SESSION_KEY` / `CLAUDE_WEB_COOKIE`),或通过 Claude Code CLI 重新认证。
## 能力探测
获取提供商能力提示(可用的 intents/scopes以及静态功能支持
```bash
openclaw channels capabilities
openclaw channels capabilities --channel discord --target channel:123
```
说明:
- `--channel` 是可选的;省略时将列出所有渠道(包括扩展)。
- `--target` 接受 `channel:<id>` 或原始数字频道 ID仅适用于 Discord。
- 探测因提供商而异Discord intents + 可选的频道权限Slack bot + 用户权限范围Telegram bot 标志 + webhookSignal 守护进程版本MS Teams 应用令牌 + Graph 角色/权限范围(已知的会标注)。无探测功能的渠道会报告 `Probe: unavailable`
## 将名称解析为 ID
使用提供商目录将渠道/用户名称解析为 ID
```bash
openclaw channels resolve --channel slack "#general" "@jane"
openclaw channels resolve --channel discord "My Server/#support" "@someone"
openclaw channels resolve --channel matrix "Project Room"
```
说明:
- 使用 `--kind user|group|auto` 强制指定目标类型。
- 当多个条目共享相同名称时,解析优先选择活跃的匹配项。

56
docs/zh-CN/cli/config.md Normal file
View file

@ -0,0 +1,56 @@
---
read_when:
- 你想以非交互方式读取或编辑配置
summary: "`openclaw config` 的 CLI 参考(获取/设置/删除配置值)"
title: config
x-i18n:
generated_at: "2026-02-01T19:58:45Z"
model: claude-opus-4-5
provider: pi
source_hash: d60a35f5330f22bc99a0df090590586109d329ddd2ca294aeed191a22560c1c2
source_path: cli/config.md
workflow: 14
---
# `openclaw config`
配置辅助工具:通过路径获取/设置/删除值。不带子命令运行时将打开配置向导(与 `openclaw configure` 相同)。
## 示例
```bash
openclaw config get browser.executablePath
openclaw config set browser.executablePath "/usr/bin/google-chrome"
openclaw config set agents.defaults.heartbeat.every "2h"
openclaw config set agents.list[0].tools.exec.node "node-id-or-name"
openclaw config unset tools.web.search.apiKey
```
## 路径
路径使用点号或方括号表示法:
```bash
openclaw config get agents.defaults.workspace
openclaw config get agents.list[0].id
```
使用智能体列表索引来指定特定智能体:
```bash
openclaw config get agents.list
openclaw config set agents.list[1].tools.exec.node "node-id-or-name"
```
## 值
值会尽可能按 JSON5 解析;否则视为字符串。
使用 `--json` 强制要求 JSON5 解析。
```bash
openclaw config set agents.defaults.heartbeat.every "0m"
openclaw config set gateway.port 19001 --json
openclaw config set channels.whatsapp.groups '["*"]' --json
```
编辑后请重启 Gateway网关。

View file

@ -0,0 +1,40 @@
---
read_when:
- 你想通过交互方式调整凭据、设备或智能体默认设置
summary: "`openclaw configure` 的 CLI 参考(交互式配置提示)"
title: configure
x-i18n:
generated_at: "2026-02-01T19:58:46Z"
model: claude-opus-4-5
provider: pi
source_hash: 9cb2bb5237b02b3a2dca71b5e43b11bd6b9939b9e4aa9ce1882457464b51efd2
source_path: cli/configure.md
workflow: 14
---
# `openclaw configure`
交互式提示,用于设置凭据、设备和智能体默认配置。
注意:**模型**部分现在包含一个多选项,用于设置
`agents.defaults.models` 允许列表(决定在 `/model` 和模型选择器中显示哪些模型)。
提示:不带子命令运行 `openclaw config` 会打开相同的向导。使用
`openclaw config get|set|unset` 进行非交互式编辑。
相关内容:
- Gateway网关配置参考[配置](/gateway/configuration)
- Config CLI[Config](/cli/config)
注意事项:
- 选择 Gateway网关运行位置时会始终更新 `gateway.mode`。如果你只需要修改这一项,可以直接选择"继续"而无需配置其他部分。
- 面向渠道的服务Slack/Discord/Matrix/Microsoft Teams在设置过程中会提示配置渠道/房间允许列表。你可以输入名称或 ID向导会尽可能将名称解析为 ID。
## 示例
```bash
openclaw configure
openclaw configure --section models --section channels
```

38
docs/zh-CN/cli/cron.md Normal file
View file

@ -0,0 +1,38 @@
---
read_when:
- 你需要定时任务和唤醒功能
- 你正在调试定时任务的执行和日志
summary: "`openclaw cron` 的 CLI 参考(调度和运行后台任务)"
title: cron
x-i18n:
generated_at: "2026-02-01T19:58:49Z"
model: claude-opus-4-5
provider: pi
source_hash: bc9317c824f3b6339df657cc269961d9b5f121da65ec2b23a07d454e6d611135
source_path: cli/cron.md
workflow: 14
---
# `openclaw cron`
管理 Gateway网关调度器的定时任务。
相关内容:
- 定时任务:[定时任务](/automation/cron-jobs)
提示:运行 `openclaw cron --help` 查看完整的命令列表。
## 常见编辑
更新投递设置而不更改消息内容:
```bash
openclaw cron edit <job-id> --deliver --channel telegram --to "123456789"
```
为隔离任务禁用投递:
```bash
openclaw cron edit <job-id> --no-deliver
```

View file

@ -0,0 +1,23 @@
---
read_when:
- 想要使用当前令牌打开控制界面
- 想要打印 URL 而不启动浏览器
summary: "`openclaw dashboard` 的 CLI 参考(打开控制界面)"
title: dashboard
x-i18n:
generated_at: "2026-02-01T19:58:50Z"
model: claude-opus-4-5
provider: pi
source_hash: 242a3b35ea43149be12ee2b8f2bc81b6dc24cea546a15f422dcfd0cf2e7724db
source_path: cli/dashboard.md
workflow: 14
---
# `openclaw dashboard`
使用当前认证信息打开控制界面。
```bash
openclaw dashboard
openclaw dashboard --no-open
```

74
docs/zh-CN/cli/devices.md Normal file
View file

@ -0,0 +1,74 @@
---
read_when:
- 你正在审批设备配对请求
- 你需要轮换或吊销设备令牌
summary: "`openclaw devices` 的 CLI 参考(设备配对 + 令牌轮换/吊销)"
title: devices
x-i18n:
generated_at: "2026-02-01T19:58:53Z"
model: claude-opus-4-5
provider: pi
source_hash: 52f903817d2886c1dc29b85d30168d1edff7944bd120a1e139159c9d99a1f517
source_path: cli/devices.md
workflow: 14
---
# `openclaw devices`
管理设备配对请求和设备范围的令牌。
## 命令
### `openclaw devices list`
列出待处理的配对请求和已配对的设备。
```
openclaw devices list
openclaw devices list --json
```
### `openclaw devices approve <requestId>`
批准待处理的设备配对请求。
```
openclaw devices approve <requestId>
```
### `openclaw devices reject <requestId>`
拒绝待处理的设备配对请求。
```
openclaw devices reject <requestId>
```
### `openclaw devices rotate --device <id> --role <role> [--scope <scope...>]`
轮换特定角色的设备令牌(可选择更新权限范围)。
```
openclaw devices rotate --device <deviceId> --role operator --scope operator.read --scope operator.write
```
### `openclaw devices revoke --device <id> --role <role>`
吊销特定角色的设备令牌。
```
openclaw devices revoke --device <deviceId> --role node
```
## 通用选项
- `--url <url>`Gateway网关 WebSocket URL配置后默认使用 `gateway.remote.url`)。
- `--token <token>`Gateway网关令牌如需要
- `--password <password>`Gateway网关密码密码认证
- `--timeout <ms>`RPC 超时时间。
- `--json`JSON 输出(推荐用于脚本)。
## 注意事项
- 令牌轮换会返回新令牌(敏感信息)。请将其视为机密处理。
- 这些命令需要 `operator.pairing`(或 `operator.admin`)权限范围。

View file

@ -0,0 +1,70 @@
---
read_when:
- 你想查找某个渠道的联系人/群组/自身 ID
- 你正在开发渠道目录适配器
summary: "`openclaw directory` 的 CLI 参考self、peers、groups"
title: directory
x-i18n:
generated_at: "2026-02-01T19:58:58Z"
model: claude-opus-4-5
provider: pi
source_hash: 7c878d9013aeaa22c8a21563fac30b465a86be85d8c917c5d4591b5c3d4b2025
source_path: cli/directory.md
workflow: 14
---
# `openclaw directory`
对支持目录功能的渠道进行查找(联系人/对等方、群组和"我")。
## 通用参数
- `--channel <name>`:渠道 ID/别名(配置了多个渠道时为必填;仅配置一个渠道时自动选择)
- `--account <id>`:账号 ID默认渠道默认账号
- `--json`:输出 JSON 格式
## 说明
- `directory` 用于帮助你查找可粘贴到其他命令中的 ID特别是 `openclaw message send --target ...`)。
- 对于许多渠道,结果来源于配置(允许列表/已配置的群组),而非实时的提供商目录。
- 默认输出为以制表符分隔的 `id`(有时包含 `name`);脚本中请使用 `--json`
## 将结果用于 `message send`
```bash
openclaw directory peers list --channel slack --query "U0"
openclaw message send --channel slack --target user:U012ABCDEF --message "hello"
```
## ID 格式(按渠道)
- WhatsApp`+15551234567`(私聊),`1234567890-1234567890@g.us`(群组)
- Telegram`@username` 或数字聊天 ID群组为数字 ID
- Slack`user:U…` 和 `channel:C…`
- Discord`user:<id>` 和 `channel:<id>`
- Matrix插件`user:@user:server`、`room:!roomId:server` 或 `#alias:server`
- Microsoft Teams插件`user:<id>` 和 `conversation:<id>`
- Zalo插件用户 IDBot API
- Zalo Personal / `zalouser`(插件):来自 `zca` 的会话 ID私聊/群组)(`me`、`friend list`、`group list`
## Self"我"
```bash
openclaw directory self --channel zalouser
```
## Peers联系人/用户)
```bash
openclaw directory peers list --channel zalouser
openclaw directory peers list --channel zalouser --query "name"
openclaw directory peers list --channel zalouser --limit 50
```
## 群组
```bash
openclaw directory groups list --channel zalouser
openclaw directory groups list --channel zalouser --query "work"
openclaw directory groups members --channel zalouser --group-id <id>
```

30
docs/zh-CN/cli/dns.md Normal file
View file

@ -0,0 +1,30 @@
---
read_when:
- 你需要通过 Tailscale + CoreDNS 实现广域发现DNS-SD
- 你正在为自定义发现域名设置分离 DNS例如openclaw.internal
summary: "`openclaw dns` 的 CLI 参考(广域发现辅助工具)"
title: dns
x-i18n:
generated_at: "2026-02-01T19:58:53Z"
model: claude-opus-4-5
provider: pi
source_hash: d2011e41982ffb4b71ab98211574529bc1c8b7769ab1838abddd593f42b12380
source_path: cli/dns.md
workflow: 14
---
# `openclaw dns`
用于广域发现的 DNS 辅助工具Tailscale + CoreDNS。目前专注于 macOS + Homebrew CoreDNS。
相关内容:
- Gateway网关发现[发现](/gateway/discovery)
- 广域发现配置:[配置](/gateway/configuration)
## 设置
```bash
openclaw dns setup
openclaw dns setup --apply
```

22
docs/zh-CN/cli/docs.md Normal file
View file

@ -0,0 +1,22 @@
---
read_when:
- 想要从终端搜索 OpenClaw 在线文档
summary: "`openclaw docs` 的 CLI 参考(搜索在线文档索引)"
title: docs
x-i18n:
generated_at: "2026-02-01T19:58:52Z"
model: claude-opus-4-5
provider: pi
source_hash: 7a4000e91f7c6ed1140f684e2d1849577651e9389c5c90532a74db58c0b86d47
source_path: cli/docs.md
workflow: 14
---
# `openclaw docs`
搜索在线文档索引。
```bash
openclaw docs browser extension
openclaw docs sandbox allowHostControl
```

48
docs/zh-CN/cli/doctor.md Normal file
View file

@ -0,0 +1,48 @@
---
read_when:
- 遇到连接/认证问题并需要引导修复
- 更新后想要进行安装完整性检查
summary: "`openclaw doctor` 的 CLI 参考(健康检查 + 引导修复)"
title: doctor
x-i18n:
generated_at: "2026-02-01T19:58:59Z"
model: claude-opus-4-5
provider: pi
source_hash: 92310aa3f3d111e91a74ce1150359d5d8a8d70a856666d9419e16c60d78209f2
source_path: cli/doctor.md
workflow: 14
---
# `openclaw doctor`
Gateway网关和渠道的健康检查 + 快速修复。
相关内容:
- 故障排除:[故障排除](/gateway/troubleshooting)
- 安全审计:[安全](/gateway/security)
## 示例
```bash
openclaw doctor
openclaw doctor --repair
openclaw doctor --deep
```
备注:
- 交互式提示(如钥匙串/OAuth 修复)仅在 stdin 为 TTY 且**未**设置 `--non-interactive` 时运行。无头运行cron、Telegram、无终端将跳过提示。
- `--fix``--repair` 的别名)会将备份写入 `~/.openclaw/openclaw.json.bak`,并删除未知的配置键,同时列出每个删除项。
## macOS`launchctl` 环境变量覆盖
如果你之前运行过 `launchctl setenv OPENCLAW_GATEWAY_TOKEN ...`(或 `...PASSWORD`),该值会覆盖你的配置文件,并可能导致持续的"未授权"错误。
```bash
launchctl getenv OPENCLAW_GATEWAY_TOKEN
launchctl getenv OPENCLAW_GATEWAY_PASSWORD
launchctl unsetenv OPENCLAW_GATEWAY_TOKEN
launchctl unsetenv OPENCLAW_GATEWAY_PASSWORD
```

202
docs/zh-CN/cli/gateway.md Normal file
View file

@ -0,0 +1,202 @@
---
read_when:
- 从 CLI 运行 Gateway网关开发或服务器环境
- 调试 Gateway网关认证、绑定模式和连接问题
- 通过 Bonjour 发现 Gateway网关局域网 + tailnet
summary: OpenClaw Gateway网关 CLI`openclaw gateway`)— 运行、查询和发现 Gateway网关
title: gateway
x-i18n:
generated_at: "2026-02-01T19:59:19Z"
model: claude-opus-4-5
provider: pi
source_hash: 054dd48056e4784f153c6511c8eb35b56f239db8d4e629661841a00259e9abbf
source_path: cli/gateway.md
workflow: 14
---
# Gateway网关 CLI
Gateway网关是 OpenClaw 的 WebSocket 服务器(渠道、节点、会话、钩子)。
本页中的子命令位于 `openclaw gateway …` 下。
相关文档:
- [/gateway/bonjour](/gateway/bonjour)
- [/gateway/discovery](/gateway/discovery)
- [/gateway/configuration](/gateway/configuration)
## 运行 Gateway网关运行本地 Gateway网关进程
```bash
openclaw gateway
```
前台运行别名:
```bash
openclaw gateway run
```
注意事项:
- 默认情况下,除非在 `~/.openclaw/openclaw.json` 中设置了 `gateway.mode=local`,否则 Gateway网关会拒绝启动。使用 `--allow-unconfigured` 进行临时/开发运行。
- 在没有认证的情况下绑定到 local loopback 以外的地址会被阻止(安全防护措施)。
- 授权后 `SIGUSR1` 会触发进程内重启(需启用 `commands.restart` 或使用 Gateway网关工具/配置应用/更新)。
- `SIGINT`/`SIGTERM` 处理程序会停止 Gateway网关进程但不会恢复任何自定义终端状态。如果你使用 TUI 或原始模式输入包装 CLI请在退出前恢复终端。
### 选项
- `--port <port>`WebSocket 端口(默认来自配置/环境变量;通常为 `18789`)。
- `--bind <loopback|lan|tailnet|auto|custom>`:监听器绑定模式。
- `--auth <token|password>`:认证模式覆盖。
- `--token <token>`:令牌覆盖(同时为进程设置 `OPENCLAW_GATEWAY_TOKEN`)。
- `--password <password>`:密码覆盖(同时为进程设置 `OPENCLAW_GATEWAY_PASSWORD`)。
- `--tailscale <off|serve|funnel>`:通过 Tailscale 暴露 Gateway网关。
- `--tailscale-reset-on-exit`:关闭时重置 Tailscale serve/funnel 配置。
- `--allow-unconfigured`:允许在配置中没有 `gateway.mode=local` 的情况下启动 Gateway网关。
- `--dev`:如果缺失则创建开发配置和工作区(跳过 BOOTSTRAP.md
- `--reset`:重置开发配置 + 凭据 + 会话 + 工作区(需要 `--dev`)。
- `--force`:启动前终止所选端口上的现有监听器。
- `--verbose`:详细日志。
- `--claude-cli-logs`:仅在控制台显示 claude-cli 日志(并启用其 stdout/stderr
- `--ws-log <auto|full|compact>`WebSocket 日志样式(默认 `auto`)。
- `--compact``--ws-log compact` 的别名。
- `--raw-stream`:将原始模型流事件记录到 jsonl。
- `--raw-stream-path <path>`:原始流 jsonl 路径。
## 查询运行中的 Gateway网关所有查询命令使用 WebSocket RPC。
输出模式:
- 默认人类可读TTY 中带颜色)。
- `--json`:机器可读的 JSON无样式/加载动画)。
- `--no-color`(或 `NO_COLOR=1`):禁用 ANSI 但保持人类可读布局。
共享选项(在支持的命令中):
- `--url <url>`Gateway网关 WebSocket URL。
- `--token <token>`Gateway网关令牌。
- `--password <password>`Gateway网关密码。
- `--timeout <ms>`:超时时间/预算(因命令而异)。
- `--expect-final`:等待"最终"响应(智能体调用)。
### `gateway health`
```bash
openclaw gateway health --url ws://127.0.0.1:18789
```
### `gateway status`
`gateway status` 显示 Gateway网关服务launchd/systemd/schtasks以及可选的 RPC 探测。
```bash
openclaw gateway status
openclaw gateway status --json
```
选项:
- `--url <url>`:覆盖探测 URL。
- `--token <token>`:探测的令牌认证。
- `--password <password>`:探测的密码认证。
- `--timeout <ms>`:探测超时时间(默认 `10000`)。
- `--no-probe`:跳过 RPC 探测(仅查看服务状态)。
- `--deep`:同时扫描系统级服务。
### `gateway probe`
`gateway probe` 是"全面调试"命令。它始终会探测:
- 你配置的远程 Gateway网关如已设置以及
- localhostlocal loopback**即使已配置远程 Gateway网关**。
如果有多个 Gateway网关可达它会全部输出。当你使用隔离的配置文件/端口时(例如救援机器人),支持多个 Gateway网关但大多数安装仍然运行单个 Gateway网关。
```bash
openclaw gateway probe
openclaw gateway probe --json
```
#### 通过 SSH 远程连接Mac 应用对等模式)
macOS 应用的"通过 SSH 远程连接"模式使用本地端口转发,使远程 Gateway网关可能仅绑定到 local loopback可通过 `ws://127.0.0.1:<port>` 访问。
CLI 等效命令:
```bash
openclaw gateway probe --ssh user@gateway-host
```
选项:
- `--ssh <target>``user@host` 或 `user@host:port`(端口默认为 `22`)。
- `--ssh-identity <path>`:身份文件。
- `--ssh-auto`:自动选择第一个发现的 Gateway网关主机作为 SSH 目标(仅限局域网/WAB
配置(可选,用作默认值):
- `gateway.remote.sshTarget`
- `gateway.remote.sshIdentity`
### `gateway call <method>`
底层 RPC 辅助工具。
```bash
openclaw gateway call status
openclaw gateway call logs.tail --params '{"sinceMs": 60000}'
```
## 管理 Gateway网关服务
```bash
openclaw gateway install
openclaw gateway start
openclaw gateway stop
openclaw gateway restart
openclaw gateway uninstall
```
注意事项:
- `gateway install` 支持 `--port`、`--runtime`、`--token`、`--force`、`--json`。
- 生命周期命令接受 `--json` 用于脚本编写。
## 发现 Gateway网关Bonjour
`gateway discover` 扫描 Gateway网关信标`_openclaw-gw._tcp`)。
- 组播 DNS-SD`local.`
- 单播 DNS-SD广域 Bonjour选择一个域名例如`openclaw.internal.`)并设置分离 DNS + DNS 服务器;参见 [/gateway/bonjour](/gateway/bonjour)
只有启用了 Bonjour 发现(默认启用)的 Gateway网关才会广播信标。
广域发现记录包含TXT
- `role`Gateway网关角色提示
- `transport`(传输提示,例如 `gateway`
- `gatewayPort`WebSocket 端口,通常为 `18789`
- `sshPort`SSH 端口;如未指定默认为 `22`
- `tailnetDns`MagicDNS 主机名,如可用)
- `gatewayTls` / `gatewayTlsSha256`TLS 启用 + 证书指纹)
- `cliPath`(可选的远程安装路径提示)
### `gateway discover`
```bash
openclaw gateway discover
```
选项:
- `--timeout <ms>`:每条命令的超时时间(浏览/解析);默认 `2000`
- `--json`:机器可读输出(同时禁用样式/加载动画)。
示例:
```bash
openclaw gateway discover --timeout 4000
openclaw gateway discover --json | jq '.beacons[].wsUrl'
```

28
docs/zh-CN/cli/health.md Normal file
View file

@ -0,0 +1,28 @@
---
read_when:
- 你想快速检查正在运行的 Gateway网关的健康状态
summary: "`openclaw health` 的 CLI 参考(通过 RPC 访问 Gateway网关健康端点"
title: health
x-i18n:
generated_at: "2026-02-01T19:58:57Z"
model: claude-opus-4-5
provider: pi
source_hash: 82a78a5a97123f7a5736699ae8d793592a736f336c5caced9eba06d14d973fd7
source_path: cli/health.md
workflow: 14
---
# `openclaw health`
从正在运行的 Gateway网关获取健康状态。
```bash
openclaw health
openclaw health --json
openclaw health --verbose
```
说明:
- `--verbose` 会运行实时探测,并在配置了多个账号时打印每个账号的耗时。
- 配置了多个智能体时,输出中会包含每个智能体的会话存储信息。

310
docs/zh-CN/cli/hooks.md Normal file
View file

@ -0,0 +1,310 @@
---
read_when:
- 你想管理智能体钩子
- 你想安装或更新钩子
summary: "`openclaw hooks` 的 CLI 参考(智能体钩子)"
title: hooks
x-i18n:
generated_at: "2026-02-01T19:59:18Z"
model: claude-opus-4-5
provider: pi
source_hash: e2032e61ff4b9135cb2708d92eb7889ac627b85a5fc153e3d5b84265f7bd7bc6
source_path: cli/hooks.md
workflow: 14
---
# `openclaw hooks`
管理智能体钩子(用于 `/new`、`/reset` 等命令以及 Gateway网关启动的事件驱动自动化
相关内容:
- 钩子:[钩子](/hooks)
- 插件钩子:[插件](/plugin#plugin-hooks)
## 列出所有钩子
```bash
openclaw hooks list
```
列出从工作区、托管和内置目录中发现的所有钩子。
**选项:**
- `--eligible`:仅显示符合条件的钩子(需求已满足)
- `--json`:以 JSON 格式输出
- `-v, --verbose`:显示详细信息,包括缺失的需求
**示例输出:**
```
Hooks (4/4 ready)
Ready:
🚀 boot-md ✓ - Run BOOT.md on gateway startup
📝 command-logger ✓ - Log all command events to a centralized audit file
💾 session-memory ✓ - Save session context to memory when /new command is issued
😈 soul-evil ✓ - Swap injected SOUL content during a purge window or by random chance
```
**示例(详细模式):**
```bash
openclaw hooks list --verbose
```
显示不符合条件的钩子缺失的需求。
**示例JSON**
```bash
openclaw hooks list --json
```
返回结构化 JSON 以供程序化使用。
## 获取钩子信息
```bash
openclaw hooks info <name>
```
显示特定钩子的详细信息。
**参数:**
- `<name>`:钩子名称(例如 `session-memory`
**选项:**
- `--json`:以 JSON 格式输出
**示例:**
```bash
openclaw hooks info session-memory
```
**输出:**
```
💾 session-memory ✓ Ready
Save session context to memory when /new command is issued
Details:
Source: openclaw-bundled
Path: /path/to/openclaw/hooks/bundled/session-memory/HOOK.md
Handler: /path/to/openclaw/hooks/bundled/session-memory/handler.ts
Homepage: https://docs.openclaw.ai/hooks#session-memory
Events: command:new
Requirements:
Config: ✓ workspace.dir
```
## 检查钩子资格
```bash
openclaw hooks check
```
显示钩子资格状态摘要(就绪与未就绪的数量)。
**选项:**
- `--json`:以 JSON 格式输出
**示例输出:**
```
Hooks Status
Total hooks: 4
Ready: 4
Not ready: 0
```
## 启用钩子
```bash
openclaw hooks enable <name>
```
通过将特定钩子添加到配置文件(`~/.openclaw/config.json`)来启用它。
**注意:** 由插件管理的钩子在 `openclaw hooks list` 中显示为 `plugin:<id>`,无法在此处启用/禁用。请改为启用/禁用对应的插件。
**参数:**
- `<name>`:钩子名称(例如 `session-memory`
**示例:**
```bash
openclaw hooks enable session-memory
```
**输出:**
```
✓ Enabled hook: 💾 session-memory
```
**执行操作:**
- 检查钩子是否存在且符合条件
- 在配置中更新 `hooks.internal.entries.<name>.enabled = true`
- 将配置保存到磁盘
**启用后:**
- 重启 Gateway网关以重新加载钩子macOS 上重启菜单栏应用,或在开发环境中重启 Gateway网关进程
## 禁用钩子
```bash
openclaw hooks disable <name>
```
通过更新配置来禁用特定钩子。
**参数:**
- `<name>`:钩子名称(例如 `command-logger`
**示例:**
```bash
openclaw hooks disable command-logger
```
**输出:**
```
⏸ Disabled hook: 📝 command-logger
```
**禁用后:**
- 重启 Gateway网关以重新加载钩子
## 安装钩子
```bash
openclaw hooks install <path-or-spec>
```
从本地文件夹/归档包或 npm 安装钩子包。
**执行操作:**
- 将钩子包复制到 `~/.openclaw/hooks/<id>`
- 在 `hooks.internal.entries.*` 中启用已安装的钩子
- 在 `hooks.internal.installs` 下记录安装信息
**选项:**
- `-l, --link`:链接本地目录而非复制(将其添加到 `hooks.internal.load.extraDirs`
**支持的归档格式:** `.zip`、`.tgz`、`.tar.gz`、`.tar`
**示例:**
```bash
# 本地目录
openclaw hooks install ./my-hook-pack
# 本地归档包
openclaw hooks install ./my-hook-pack.zip
# NPM 包
openclaw hooks install @openclaw/my-hook-pack
# 链接本地目录而非复制
openclaw hooks install -l ./my-hook-pack
```
## 更新钩子
```bash
openclaw hooks update <id>
openclaw hooks update --all
```
更新已安装的钩子包(仅限 npm 安装)。
**选项:**
- `--all`:更新所有已跟踪的钩子包
- `--dry-run`:显示将要更改的内容而不实际写入
## 内置钩子
### session-memory
在你执行 `/new` 时将会话上下文保存到记忆中。
**启用:**
```bash
openclaw hooks enable session-memory
```
**输出:** `~/.openclaw/workspace/memory/YYYY-MM-DD-slug.md`
**参见:** [session-memory 文档](/hooks#session-memory)
### command-logger
将所有命令事件记录到集中审计文件中。
**启用:**
```bash
openclaw hooks enable command-logger
```
**输出:** `~/.openclaw/logs/commands.log`
**查看日志:**
```bash
# 最近的命令
tail -n 20 ~/.openclaw/logs/commands.log
# 格式化输出
cat ~/.openclaw/logs/commands.log | jq .
# 按操作过滤
grep '"action":"new"' ~/.openclaw/logs/commands.log | jq .
```
**参见:** [command-logger 文档](/hooks#command-logger)
### soul-evil
在清除窗口期间或随机情况下,将注入的 `SOUL.md` 内容替换为 `SOUL_EVIL.md`
**启用:**
```bash
openclaw hooks enable soul-evil
```
**参见:** [SOUL Evil 钩子](/hooks/soul-evil)
### boot-md
在 Gateway网关启动时渠道启动之后运行 `BOOT.md`
**事件**`gateway:startup`
**启用**
```bash
openclaw hooks enable boot-md
```
**参见:** [boot-md 文档](/hooks#boot-md)

1033
docs/zh-CN/cli/index.md Normal file

File diff suppressed because it is too large Load diff

31
docs/zh-CN/cli/logs.md Normal file
View file

@ -0,0 +1,31 @@
---
read_when:
- 需要远程查看 Gateway网关日志无需 SSH
- 需要 JSON 格式的日志行以供工具使用
summary: 通过 RPC 查看 Gateway网关日志的 `openclaw logs` CLI 参考
title: logs
x-i18n:
generated_at: "2026-02-01T20:21:08Z"
model: claude-opus-4-5
provider: pi
source_hash: 911a57f0f3b78412c26312f7bf87a5a26418ab7b74e5e2eb40f16edefb6c6b8e
source_path: cli/logs.md
workflow: 14
---
# `openclaw logs`
通过 RPC 实时查看 Gateway网关文件日志支持远程模式
相关内容:
- 日志概述:[日志](/logging)
## 示例
```bash
openclaw logs
openclaw logs --follow
openclaw logs --json
openclaw logs --limit 500
```

52
docs/zh-CN/cli/memory.md Normal file
View file

@ -0,0 +1,52 @@
---
read_when:
- 你想要索引或搜索语义记忆
- 你正在调试记忆可用性或索引问题
summary: "`openclaw memory`status/index/search的 CLI 参考"
title: memory
x-i18n:
generated_at: "2026-02-01T20:21:11Z"
model: claude-opus-4-5
provider: pi
source_hash: 95a9e94306f95be2218a909be59be5bbaa5d31322b71b23564c71a89c3a3941a
source_path: cli/memory.md
workflow: 14
---
# `openclaw memory`
管理语义记忆的索引和搜索。
由活跃的记忆插件提供(默认:`memory-core`;设置 `plugins.slots.memory = "none"` 可禁用)。
相关内容:
- 记忆概念:[记忆](/concepts/memory)
- 插件:[插件](/plugins)
## 示例
```bash
openclaw memory status
openclaw memory status --deep
openclaw memory status --deep --index
openclaw memory status --deep --index --verbose
openclaw memory index
openclaw memory index --verbose
openclaw memory search "release checklist"
openclaw memory status --agent main
openclaw memory index --agent main --verbose
```
## 选项
通用选项:
- `--agent <id>`:限定到单个智能体(默认:所有已配置的智能体)。
- `--verbose`:在探测和索引期间输出详细日志。
说明:
- `memory status --deep` 探测向量存储和嵌入模型的可用性。
- `memory status --deep --index` 在存储有未同步变更时运行重新索引。
- `memory index --verbose` 打印每个阶段的详细信息(提供商、模型、数据源、批处理活动)。
- `memory status` 包含通过 `memorySearch.extraPaths` 配置的所有额外路径。

246
docs/zh-CN/cli/message.md Normal file
View file

@ -0,0 +1,246 @@
---
read_when:
- 添加或修改消息 CLI 操作
- 更改出站渠道行为
summary: "`openclaw message`(发送 + 渠道操作)的 CLI 参考"
title: message
x-i18n:
generated_at: "2026-02-01T20:21:30Z"
model: claude-opus-4-5
provider: pi
source_hash: 35159baf1ef7136252e3ab1e5e03881ebc4196dd43425e2319a39306ced7f48c
source_path: cli/message.md
workflow: 14
---
# `openclaw message`
用于发送消息和渠道操作的单一出站命令
Discord/Google Chat/Slack/Mattermost插件/Telegram/WhatsApp/Signal/iMessage/MS Teams
## 用法
```
openclaw message <subcommand> [flags]
```
渠道选择:
- 如果配置了多个渠道,则必须指定 `--channel`
- 如果只配置了一个渠道,则该渠道为默认值。
- 可选值:`whatsapp|telegram|discord|googlechat|slack|mattermost|signal|imessage|msteams`Mattermost 需要插件)
目标格式(`--target`
- WhatsAppE.164 或群组 JID
- Telegram聊天 ID 或 `@username`
- Discord`channel:<id>` 或 `user:<id>`(或 `<@id>` 提及;纯数字 ID 被视为频道)
- Google Chat`spaces/<spaceId>` 或 `users/<userId>`
- Slack`channel:<id>` 或 `user:<id>`(接受纯频道 ID
- Mattermost插件`channel:<id>`、`user:<id>` 或 `@username`(纯 ID 被视为频道)
- Signal`+E.164`、`group:<id>`、`signal:+E.164`、`signal:group:<id>` 或 `username:<name>`/`u:<name>`
- iMessage句柄、`chat_id:<id>`、`chat_guid:<guid>` 或 `chat_identifier:<id>`
- MS Teams会话 ID`19:...@thread.tacv2`)或 `conversation:<id>``user:<aad-object-id>`
名称查找:
- 对于支持的提供商Discord/Slack 等),如 `Help``#help` 之类的频道名称会通过目录缓存进行解析。
- 缓存未命中时如果提供商支持OpenClaw 将尝试实时目录查找。
## 通用标志
- `--channel <name>`
- `--account <id>`
- `--target <dest>`(用于 send/poll/read 等的目标渠道或用户)
- `--targets <name>`(可重复;仅限广播)
- `--json`
- `--dry-run`
- `--verbose`
## 操作
### 核心
- `send`
- 渠道WhatsApp/Telegram/Discord/Google Chat/Slack/Mattermost插件/Signal/iMessage/MS Teams
- 必需:`--target`,以及 `--message``--media`
- 可选:`--media`、`--reply-to`、`--thread-id`、`--gif-playback`
- 仅限 Telegram`--buttons`(需要 `channels.telegram.capabilities.inlineButtons` 以启用)
- 仅限 Telegram`--thread-id`(论坛主题 ID
- 仅限 Slack`--thread-id`(线程时间戳;`--reply-to` 使用相同字段)
- 仅限 WhatsApp`--gif-playback`
- `poll`
- 渠道WhatsApp/Discord/MS Teams
- 必需:`--target`、`--poll-question`、`--poll-option`(可重复)
- 可选:`--poll-multi`
- 仅限 Discord`--poll-duration-hours`、`--message`
- `react`
- 渠道Discord/Google Chat/Slack/Telegram/WhatsApp/Signal
- 必需:`--message-id`、`--target`
- 可选:`--emoji`、`--remove`、`--participant`、`--from-me`、`--target-author`、`--target-author-uuid`
- 注意:`--remove` 需要 `--emoji`(省略 `--emoji` 可清除自己的表情回应(如果支持);参见 /tools/reactions
- 仅限 WhatsApp`--participant`、`--from-me`
- Signal 群组表情回应:需要 `--target-author``--target-author-uuid`
- `reactions`
- 渠道Discord/Google Chat/Slack
- 必需:`--message-id`、`--target`
- 可选:`--limit`
- `read`
- 渠道Discord/Slack
- 必需:`--target`
- 可选:`--limit`、`--before`、`--after`
- 仅限 Discord`--around`
- `edit`
- 渠道Discord/Slack
- 必需:`--message-id`、`--message`、`--target`
- `delete`
- 渠道Discord/Slack/Telegram
- 必需:`--message-id`、`--target`
- `pin` / `unpin`
- 渠道Discord/Slack
- 必需:`--message-id`、`--target`
- `pins`(列表)
- 渠道Discord/Slack
- 必需:`--target`
- `permissions`
- 渠道Discord
- 必需:`--target`
- `search`
- 渠道Discord
- 必需:`--guild-id`、`--query`
- 可选:`--channel-id`、`--channel-ids`(可重复)、`--author-id`、`--author-ids`(可重复)、`--limit`
### 线程
- `thread create`
- 渠道Discord
- 必需:`--thread-name`、`--target`(频道 ID
- 可选:`--message-id`、`--auto-archive-min`
- `thread list`
- 渠道Discord
- 必需:`--guild-id`
- 可选:`--channel-id`、`--include-archived`、`--before`、`--limit`
- `thread reply`
- 渠道Discord
- 必需:`--target`(线程 ID、`--message`
- 可选:`--media`、`--reply-to`
### 表情符号
- `emoji list`
- Discord`--guild-id`
- Slack无需额外标志
- `emoji upload`
- 渠道Discord
- 必需:`--guild-id`、`--emoji-name`、`--media`
- 可选:`--role-ids`(可重复)
### 贴纸
- `sticker send`
- 渠道Discord
- 必需:`--target`、`--sticker-id`(可重复)
- 可选:`--message`
- `sticker upload`
- 渠道Discord
- 必需:`--guild-id`、`--sticker-name`、`--sticker-desc`、`--sticker-tags`、`--media`
### 角色 / 频道 / 成员 / 语音
- `role info`Discord`--guild-id`
- `role add` / `role remove`Discord`--guild-id`、`--user-id`、`--role-id`
- `channel info`Discord`--target`
- `channel list`Discord`--guild-id`
- `member info`Discord/Slack`--user-id`Discord 还需要 `--guild-id`
- `voice status`Discord`--guild-id`、`--user-id`
### 事件
- `event list`Discord`--guild-id`
- `event create`Discord`--guild-id`、`--event-name`、`--start-time`
- 可选:`--end-time`、`--desc`、`--channel-id`、`--location`、`--event-type`
### 管理Discord
- `timeout``--guild-id`、`--user-id`(可选 `--duration-min``--until`;两者都省略则清除超时)
- `kick``--guild-id`、`--user-id`+ `--reason`
- `ban``--guild-id`、`--user-id`+ `--delete-days`、`--reason`
- `timeout` 也支持 `--reason`
### 广播
- `broadcast`
- 渠道:任何已配置的渠道;使用 `--channel all` 可针对所有提供商
- 必需:`--targets`(可重复)
- 可选:`--message`、`--media`、`--dry-run`
## 示例
发送 Discord 回复:
```
openclaw message send --channel discord \
--target channel:123 --message "hi" --reply-to 456
```
创建 Discord 投票:
```
openclaw message poll --channel discord \
--target channel:123 \
--poll-question "Snack?" \
--poll-option Pizza --poll-option Sushi \
--poll-multi --poll-duration-hours 48
```
发送 Teams 主动消息:
```
openclaw message send --channel msteams \
--target conversation:19:abc@thread.tacv2 --message "hi"
```
创建 Teams 投票:
```
openclaw message poll --channel msteams \
--target conversation:19:abc@thread.tacv2 \
--poll-question "Lunch?" \
--poll-option Pizza --poll-option Sushi
```
在 Slack 中添加表情回应:
```
openclaw message react --channel slack \
--target C123 --message-id 456 --emoji "✅"
```
在 Signal 群组中添加表情回应:
```
openclaw message react --channel signal \
--target signal:group:abc123 --message-id 1737630212345 \
--emoji "✅" --target-author-uuid 123e4567-e89b-12d3-a456-426614174000
```
发送 Telegram 内联按钮:
```
openclaw message send --channel telegram --target @mychat --message "Choose:" \
--buttons '[ [{"text":"Yes","callback_data":"cmd:yes"}], [{"text":"No","callback_data":"cmd:no"}] ]'
```

85
docs/zh-CN/cli/models.md Normal file
View file

@ -0,0 +1,85 @@
---
read_when:
- 你想更改默认模型或查看提供商认证状态
- 你想扫描可用的模型/提供商并调试认证配置
summary: "`openclaw models` 的 CLI 参考status/list/set/scan、别名、回退、认证"
title: models
x-i18n:
generated_at: "2026-02-01T20:21:16Z"
model: claude-opus-4-5
provider: pi
source_hash: 923b6ffc7de382ba25bc6e699f0515607e74877b39f2136ccdba2d99e1b1e9c3
source_path: cli/models.md
workflow: 14
---
# `openclaw models`
模型发现、扫描和配置(默认模型、回退、认证配置)。
相关内容:
- 提供商 + 模型:[模型](/providers/models)
- 提供商认证设置:[快速开始](/start/getting-started)
## 常用命令
```bash
openclaw models status
openclaw models list
openclaw models set <model-or-alias>
openclaw models scan
```
`openclaw models status` 显示已解析的默认模型/回退配置以及认证概览。
当提供商使用快照可用时OAuth/令牌状态部分会包含提供商使用头信息。
添加 `--probe` 可对每个已配置的提供商配置运行实时认证探测。
探测会发送真实请求(可能消耗令牌并触发速率限制)。
使用 `--agent <id>` 可检查已配置智能体的模型/认证状态。省略时,
命令会使用 `OPENCLAW_AGENT_DIR`/`PI_CODING_AGENT_DIR`(如已设置),否则使用
已配置的默认智能体。
注意事项:
- `models set <model-or-alias>` 接受 `provider/model` 或别名。
- 模型引用通过在**第一个** `/` 处拆分来解析。如果模型 ID 包含 `/`OpenRouter 风格),需包含提供商前缀(示例:`openrouter/moonshotai/kimi-k2`)。
- 如果省略提供商OpenClaw 会将输入视为别名或**默认提供商**的模型(仅在模型 ID 不包含 `/` 时有效)。
### `models status`
选项:
- `--json`
- `--plain`
- `--check`(退出码 1=已过期/缺失2=即将过期)
- `--probe`(对已配置的认证配置进行实时探测)
- `--probe-provider <name>`(探测单个提供商)
- `--probe-profile <id>`(可重复或逗号分隔的配置 ID
- `--probe-timeout <ms>`
- `--probe-concurrency <n>`
- `--probe-max-tokens <n>`
- `--agent <id>`(已配置的智能体 ID覆盖 `OPENCLAW_AGENT_DIR`/`PI_CODING_AGENT_DIR`
## 别名 + 回退
```bash
openclaw models aliases list
openclaw models fallbacks list
```
## 认证配置
```bash
openclaw models auth add
openclaw models auth login --provider <id>
openclaw models auth setup-token
openclaw models auth paste-token
```
`models auth login` 运行提供商插件的认证流程OAuth/API 密钥)。使用
`openclaw plugins list` 查看已安装的提供商。
注意事项:
- `setup-token` 会提示输入 setup-token 值(在任意机器上使用 `claude setup-token` 生成)。
- `paste-token` 接受在其他地方或通过自动化生成的令牌字符串。

115
docs/zh-CN/cli/node.md Normal file
View file

@ -0,0 +1,115 @@
---
read_when:
- 运行无头节点主机
- 为 system.run 配对非 macOS 节点
summary: "`openclaw node`(无头节点主机)的 CLI 参考"
title: node
x-i18n:
generated_at: "2026-02-01T20:21:18Z"
model: claude-opus-4-5
provider: pi
source_hash: a8b1a57712663e2285c9ecd306fe57d067eb3e6820d7d8aec650b41b022d995a
source_path: cli/node.md
workflow: 14
---
# `openclaw node`
运行一个**无头节点主机**,连接到 Gateway网关 WebSocket 并在本机上暴露
`system.run` / `system.which`
## 为什么使用节点主机?
当你希望智能体**在网络中的其他机器上运行命令**,而无需在那些机器上安装完整的 macOS 伴侣应用时,可以使用节点主机。
常见用例:
- 在远程 Linux/Windows 机器上运行命令构建服务器、实验室机器、NAS
- 在 Gateway网关上保持执行**沙箱隔离**,但将已批准的运行委派给其他主机。
- 为自动化或 CI 节点提供轻量级、无头的执行目标。
执行仍受**执行审批**和节点主机上的按智能体白名单保护,因此你可以保持命令访问的范围明确可控。
## 浏览器代理(零配置)
如果节点上的 `browser.enabled` 未被禁用,节点主机会自动通告浏览器代理。这使智能体无需额外配置即可在该节点上使用浏览器自动化。
如需在节点上禁用:
```json5
{
nodeHost: {
browserProxy: {
enabled: false,
},
},
}
```
## 前台运行
```bash
openclaw node run --host <gateway-host> --port 18789
```
选项:
- `--host <host>`Gateway网关 WebSocket 主机(默认:`127.0.0.1`
- `--port <port>`Gateway网关 WebSocket 端口(默认:`18789`
- `--tls`:为 Gateway网关连接使用 TLS
- `--tls-fingerprint <sha256>`:预期的 TLS 证书指纹sha256
- `--node-id <id>`:覆盖节点 ID清除配对令牌
- `--display-name <name>`:覆盖节点显示名称
## 服务(后台运行)
将无头节点主机安装为用户服务。
```bash
openclaw node install --host <gateway-host> --port 18789
```
选项:
- `--host <host>`Gateway网关 WebSocket 主机(默认:`127.0.0.1`
- `--port <port>`Gateway网关 WebSocket 端口(默认:`18789`
- `--tls`:为 Gateway网关连接使用 TLS
- `--tls-fingerprint <sha256>`:预期的 TLS 证书指纹sha256
- `--node-id <id>`:覆盖节点 ID清除配对令牌
- `--display-name <name>`:覆盖节点显示名称
- `--runtime <runtime>`:服务运行时(`node` 或 `bun`
- `--force`:如果已安装则重新安装/覆盖
管理服务:
```bash
openclaw node status
openclaw node stop
openclaw node restart
openclaw node uninstall
```
使用 `openclaw node run` 进行前台节点主机运行(无服务)。
服务命令支持 `--json` 以获取机器可读输出。
## 配对
首次连接会在 Gateway网关上创建一个待处理的节点配对请求。
通过以下方式批准:
```bash
openclaw nodes pending
openclaw nodes approve <requestId>
```
节点主机将其节点 ID、令牌、显示名称和 Gateway网关连接信息存储在
`~/.openclaw/node.json` 中。
## 执行审批
`system.run` 受本地执行审批控制:
- `~/.openclaw/exec-approvals.json`
- [执行审批](/tools/exec-approvals)
- `openclaw approvals --node <id|name|ip>`(从 Gateway网关编辑

79
docs/zh-CN/cli/nodes.md Normal file
View file

@ -0,0 +1,79 @@
---
read_when:
- 正在管理配对节点(摄像头、屏幕、画布)
- 需要批准请求或调用节点命令
summary: 管理配对节点(列表/状态/批准/调用,摄像头/画布/屏幕)的 `openclaw nodes` CLI 参考
title: nodes
x-i18n:
generated_at: "2026-02-01T20:21:19Z"
model: claude-opus-4-5
provider: pi
source_hash: 23da6efdd659a82dbbc4afd18eb4ab1020a2892f69c28d610f912c8a799f734c
source_path: cli/nodes.md
workflow: 14
---
# `openclaw nodes`
管理配对节点(设备)并调用节点功能。
相关内容:
- 节点概述:[节点](/nodes)
- 摄像头:[摄像头节点](/nodes/camera)
- 图像:[图像节点](/nodes/images)
常用选项:
- `--url`、`--token`、`--timeout`、`--json`
## 常用命令
```bash
openclaw nodes list
openclaw nodes list --connected
openclaw nodes list --last-connected 24h
openclaw nodes pending
openclaw nodes approve <requestId>
openclaw nodes status
openclaw nodes status --connected
openclaw nodes status --last-connected 24h
```
`nodes list` 输出待处理/已配对的表格。已配对的行包含最近一次连接的时间间隔Last Connect
使用 `--connected` 仅显示当前已连接的节点。使用 `--last-connected <duration>` 筛选在指定时间段内连接过的节点(例如 `24h`、`7d`)。
## 调用 / 运行
```bash
openclaw nodes invoke --node <id|name|ip> --command <command> --params <json>
openclaw nodes run --node <id|name|ip> <command...>
openclaw nodes run --raw "git status"
openclaw nodes run --agent main --node <id|name|ip> --raw "git status"
```
调用标志:
- `--params <json>`JSON 对象字符串(默认 `{}`)。
- `--invoke-timeout <ms>`:节点调用超时时间(默认 `15000`)。
- `--idempotency-key <key>`:可选的幂等键。
### Exec 风格的默认行为
`nodes run` 模拟模型的 exec 行为(默认值 + 审批):
- 读取 `tools.exec.*`(以及 `agents.list[].tools.exec.*` 的覆盖配置)。
- 在调用 `system.run` 之前使用 exec 审批(`exec.approval.request`)。
- 当设置了 `tools.exec.node` 时,可以省略 `--node`
- 需要一个声明支持 `system.run` 的节点macOS 伴侣应用或无头节点主机)。
标志:
- `--cwd <path>`:工作目录。
- `--env <key=val>`:环境变量覆盖(可重复使用)。
- `--command-timeout <ms>`:命令超时时间。
- `--invoke-timeout <ms>`:节点调用超时时间(默认 `30000`)。
- `--needs-screen-recording`:要求屏幕录制权限。
- `--raw <command>`:运行 shell 字符串(`/bin/sh -lc` 或 `cmd.exe /c`)。
- `--agent <id>`:智能体范围的审批/白名单(默认为已配置的智能体)。
- `--ask <off|on-miss|always>`、`--security <deny|allowlist|full>`:覆盖选项。

36
docs/zh-CN/cli/onboard.md Normal file
View file

@ -0,0 +1,36 @@
---
read_when:
- 你想要通过引导式设置配置 Gateway网关、工作区、认证、渠道和 Skills
summary: "`openclaw onboard`(交互式新手引导向导)的 CLI 参考"
title: onboard
x-i18n:
generated_at: "2026-02-01T20:21:15Z"
model: claude-opus-4-5
provider: pi
source_hash: a661049a6983233986a880a68440a3bcc6869ee2c4c6f5e9f3ab8ff973e22f60
source_path: cli/onboard.md
workflow: 14
---
# `openclaw onboard`
交互式新手引导向导(本地或远程 Gateway网关设置
相关内容:
- 向导指南:[新手引导](/start/onboarding)
## 示例
```bash
openclaw onboard
openclaw onboard --flow quickstart
openclaw onboard --flow manual
openclaw onboard --mode remote --remote-url ws://gateway-host:18789
```
流程说明:
- `quickstart`:最少提示,自动生成 Gateway网关令牌。
- `manual`:完整的端口/绑定/认证提示(`advanced` 的别名)。
- 最快开始聊天的方式:`openclaw dashboard`(控制台 UI无需渠道设置

28
docs/zh-CN/cli/pairing.md Normal file
View file

@ -0,0 +1,28 @@
---
read_when:
- 你正在使用配对模式的私信功能,需要批准发送者
summary: "`openclaw pairing`(批准/列出配对请求)的 CLI 参考"
title: pairing
x-i18n:
generated_at: "2026-02-01T20:21:19Z"
model: claude-opus-4-5
provider: pi
source_hash: e0bc9707294463c95d13e0deb67d834cfad6a105ab44baf4c25592e5de65ddf5
source_path: cli/pairing.md
workflow: 14
---
# `openclaw pairing`
批准或检查私信配对请求(适用于支持配对的渠道)。
相关内容:
- 配对流程:[配对](/start/pairing)
## 命令
```bash
openclaw pairing list whatsapp
openclaw pairing approve whatsapp <code> --notify
```

66
docs/zh-CN/cli/plugins.md Normal file
View file

@ -0,0 +1,66 @@
---
read_when:
- 你想安装或管理进程内 Gateway网关插件
- 你想调试插件加载失败问题
summary: "`openclaw plugins` 的 CLI 参考list、install、enable/disable、doctor"
title: plugins
x-i18n:
generated_at: "2026-02-01T20:21:23Z"
model: claude-opus-4-5
provider: pi
source_hash: c6bf76b1e766b912ec30a0101d455151c88f1a778bffa121cdd1d0b4fbe73e1c
source_path: cli/plugins.md
workflow: 14
---
# `openclaw plugins`
管理 Gateway网关插件/扩展(进程内加载)。
相关内容:
- 插件系统:[插件](/plugin)
- 插件清单 + schema[插件清单](/plugins/manifest)
- 安全加固:[安全](/gateway/security)
## 命令
```bash
openclaw plugins list
openclaw plugins info <id>
openclaw plugins enable <id>
openclaw plugins disable <id>
openclaw plugins doctor
openclaw plugins update <id>
openclaw plugins update --all
```
内置插件随 OpenClaw 一起分发,但默认处于禁用状态。使用 `plugins enable` 来激活它们。
所有插件必须附带一个 `openclaw.plugin.json` 文件,其中包含内联 JSON Schema`configSchema`,即使为空也需要)。缺失或无效的清单或 schema 会导致插件无法加载,并使配置验证失败。
### 安装
```bash
openclaw plugins install <path-or-spec>
```
安全提示:安装插件等同于运行代码,请优先使用固定版本。
支持的归档格式:`.zip`、`.tgz`、`.tar.gz`、`.tar`。
使用 `--link` 可避免复制本地目录(会添加到 `plugins.load.paths`
```bash
openclaw plugins install -l ./my-plugin
```
### 更新
```bash
openclaw plugins update <id>
openclaw plugins update --all
openclaw plugins update <id> --dry-run
```
更新仅适用于从 npm 安装的插件(在 `plugins.installs` 中跟踪)。

24
docs/zh-CN/cli/reset.md Normal file
View file

@ -0,0 +1,24 @@
---
read_when:
- 你想在保留 CLI 安装的同时清除本地状态
- 你想预览哪些内容会被移除
summary: "`openclaw reset`(重置本地状态/配置)的 CLI 参考"
title: reset
x-i18n:
generated_at: "2026-02-01T20:21:22Z"
model: claude-opus-4-5
provider: pi
source_hash: 08afed5830f892e07d6e2e167f09aaf2d79fd5b2ba2a26a65dca857ebdbf873c
source_path: cli/reset.md
workflow: 14
---
# `openclaw reset`
重置本地配置/状态(保留 CLI 安装)。
```bash
openclaw reset
openclaw reset --dry-run
openclaw reset --scope config+creds+sessions --yes --non-interactive
```

158
docs/zh-CN/cli/sandbox.md Normal file
View file

@ -0,0 +1,158 @@
---
read_when: 你正在管理沙箱容器或调试沙箱/工具策略行为。
status: active
summary: 管理沙箱容器并检查生效的沙箱策略
title: Sandbox CLI
x-i18n:
generated_at: "2026-02-01T20:21:35Z"
model: claude-opus-4-5
provider: pi
source_hash: 6e1186f26c77e188206ce5e198ab624d6b38bc7bb7c06e4d2281b6935c39e347
source_path: cli/sandbox.md
workflow: 14
---
# Sandbox CLI
管理基于 Docker 的沙箱容器,用于隔离智能体执行。
## 概述
OpenClaw 可以在隔离的 Docker 容器中运行智能体以确保安全性。`sandbox` 命令帮助你管理这些容器,尤其是在更新或配置变更之后。
## 命令
### `openclaw sandbox explain`
检查**生效的**沙箱模式/作用域/工作区访问权限、沙箱工具策略以及提权门控(附带修复建议的配置键路径)。
```bash
openclaw sandbox explain
openclaw sandbox explain --session agent:main:main
openclaw sandbox explain --agent work
openclaw sandbox explain --json
```
### `openclaw sandbox list`
列出所有沙箱容器及其状态和配置。
```bash
openclaw sandbox list
openclaw sandbox list --browser # 仅列出浏览器容器
openclaw sandbox list --json # JSON 输出
```
**输出包括:**
- 容器名称和状态(运行中/已停止)
- Docker 镜像及其是否与配置匹配
- 存在时间(自创建以来的时长)
- 空闲时间(自上次使用以来的时长)
- 关联的会话/智能体
### `openclaw sandbox recreate`
移除沙箱容器,以便使用更新的镜像/配置强制重新创建。
```bash
openclaw sandbox recreate --all # 重新创建所有容器
openclaw sandbox recreate --session main # 指定会话
openclaw sandbox recreate --agent mybot # 指定智能体
openclaw sandbox recreate --browser # 仅浏览器容器
openclaw sandbox recreate --all --force # 跳过确认提示
```
**选项:**
- `--all`:重新创建所有沙箱容器
- `--session <key>`:重新创建指定会话的容器
- `--agent <id>`:重新创建指定智能体的容器
- `--browser`:仅重新创建浏览器容器
- `--force`:跳过确认提示
**重要提示:** 容器会在智能体下次使用时自动重新创建。
## 使用场景
### 更新 Docker 镜像后
```bash
# 拉取新镜像
docker pull openclaw-sandbox:latest
docker tag openclaw-sandbox:latest openclaw-sandbox:bookworm-slim
# 更新配置以使用新镜像
# 编辑配置agents.defaults.sandbox.docker.image或 agents.list[].sandbox.docker.image
# 重新创建容器
openclaw sandbox recreate --all
```
### 更改沙箱配置后
```bash
# 编辑配置agents.defaults.sandbox.*(或 agents.list[].sandbox.*
# 重新创建以应用新配置
openclaw sandbox recreate --all
```
### 更改 setupCommand 后
```bash
openclaw sandbox recreate --all
# 或仅针对某个智能体:
openclaw sandbox recreate --agent family
```
### 仅针对特定智能体
```bash
# 仅更新某个智能体的容器
openclaw sandbox recreate --agent alfred
```
## 为什么需要这样做?
**问题:** 当你更新沙箱 Docker 镜像或配置时:
- 现有容器会继续使用旧设置运行
- 容器仅在空闲 24 小时后才会被清理
- 经常使用的智能体会无限期地保持旧容器运行
**解决方案:** 使用 `openclaw sandbox recreate` 强制移除旧容器。它们会在下次需要时自动使用当前设置重新创建。
提示:建议使用 `openclaw sandbox recreate` 而非手动执行 `docker rm`。它使用 Gateway网关的容器命名规则避免在作用域/会话键发生变化时出现不匹配问题。
## 配置
沙箱设置位于 `~/.openclaw/openclaw.json` 中的 `agents.defaults.sandbox` 下(按智能体覆盖的配置放在 `agents.list[].sandbox` 中):
```jsonc
{
"agents": {
"defaults": {
"sandbox": {
"mode": "all", // off, non-main, all
"scope": "agent", // session, agent, shared
"docker": {
"image": "openclaw-sandbox:bookworm-slim",
"containerPrefix": "openclaw-sbx-",
// ... 更多 Docker 选项
},
"prune": {
"idleHours": 24, // 空闲 24 小时后自动清理
"maxAgeDays": 7, // 7 天后自动清理
},
},
},
},
}
```
## 另请参阅
- [沙箱文档](/gateway/sandboxing)
- [智能体配置](/concepts/agent-workspace)
- [Doctor 命令](/gateway/doctor) - 检查沙箱设置

View file

@ -0,0 +1,33 @@
---
read_when:
- 想要对配置/状态进行快速安全审计
- 想要应用安全的"修复"建议chmod、收紧默认值
summary: 审计和修复常见安全隐患的 `openclaw security` CLI 参考
title: security
x-i18n:
generated_at: "2026-02-01T20:21:24Z"
model: claude-opus-4-5
provider: pi
source_hash: 19705b0fff848fa6f302b4ed09b7660c64e09048dba517c7f6a833d2db40bebf
source_path: cli/security.md
workflow: 14
---
# `openclaw security`
安全工具(审计 + 可选修复)。
相关内容:
- 安全指南:[安全](/gateway/security)
## 审计
```bash
openclaw security audit
openclaw security audit --deep
openclaw security audit --fix
```
当多个私信发送者共享主会话时,审计会发出警告,并建议共享收件箱使用 `session.dmScope="per-channel-peer"`(多账户渠道则使用 `per-account-channel-peer`)。
审计还会在小模型(`<=300B`)未启用沙箱且启用了 web/browser 工具时发出警告。

View file

@ -0,0 +1,23 @@
---
read_when:
- 你想列出已存储的会话并查看近期活动
summary: "`openclaw sessions`(列出已存储的会话及使用情况)的 CLI 参考"
title: sessions
x-i18n:
generated_at: "2026-02-01T20:21:25Z"
model: claude-opus-4-5
provider: pi
source_hash: d8866ef166c0dea5e8d691bb62171298694935ae0771a46fada537774dadfb32
source_path: cli/sessions.md
workflow: 14
---
# `openclaw sessions`
列出已存储的对话会话。
```bash
openclaw sessions
openclaw sessions --active 120
openclaw sessions --json
```

36
docs/zh-CN/cli/setup.md Normal file
View file

@ -0,0 +1,36 @@
---
read_when:
- 你在不使用完整新手引导向导的情况下进行首次设置
- 你想设置默认工作区路径
summary: "`openclaw setup` 的 CLI 参考(初始化配置 + 工作区)"
title: setup
x-i18n:
generated_at: "2026-02-01T20:21:26Z"
model: claude-opus-4-5
provider: pi
source_hash: 7f3fc8b246924edf48501785be2c0d356bd31bfbb133e75a139a5ee41dbf57f4
source_path: cli/setup.md
workflow: 14
---
# `openclaw setup`
初始化 `~/.openclaw/openclaw.json` 和智能体工作区。
相关内容:
- 快速开始:[快速开始](/start/getting-started)
- 向导:[新手引导](/start/onboarding)
## 示例
```bash
openclaw setup
openclaw setup --workspace ~/.openclaw/workspace
```
通过 setup 运行向导:
```bash
openclaw setup --wizard
```

33
docs/zh-CN/cli/skills.md Normal file
View file

@ -0,0 +1,33 @@
---
read_when:
- 想要查看哪些 Skills 可用且可以运行
- 想要调试 Skills 缺失的二进制文件/环境变量/配置
summary: Skills 列表/信息/检查及 Skills 资格的 `openclaw skills` CLI 参考
title: skills
x-i18n:
generated_at: "2026-02-01T20:21:28Z"
model: claude-opus-4-5
provider: pi
source_hash: 7878442c88a27ec8033f3125c319e9a6a85a1c497a404a06112ad45185c261b0
source_path: cli/skills.md
workflow: 14
---
# `openclaw skills`
检查 Skills内置 + 工作区 + 托管覆盖),查看哪些符合条件以及哪些缺少依赖。
相关内容:
- Skills 系统:[Skills](/tools/skills)
- Skills配置[Skills配置](/tools/skills-config)
- ClawHub 安装:[ClawHub](/tools/clawhub)
## 命令
```bash
openclaw skills list
openclaw skills list --eligible
openclaw skills info <name>
openclaw skills check
```

33
docs/zh-CN/cli/status.md Normal file
View file

@ -0,0 +1,33 @@
---
read_when:
- 你想快速诊断渠道健康状况及近期会话接收者
- 你想获取可粘贴的完整状态信息用于调试
summary: "`openclaw status`(诊断、探测、使用情况快照)的 CLI 参考"
title: status
x-i18n:
generated_at: "2026-02-01T20:21:30Z"
model: claude-opus-4-5
provider: pi
source_hash: 2bbf5579c48034fc15c2cbd5506c50456230b17e4a74c06318968c590d8f1501
source_path: cli/status.md
workflow: 14
---
# `openclaw status`
渠道和会话的诊断信息。
```bash
openclaw status
openclaw status --all
openclaw status --deep
openclaw status --usage
```
说明:
- `--deep` 会运行实时探测WhatsApp Web + Telegram + Discord + Google Chat + Slack + Signal
- 当配置了多个智能体时,输出包含每个智能体的会话存储。
- 概览包含 Gateway网关和节点主机服务的安装/运行状态(如可用)。
- 概览包含更新渠道和 git SHA适用于源码检出
- 更新信息会显示在概览中;如果有可用更新,状态会提示运行 `openclaw update`(参见[更新](/install/updating))。

63
docs/zh-CN/cli/system.md Normal file
View file

@ -0,0 +1,63 @@
---
read_when:
- 你想在不创建 cron 任务的情况下将系统事件加入队列
- 你需要启用或禁用心跳
- 你想检查系统存在状态条目
summary: "`openclaw system` 的 CLI 参考(系统事件、心跳、存在状态)"
title: system
x-i18n:
generated_at: "2026-02-01T20:21:34Z"
model: claude-opus-4-5
provider: pi
source_hash: 36ae5dbdec327f5a32f7ef44bdc1f161bad69868de62f5071bb4d25a71bfdfe9
source_path: cli/system.md
workflow: 14
---
# `openclaw system`
Gateway网关的系统级辅助工具将系统事件加入队列、控制心跳以及查看存在状态。
## 常用命令
```bash
openclaw system event --text "Check for urgent follow-ups" --mode now
openclaw system heartbeat enable
openclaw system heartbeat last
openclaw system presence
```
## `system event`
在**主**会话上将系统事件加入队列。下一次心跳会将其作为 `System:` 行注入到提示中。使用 `--mode now` 可立即触发心跳;`next-heartbeat` 则等待下一次计划的心跳周期。
标志:
- `--text <text>`:必需的系统事件文本。
- `--mode <mode>``now` 或 `next-heartbeat`(默认)。
- `--json`:机器可读输出。
## `system heartbeat last|enable|disable`
心跳控制:
- `last`:显示上一次心跳事件。
- `enable`:重新开启心跳(如果之前被禁用,请使用此命令)。
- `disable`:暂停心跳。
标志:
- `--json`:机器可读输出。
## `system presence`
列出 Gateway网关已知的当前系统存在状态条目节点、实例及类似状态行
标志:
- `--json`:机器可读输出。
## 注意事项
- 需要当前配置(本地或远程)可访问的运行中 Gateway网关。
- 系统事件是临时的,不会在重启后持久化。

30
docs/zh-CN/cli/tui.md Normal file
View file

@ -0,0 +1,30 @@
---
read_when:
- 想要使用 Gateway网关的终端 UI支持远程
- 想要从脚本传递 url/token/session
summary: 连接到 Gateway网关的终端 UI 的 `openclaw tui` CLI 参考
title: tui
x-i18n:
generated_at: "2026-02-01T20:21:31Z"
model: claude-opus-4-5
provider: pi
source_hash: f0a97d92e08746a9d6a4f31d361ccad9aea4c3dc61cfafb310d88715f61cfb64
source_path: cli/tui.md
workflow: 14
---
# `openclaw tui`
打开连接到 Gateway网关的终端 UI。
相关内容:
- TUI 指南:[TUI](/tui)
## 示例
```bash
openclaw tui
openclaw tui --url ws://127.0.0.1:18789 --token <token>
openclaw tui --session main --deliver
```

View file

@ -0,0 +1,24 @@
---
read_when:
- 你想移除 Gateway网关服务和/或本地状态
- 你想先进行试运行
summary: "`openclaw uninstall`(移除 Gateway网关服务 + 本地数据)的 CLI 参考"
title: uninstall
x-i18n:
generated_at: "2026-02-01T20:21:33Z"
model: claude-opus-4-5
provider: pi
source_hash: 8d6c3890923f18f95c12b76443d649a6b404934ebd054fb86a9fa1abae843fe4
source_path: cli/uninstall.md
workflow: 14
---
# `openclaw uninstall`
卸载 Gateway网关服务 + 本地数据CLI 保留)。
```bash
openclaw uninstall
openclaw uninstall --all --yes
openclaw uninstall --dry-run
```

101
docs/zh-CN/cli/update.md Normal file
View file

@ -0,0 +1,101 @@
---
read_when:
- 你想安全地更新源码检出
- 你需要了解 `--update` 简写行为
summary: "`openclaw update`(安全的源码更新 + Gateway网关自动重启的 CLI 参考"
title: update
x-i18n:
generated_at: "2026-02-01T20:21:45Z"
model: claude-opus-4-5
provider: pi
source_hash: 3a08e8ac797612c498eef54ecb83e61c9a1ee5de09162a01dbb4b3bd72897206
source_path: cli/update.md
workflow: 14
---
# `openclaw update`
安全更新 OpenClaw 并在 stable/beta/dev 渠道之间切换。
如果你通过 **npm/pnpm** 安装(全局安装,无 git 元数据),更新将通过[更新](/install/updating)中的包管理器流程进行。
## 用法
```bash
openclaw update
openclaw update status
openclaw update wizard
openclaw update --channel beta
openclaw update --channel dev
openclaw update --tag beta
openclaw update --no-restart
openclaw update --json
openclaw --update
```
## 选项
- `--no-restart`:成功更新后跳过重启 Gateway网关服务。
- `--channel <stable|beta|dev>`设置更新渠道git + npm持久化到配置中
- `--tag <dist-tag|version>`:仅为本次更新覆盖 npm dist-tag 或版本。
- `--json`:输出机器可读的 `UpdateRunResult` JSON。
- `--timeout <seconds>`:每步超时时间(默认为 1200 秒)。
注意:降级需要确认,因为旧版本可能会破坏配置。
## `update status`
显示当前活跃的更新渠道 + git 标签/分支/SHA适用于源码检出以及更新可用性。
```bash
openclaw update status
openclaw update status --json
openclaw update status --timeout 10
```
选项:
- `--json`:输出机器可读的状态 JSON。
- `--timeout <seconds>`:检查超时时间(默认为 3 秒)。
## `update wizard`
交互式流程,用于选择更新渠道并确认更新后是否重启 Gateway网关默认重启。如果你选择 `dev` 但没有 git 检出,它会提供创建一个的选项。
## 工作原理
当你显式切换渠道(`--channel ...`OpenClaw 也会保持安装方式一致:
- `dev` → 确保存在 git 检出(默认:`~/openclaw`,可通过 `OPENCLAW_GIT_DIR` 覆盖),更新它,并从该检出安装全局 CLI。
- `stable`/`beta` → 使用匹配的 dist-tag 从 npm 安装。
## Git 检出流程
渠道:
- `stable`:检出最新的非 beta 标签,然后构建 + doctor。
- `beta`:检出最新的 `-beta` 标签,然后构建 + doctor。
- `dev`:检出 `main`,然后 fetch + rebase。
概要流程:
1. 要求工作树干净(无未提交的更改)。
2. 切换到所选渠道(标签或分支)。
3. 拉取上游(仅 dev
4. 仅 dev在临时工作树中进行预检 lint + TypeScript 构建;如果最新提交失败,会向前回溯最多 10 个提交以找到最新的可成功构建的提交。
5. Rebase 到所选提交(仅 dev
6. 安装依赖(优先使用 pnpm回退到 npm
7. 构建项目 + 构建控制台 UI。
8. 运行 `openclaw doctor` 作为最终的"安全更新"检查。
9. 将插件同步到活跃渠道dev 使用内置扩展stable/beta 使用 npm并更新通过 npm 安装的插件。
## `--update` 简写
`openclaw --update` 会重写为 `openclaw update`(便于在 shell 和启动脚本中使用)。
## 另请参阅
- `openclaw doctor`(在 git 检出上会提供先运行更新的选项)
- [开发渠道](/install/development-channels)
- [更新](/install/updating)
- [CLI 参考](/cli)

View file

@ -0,0 +1,41 @@
---
read_when:
- 使用语音通话插件并想了解 CLI 入口
- 想要 `voicecall call|continue|status|tail|expose` 的快速示例
summary: 语音通话插件命令的 `openclaw voicecall` CLI 参考
title: voicecall
x-i18n:
generated_at: "2026-02-01T20:21:37Z"
model: claude-opus-4-5
provider: pi
source_hash: d93aaee6f6f5c9ac468d8d2905cb23f0f2db75809408cb305c055505be9936f2
source_path: cli/voicecall.md
workflow: 14
---
# `openclaw voicecall`
`voicecall` 是一个由插件提供的命令。只有在安装并启用了语音通话插件时才会出现。
主要文档:
- 语音通话插件:[语音通话](/plugins/voice-call)
## 常用命令
```bash
openclaw voicecall status --call-id <id>
openclaw voicecall call --to "+15555550123" --message "Hello" --mode notify
openclaw voicecall continue --call-id <id> --message "Any questions?"
openclaw voicecall end --call-id <id>
```
## 暴露 WebhookTailscale
```bash
openclaw voicecall expose --mode serve
openclaw voicecall expose --mode funnel
openclaw voicecall unexpose
```
安全提示:仅将 webhook 端点暴露给你信任的网络。尽可能优先使用 Tailscale Serve 而非 Funnel。

View file

@ -0,0 +1,32 @@
---
read_when:
- 你想将 Gmail Pub/Sub 事件接入 OpenClaw
- 你需要 Webhook 辅助命令
summary: "`openclaw webhooks`Webhook 辅助工具 + Gmail Pub/Sub的 CLI 参考"
title: webhooks
x-i18n:
generated_at: "2026-02-01T20:21:38Z"
model: claude-opus-4-5
provider: pi
source_hash: 785ec62afe6631b340ce4a4541ceb34cd6b97704cf7a9889762cb4c1f29a5ca0
source_path: cli/webhooks.md
workflow: 14
---
# `openclaw webhooks`
Webhook 辅助工具和集成Gmail Pub/Sub、Webhook 辅助工具)。
相关内容:
- Webhook[Webhook](/automation/webhook)
- Gmail Pub/Sub[Gmail Pub/Sub](/automation/gmail-pubsub)
## Gmail
```bash
openclaw webhooks gmail setup --account you@example.com
openclaw webhooks gmail run
```
详情请参阅 [Gmail Pub/Sub 文档](/automation/gmail-pubsub)。

View file

@ -0,0 +1,150 @@
---
read_when:
- 你需要智能体循环或生命周期事件的详细说明
summary: 智能体循环生命周期、流和等待语义
title: 智能体循环
x-i18n:
generated_at: "2026-02-01T20:22:03Z"
model: claude-opus-4-5
provider: pi
source_hash: 0775b96eb3451e137297661a1095eaefb2bafeebb5f78123174a46290e18b014
source_path: concepts/agent-loop.md
workflow: 14
---
# 智能体循环OpenClaw
智能体循环是智能体的一次完整"真实"运行:接收 → 上下文组装 → 模型推理 →
工具执行 → 流式回复 → 持久化。它是将消息转化为操作和最终回复的权威路径,同时保持会话状态的一致性。
在 OpenClaw 中,循环是每个会话的单次序列化运行,在模型思考、调用工具和流式输出时发出生命周期和流事件。本文档解释了这个完整循环是如何端到端连接的。
## 入口点
- Gateway网关 RPC`agent` 和 `agent.wait`
- CLI`agent` 命令。
## 工作原理(高层概述)
1. `agent` RPC 验证参数解析会话sessionKey/sessionId持久化会话元数据立即返回 `{ runId, acceptedAt }`
2. `agentCommand` 运行智能体:
- 解析模型 + thinking/verbose 默认值
- 加载 Skills 快照
- 调用 `runEmbeddedPiAgent`pi-agent-core 运行时)
- 如果嵌入式循环未发出**生命周期 end/error** 事件,则补充发出
3. `runEmbeddedPiAgent`
- 通过每会话 + 全局队列序列化运行
- 解析模型 + 认证配置并构建 pi 会话
- 订阅 pi 事件并流式传输助手/工具增量
- 强制执行超时 -> 超时则中止运行
- 返回载荷 + 使用量元数据
4. `subscribeEmbeddedPiSession` 将 pi-agent-core 事件桥接到 OpenClaw `agent` 流:
- 工具事件 => `stream: "tool"`
- 助手增量 => `stream: "assistant"`
- 生命周期事件 => `stream: "lifecycle"``phase: "start" | "end" | "error"`
5. `agent.wait` 使用 `waitForAgentJob`
- 等待 `runId` 的**生命周期 end/error**
- 返回 `{ status: ok|error|timeout, startedAt, endedAt, error? }`
## 队列 + 并发
- 运行按会话键(会话通道)序列化,并可选择通过全局通道进行。
- 这可以防止工具/会话竞争并保持会话历史的一致性。
- 消息渠道可以选择队列模式collect/steer/followup来供给此通道系统。
参见[命令队列](/concepts/queue)。
## 会话 + 工作区准备
- 工作区被解析并创建;沙箱运行可能会重定向到沙箱工作区根目录。
- Skills 被加载(或从快照中复用)并注入到环境和提示中。
- 引导/上下文文件被解析并注入到系统提示报告中。
- 获取会话写锁;在流式传输之前打开并准备 `SessionManager`
## 提示组装 + 系统提示
- 系统提示由 OpenClaw 的基础提示、Skills 提示、引导上下文和每次运行的覆盖项构建而成。
- 强制执行模型特定的限制和压缩预留令牌数。
- 参见[系统提示](/concepts/system-prompt)了解模型所看到的内容。
## 钩子点(可拦截的位置)
OpenClaw 有两个钩子系统:
- **内部钩子**Gateway网关钩子用于命令和生命周期事件的事件驱动脚本。
- **插件钩子**:智能体/工具生命周期和 Gateway网关管道中的扩展点。
### 内部钩子Gateway网关钩子
- **`agent:bootstrap`**:在系统提示最终确定之前构建引导文件时运行。
用于添加/移除引导上下文文件。
- **命令钩子**`/new`、`/reset`、`/stop` 和其他命令事件(参见钩子文档)。
参见[钩子](/hooks)了解设置和示例。
### 插件钩子(智能体 + Gateway网关生命周期
这些在智能体循环或 Gateway网关管道内运行
- **`before_agent_start`**:在运行开始前注入上下文或覆盖系统提示。
- **`agent_end`**:在完成后检查最终消息列表和运行元数据。
- **`before_compaction` / `after_compaction`**:观察或标注压缩周期。
- **`before_tool_call` / `after_tool_call`**:拦截工具参数/结果。
- **`tool_result_persist`**:在工具结果写入会话记录之前同步转换工具结果。
- **`message_received` / `message_sending` / `message_sent`**:入站 + 出站消息钩子。
- **`session_start` / `session_end`**:会话生命周期边界。
- **`gateway_start` / `gateway_stop`**Gateway网关生命周期事件。
参见[插件](/plugin#plugin-hooks)了解钩子 API 和注册详情。
## 流式传输 + 部分回复
- 助手增量从 pi-agent-core 流式传输并作为 `assistant` 事件发出。
- 块流式传输可以在 `text_end``message_end` 时发出部分回复。
- 推理流式传输可以作为单独的流或作为块回复发出。
- 参见[流式传输](/concepts/streaming)了解分块和块回复行为。
## 工具执行 + 消息工具
- 工具的 start/update/end 事件在 `tool` 流上发出。
- 工具结果在记录/发出之前会针对大小和图片载荷进行清理。
- 消息工具的发送会被跟踪,以抑制重复的助手确认。
## 回复整形 + 抑制
- 最终载荷由以下内容组装:
- 助手文本(及可选的推理内容)
- 内联工具摘要(当 verbose + 允许时)
- 模型出错时的助手错误文本
- `NO_REPLY` 被视为静默令牌,从传出载荷中过滤。
- 消息工具的重复项从最终载荷列表中移除。
- 如果没有可渲染的载荷且工具出错,则发出回退的工具错误回复
(除非消息工具已发送了用户可见的回复)。
## 压缩 + 重试
- 自动压缩发出 `compaction` 流事件,并可能触发重试。
- 重试时,内存缓冲区和工具摘要会被重置以避免重复输出。
- 参见[压缩](/concepts/compaction)了解压缩管道。
## 事件流(当前)
- `lifecycle`:由 `subscribeEmbeddedPiSession` 发出(以及作为 `agentCommand` 的回退)
- `assistant`:来自 pi-agent-core 的流式增量
- `tool`:来自 pi-agent-core 的流式工具事件
## 聊天渠道处理
- 助手增量被缓冲为聊天 `delta` 消息。
- 在**生命周期 end/error** 时发出聊天 `final`
## 超时
- `agent.wait` 默认值30 秒(仅等待阶段)。`timeoutMs` 参数可覆盖。
- 智能体运行时:`agents.defaults.timeoutSeconds` 默认 600 秒;在 `runEmbeddedPiAgent` 中止计时器中强制执行。
## 可能提前结束的情况
- 智能体超时(中止)
- AbortSignal取消
- Gateway网关断开连接或 RPC 超时
- `agent.wait` 超时(仅等待阶段,不会停止智能体)

View file

@ -0,0 +1,214 @@
---
read_when:
- 你需要解释智能体工作区或其文件布局
- 你想要备份或迁移智能体工作区
summary: 智能体工作区:位置、布局和备份策略
title: 智能体工作区
x-i18n:
generated_at: "2026-02-01T20:22:05Z"
model: claude-opus-4-5
provider: pi
source_hash: 84c550fd89b5f2474aeae586795485fd29d36effbb462f13342b31540fc18b82
source_path: concepts/agent-workspace.md
workflow: 14
---
# 智能体工作区
工作区是智能体的主目录。它是文件工具和工作区上下文使用的唯一工作目录。请将其保持私密,并视为记忆来对待。
它与 `~/.openclaw/` 是分开的,后者存储配置、凭据和会话。
**重要提示:** 工作区是**默认工作目录**,而非硬性沙箱。工具会基于工作区解析相对路径,但绝对路径仍然可以访问主机上的其他位置,除非启用了沙箱。如果你需要隔离,请使用 [`agents.defaults.sandbox`](/gateway/sandboxing)(和/或按智能体的沙箱配置)。当启用沙箱且 `workspaceAccess` 不是 `"rw"` 时,工具在 `~/.openclaw/sandboxes` 下的沙箱工作区中运行,而非你的主机工作区。
## 默认位置
- 默认:`~/.openclaw/workspace`
- 如果设置了 `OPENCLAW_PROFILE` 且不是 `"default"`,则默认变为
`~/.openclaw/workspace-<profile>`
- 在 `~/.openclaw/openclaw.json` 中覆盖:
```json5
{
agent: {
workspace: "~/.openclaw/workspace",
},
}
```
`openclaw onboard`、`openclaw configure` 或 `openclaw setup` 将创建工作区,并在引导文件缺失时生成它们。
如果你已经自行管理工作区文件,可以禁用引导文件创建:
```json5
{ agent: { skipBootstrap: true } }
```
## 额外的工作区文件夹
较旧的安装可能创建了 `~/openclaw`。保留多个工作区目录可能会导致认证或状态不一致的困惑,因为同一时间只有一个工作区处于活跃状态。
**建议:** 保持单一活跃工作区。如果你不再使用额外的文件夹,请将其归档或移至回收站(例如 `trash ~/openclaw`)。如果你有意保留多个工作区,请确保 `agents.defaults.workspace` 指向活跃的那个。
`openclaw doctor` 在检测到额外工作区目录时会发出警告。
## 工作区文件映射(每个文件的含义)
以下是 OpenClaw 在工作区中期望的标准文件:
- `AGENTS.md`
- 智能体的操作指令以及它应如何使用记忆。
- 在每个会话开始时加载。
- 适合放置规则、优先级和"行为方式"的详细说明。
- `SOUL.md`
- 人设、语气和边界。
- 每个会话加载。
- `USER.md`
- 用户是谁以及如何称呼他们。
- 每个会话加载。
- `IDENTITY.md`
- 智能体的名称、风格和表情符号。
- 在引导仪式期间创建/更新。
- `TOOLS.md`
- 关于本地工具和约定的说明。
- 不控制工具可用性;仅作为指导。
- `HEARTBEAT.md`
- 可选的心跳运行小清单。
- 保持简短以避免消耗令牌。
- `BOOT.md`
- 可选的启动清单,在启用内部钩子时于 Gateway网关重启时执行。
- 保持简短;使用消息工具进行外发。
- `BOOTSTRAP.md`
- 一次性首次运行仪式。
- 仅为全新工作区创建。
- 仪式完成后请删除它。
- `memory/YYYY-MM-DD.md`
- 每日记忆日志(每天一个文件)。
- 建议在会话开始时读取今天和昨天的内容。
- `MEMORY.md`(可选)
- 精选的长期记忆。
- 仅在主要的私人会话中加载(不在共享/群组上下文中)。
参见[记忆](/concepts/memory)了解工作流程和自动记忆刷写。
- `skills/`(可选)
- 工作区特定的 Skills。
- 名称冲突时覆盖托管/内置 Skills。
- `canvas/`(可选)
- 用于节点显示的 Canvas UI 文件(例如 `canvas/index.html`)。
如果任何引导文件缺失OpenClaw 会在会话中注入"文件缺失"标记并继续运行。大型引导文件在注入时会被截断;可通过 `agents.defaults.bootstrapMaxChars`默认20000调整限制。`openclaw setup` 可以重新创建缺失的默认文件而不会覆盖现有文件。
## 不在工作区中的内容
以下内容位于 `~/.openclaw/` 下,**不应**提交到工作区仓库:
- `~/.openclaw/openclaw.json`(配置)
- `~/.openclaw/credentials/`OAuth 令牌、API 密钥)
- `~/.openclaw/agents/<agentId>/sessions/`(会话记录和元数据)
- `~/.openclaw/skills/`(托管 Skills
如果你需要迁移会话或配置,请单独复制它们并将其排除在版本控制之外。
## Git 备份(推荐,私有)
将工作区视为私有记忆。将其放入一个**私有** git 仓库中,以便备份和恢复。
在 Gateway网关运行的机器上执行以下步骤工作区就在那里
### 1) 初始化仓库
如果安装了 git全新的工作区会自动初始化。如果此工作区尚未是仓库请运行
```bash
cd ~/.openclaw/workspace
git init
git add AGENTS.md SOUL.md TOOLS.md IDENTITY.md USER.md HEARTBEAT.md memory/
git commit -m "Add agent workspace"
```
### 2) 添加私有远程仓库(新手友好选项)
选项 AGitHub 网页界面
1. 在 GitHub 上创建一个新的**私有**仓库。
2. 不要使用 README 初始化(避免合并冲突)。
3. 复制 HTTPS 远程 URL。
4. 添加远程仓库并推送:
```bash
git branch -M main
git remote add origin <https-url>
git push -u origin main
```
选项 BGitHub CLI (`gh`)
```bash
gh auth login
gh repo create openclaw-workspace --private --source . --remote origin --push
```
选项 CGitLab 网页界面
1. 在 GitLab 上创建一个新的**私有**仓库。
2. 不要使用 README 初始化(避免合并冲突)。
3. 复制 HTTPS 远程 URL。
4. 添加远程仓库并推送:
```bash
git branch -M main
git remote add origin <https-url>
git push -u origin main
```
### 3) 持续更新
```bash
git status
git add .
git commit -m "Update memory"
git push
```
## 不要提交密钥
即使在私有仓库中,也要避免在工作区中存储密钥:
- API 密钥、OAuth 令牌、密码或私有凭据。
- `~/.openclaw/` 下的任何内容。
- 聊天记录的原始转储或敏感附件。
如果你必须存储敏感引用,请使用占位符并将真实密钥保存在其他地方(密码管理器、环境变量或 `~/.openclaw/`)。
建议的 `.gitignore` 起始内容:
```gitignore
.DS_Store
.env
**/*.key
**/*.pem
**/secrets*
```
## 将工作区迁移到新机器
1. 将仓库克隆到目标路径(默认 `~/.openclaw/workspace`)。
2. 在 `~/.openclaw/openclaw.json` 中将 `agents.defaults.workspace` 设置为该路径。
3. 运行 `openclaw setup --workspace <path>` 以生成任何缺失的文件。
4. 如果你需要会话记录,请从旧机器单独复制 `~/.openclaw/agents/<agentId>/sessions/`
## 高级说明
- 多智能体路由可以为每个智能体使用不同的工作区。参见[渠道路由](/concepts/channel-routing)了解路由配置。
- 如果启用了 `agents.defaults.sandbox`,非主要会话可以使用 `agents.defaults.sandbox.workspaceRoot` 下的按会话沙箱工作区。

View file

@ -0,0 +1,114 @@
---
read_when:
- 更改智能体运行时、工作区引导或会话行为
summary: 智能体运行时(嵌入式 pi-mono、工作区契约和会话引导
title: 智能体运行时
x-i18n:
generated_at: "2026-02-01T20:22:02Z"
model: claude-opus-4-5
provider: pi
source_hash: 04b4e0bc6345d2afd9a93186e5d7a02a393ec97da2244e531703cb6a1c182325
source_path: concepts/agent.md
workflow: 14
---
# 智能体运行时 🤖
OpenClaw 运行一个源自 **pi-mono** 的单一嵌入式智能体运行时。
## 工作区(必需)
OpenClaw 使用单一智能体工作区目录(`agents.defaults.workspace`)作为智能体工具和上下文的**唯一**工作目录(`cwd`)。
建议:使用 `openclaw setup` 创建 `~/.openclaw/openclaw.json`(如果不存在)并初始化工作区文件。
完整的工作区布局 + 备份指南:[智能体工作区](/concepts/agent-workspace)
如果启用了 `agents.defaults.sandbox`,非主会话可以使用 `agents.defaults.sandbox.workspaceRoot` 下的按会话工作区覆盖此设置(参见 [Gateway网关配置](/gateway/configuration))。
## 引导文件(注入)
`agents.defaults.workspace`OpenClaw 期望这些用户可编辑的文件:
- `AGENTS.md` — 操作指令 + "记忆"
- `SOUL.md` — 角色设定、边界、语气
- `TOOLS.md` — 用户维护的工具说明(例如 `imsg`、`sag`、约定)
- `BOOTSTRAP.md` — 一次性首次运行仪式(完成后删除)
- `IDENTITY.md` — 智能体名称/风格/表情符号
- `USER.md` — 用户档案 + 首选称呼
在新会话的第一轮对话中OpenClaw 会将这些文件的内容直接注入到智能体上下文中。
空白文件会被跳过。大文件会被裁剪和截断并附带标记,以保持提示词精简(阅读完整文件以获取全部内容)。
如果文件缺失OpenClaw 会注入一行"文件缺失"标记(`openclaw setup` 会创建安全的默认模板)。
`BOOTSTRAP.md` 仅在**全新工作区**(没有其他引导文件存在)时创建。如果你在完成仪式后删除了它,后续重启时不会重新创建。
要完全禁用引导文件创建(用于预填充的工作区),请设置:
```json5
{ agent: { skipBootstrap: true } }
```
## 内置工具
核心工具read/exec/edit/write 及相关系统工具)始终可用,受工具策略约束。`apply_patch` 是可选的,由 `tools.exec.applyPatch` 控制。`TOOLS.md` **不**控制哪些工具存在;它是关于你希望如何使用这些工具的指导。
## Skills
OpenClaw 从三个位置加载 Skills名称冲突时工作区优先
- 内置(随安装包附带)
- 托管/本地:`~/.openclaw/skills`
- 工作区:`<workspace>/skills`
Skills 可以通过配置/环境变量进行控制(参见 [Gateway网关配置](/gateway/configuration) 中的 `skills`)。
## pi-mono 集成
OpenClaw 复用了 pi-mono 代码库的部分内容(模型/工具),但**会话管理、发现和工具连接由 OpenClaw 负责**。
- 没有 pi-coding 智能体运行时。
- 不会读取 `~/.pi/agent``<workspace>/.pi` 设置。
## 会话
会话记录以 JSONL 格式存储在:
- `~/.openclaw/agents/<agentId>/sessions/<SessionId>.jsonl`
会话 ID 是稳定的,由 OpenClaw 选择。
**不会**读取旧版 Pi/Tau 会话文件夹。
## 流式传输期间的引导
当队列模式为 `steer` 时,入站消息会被注入到当前运行中。队列在**每次工具调用后**检查;如果存在排队消息,当前助手消息的剩余工具调用会被跳过(工具结果显示"Skipped due to queued user message."错误),然后在下一个助手响应之前注入排队的用户消息。
当队列模式为 `followup``collect` 时,入站消息会被保留直到当前轮次结束,然后使用排队的负载开始新的智能体轮次。参见[队列](/concepts/queue)了解模式 + 防抖/上限行为。
块流式传输在完成的助手块完成后立即发送;**默认关闭**`agents.defaults.blockStreamingDefault: "off"`)。
通过 `agents.defaults.blockStreamingBreak` 调整边界(`text_end` 与 `message_end`;默认为 text_end
使用 `agents.defaults.blockStreamingChunk` 控制软块分块(默认 8001200 字符;优先段落分隔,其次换行;最后是句子)。
使用 `agents.defaults.blockStreamingCoalesce` 合并流式块,以减少单行刷屏(基于空闲的合并后再发送)。非 Telegram 渠道需要显式设置 `*.blockStreaming: true` 以启用块回复。
详细的工具摘要在工具启动时发出无防抖Control UI 在可用时通过智能体事件流式传输工具输出。
更多详情:[流式传输 + 分块](/concepts/streaming)。
## 模型引用
配置中的模型引用(例如 `agents.defaults.model``agents.defaults.models`)通过**第一个** `/` 进行拆分解析。
- 配置模型时使用 `provider/model` 格式。
- 如果模型 ID 本身包含 `/`OpenRouter 风格),请包含提供商前缀(示例:`openrouter/moonshotai/kimi-k2`)。
- 如果省略提供商OpenClaw 会将输入视为别名或**默认提供商**的模型(仅在模型 ID 中没有 `/` 时有效)。
## 配置(最小化)
至少需要设置:
- `agents.defaults.workspace`
- `channels.whatsapp.allowFrom`(强烈建议)
---
_下一篇[群聊](/concepts/group-messages)_ 🦞

View file

@ -0,0 +1,123 @@
---
read_when:
- 处理 Gateway网关协议、客户端或传输层相关工作时
summary: WebSocket Gateway网关架构、组件和客户端流程
title: Gateway网关架构
x-i18n:
generated_at: "2026-02-01T20:22:27Z"
model: claude-opus-4-5
provider: pi
source_hash: c636d5d8a5e628067432b30671466309e3d630b106d413f1708765bf2a9399a1
source_path: concepts/architecture.md
workflow: 14
---
# Gateway网关架构
最后更新2026-01-22
## 概述
- 单个长生命周期的 **Gateway网关** 管理所有消息接入面(通过 Baileys 接入 WhatsApp、通过 grammY 接入 Telegram、Slack、Discord、Signal、iMessage、WebChat
- 控制面客户端macOS 应用、CLI、Web UI、自动化通过 **WebSocket** 连接到 Gateway网关使用配置的绑定地址默认 `127.0.0.1:18789`)。
- **节点**macOS/iOS/Android/无头模式)也通过 **WebSocket** 连接,但声明 `role: node` 并显式指定能力/命令。
- 每台主机一个 Gateway网关它是唯一打开 WhatsApp 会话的位置。
- **画布主机**(默认 `18793`)提供智能体可编辑的 HTML 和 A2UI。
## 组件和流程
### Gateway网关守护进程
- 维护提供商连接。
- 暴露类型化的 WS API请求、响应、服务端推送事件
- 根据 JSON Schema 验证入站帧。
- 发出 `agent`、`chat`、`presence`、`health`、`heartbeat`、`cron` 等事件。
### 客户端Mac 应用 / CLI / Web 管理端)
- 每个客户端一个 WS 连接。
- 发送请求(`health`、`status`、`send`、`agent`、`system-presence`)。
- 订阅事件(`tick`、`agent`、`presence`、`shutdown`)。
### 节点macOS / iOS / Android / 无头模式)
- 连接到**同一个 WS 服务器**,声明 `role: node`
- 在 `connect` 中提供设备身份;配对是**基于设备**的(角色为 `node`),审批信息存储在设备配对存储中。
- 暴露 `canvas.*`、`camera.*`、`screen.record`、`location.get` 等命令。
协议详情:
- [Gateway网关协议](/gateway/protocol)
### WebChat
- 静态 UI使用 Gateway网关 WS API 获取聊天历史和发送消息。
- 在远程设置中,通过与其他客户端相同的 SSH/Tailscale 隧道连接。
## 连接生命周期(单个客户端)
```
Client Gateway网关
| |
|---- req:connect -------->|
|<------ res (ok) ---------| res error + 关闭
| payload=hello-ok 携带快照presence + health
| |
|<------ event:presence ---|
|<------ event:tick -------|
| |
|------- req:agent ------->|
|<------ res:agent --------| 确认{runId,status:"accepted"}
|<------ event:agent ------| 流式传输
|<------ res:agent --------| 最终{runId,status,summary}
| |
```
## 线路协议(摘要)
- 传输层WebSocket文本帧携带 JSON 负载。
- 第一帧**必须**是 `connect`
- 握手完成后:
- 请求:`{type:"req", id, method, params}` → `{type:"res", id, ok, payload|error}`
- 事件:`{type:"event", event, payload, seq?, stateVersion?}`
- 如果设置了 `OPENCLAW_GATEWAY_TOKEN`(或 `--token``connect.params.auth.token` 必须匹配,否则套接字将关闭。
- 有副作用的方法(`send`、`agent`)需要幂等性键以安全重试;服务器维护一个短期去重缓存。
- 节点必须在 `connect` 中包含 `role: "node"` 以及能力/命令/权限。
## 配对与本地信任
- 所有 WS 客户端(操作员 + 节点)在 `connect` 时包含**设备身份**。
- 新设备 ID 需要配对审批Gateway网关颁发**设备令牌**用于后续连接。
- **本地**连接local loopback 或 Gateway网关主机自身的 tailnet 地址)可以自动审批,以保持同主机用户体验的流畅性。
- **非本地**连接必须对 `connect.challenge` nonce 签名,并需要显式审批。
- Gateway网关认证`gateway.auth.*`)仍适用于**所有**连接,无论本地还是远程。
详情:[Gateway网关协议](/gateway/protocol)、[配对](/start/pairing)、[安全](/gateway/security)。
## 协议类型定义与代码生成
- TypeBox schema 定义协议。
- 从这些 schema 生成 JSON Schema。
- 从 JSON Schema 生成 Swift 模型。
## 远程访问
- 推荐方式Tailscale 或 VPN。
- 备选方式SSH 隧道
```bash
ssh -N -L 18789:127.0.0.1:18789 user@host
```
- 相同的握手 + 认证令牌适用于隧道连接。
- 远程设置中可为 WS 启用 TLS + 可选的证书固定。
## 运维概览
- 启动:`openclaw gateway`(前台运行,日志输出到 stdout
- 健康检查:通过 WS 发送 `health`(也包含在 `hello-ok` 中)。
- 监管:使用 launchd/systemd 实现自动重启。
## 不变量
- 每台主机恰好一个 Gateway网关控制单个 Baileys 会话。
- 握手是强制的;任何非 JSON 或非 connect 的首帧将导致硬关闭。
- 事件不会重放;客户端必须在出现间隙时刷新。

View file

@ -0,0 +1,117 @@
---
read_when:
- 更改渠道路由或收件箱行为
summary: 每个渠道WhatsApp、Telegram、Discord、Slack的路由规则及共享上下文
title: 渠道路由
x-i18n:
generated_at: "2026-02-01T20:22:21Z"
model: claude-opus-4-5
provider: pi
source_hash: 1a322b5187e32c82fc1e8aac02437e2eeb7ba84e7b3a1db89feeab1dcf7dbbab
source_path: concepts/channel-routing.md
workflow: 14
---
# 渠道与路由
OpenClaw 将回复**路由回消息来源的渠道**。模型不会选择渠道;路由是确定性的,由主机配置控制。
## 关键术语
- **渠道**`whatsapp`、`telegram`、`discord`、`slack`、`signal`、`imessage`、`webchat`。
- **AccountId**:每个渠道的账户实例(在支持的情况下)。
- **AgentId**:隔离的工作区 + 会话存储("大脑")。
- **SessionKey**:用于存储上下文和控制并发的桶键。
## 会话键格式(示例)
私信会折叠到智能体的**主**会话:
- `agent:<agentId>:<mainKey>`(默认:`agent:main:main`
群组和渠道按渠道隔离:
- 群组:`agent:<agentId>:<channel>:group:<id>`
- 渠道/房间:`agent:<agentId>:<channel>:channel:<id>`
线程:
- Slack/Discord 线程会在基础键后追加 `:thread:<threadId>`
- Telegram 论坛主题在群组键中嵌入 `:topic:<topicId>`
示例:
- `agent:main:telegram:group:-1001234567890:topic:42`
- `agent:main:discord:channel:123456:thread:987654`
## 路由规则(如何选择智能体)
路由为每条入站消息选择**一个智能体**
1. **精确对端匹配**`bindings` 中的 `peer.kind` + `peer.id`)。
2. **Guild 匹配**Discord通过 `guildId`
3. **Team 匹配**Slack通过 `teamId`
4. **账户匹配**(渠道上的 `accountId`)。
5. **渠道匹配**(该渠道上的任意账户)。
6. **默认智能体**`agents.list[].default`,否则取列表第一项,兜底为 `main`)。
匹配到的智能体决定使用哪个工作区和会话存储。
## 广播组(运行多个智能体)
广播组允许你为同一对端运行**多个智能体****在 OpenClaw 正常回复时**触发(例如:在 WhatsApp 群组中,经过提及/激活门控之后)。
配置:
```json5
{
broadcast: {
strategy: "parallel",
"120363403215116621@g.us": ["alfred", "baerbel"],
"+15555550123": ["support", "logger"],
},
}
```
参见:[广播组](/broadcast-groups)。
## 配置概览
- `agents.list`:命名的智能体定义(工作区、模型等)。
- `bindings`:将入站渠道/账户/对端映射到智能体。
示例:
```json5
{
agents: {
list: [{ id: "support", name: "Support", workspace: "~/.openclaw/workspace-support" }],
},
bindings: [
{ match: { channel: "slack", teamId: "T123" }, agentId: "support" },
{ match: { channel: "telegram", peer: { kind: "group", id: "-100123" } }, agentId: "support" },
],
}
```
## 会话存储
会话存储位于状态目录下(默认 `~/.openclaw`
- `~/.openclaw/agents/<agentId>/sessions/sessions.json`
- JSONL 记录文件与存储位于同一目录
你可以通过 `session.store``{agentId}` 模板来覆盖存储路径。
## WebChat 行为
WebChat 连接到**所选智能体**并默认使用该智能体的主会话。因此WebChat 让你可以在一个地方查看该智能体的跨渠道上下文。
## 回复上下文
入站回复包含:
- `ReplyToId`、`ReplyToBody` 和 `ReplyToSender`(在可用时)。
- 引用的上下文会以 `[Replying to ...]` 块的形式追加到 `Body` 中。
这在所有渠道中保持一致。

View file

@ -0,0 +1,67 @@
---
read_when:
- 你想了解自动压缩和 /compact
- 你正在调试长会话触及上下文限制的问题
summary: 上下文窗口 + 压缩OpenClaw 如何将会话保持在模型限制内
title: 压缩
x-i18n:
generated_at: "2026-02-01T20:22:17Z"
model: claude-opus-4-5
provider: pi
source_hash: e1d6791f2902044b5798ebf9320a7d055d37211eff4be03caa35d7e328ae803c
source_path: concepts/compaction.md
workflow: 14
---
# 上下文窗口与压缩
每个模型都有一个**上下文窗口**(可见的最大 token 数。长时间运行的对话会累积消息和工具结果一旦窗口空间紧张OpenClaw 会**压缩**较早的历史记录以保持在限制范围内。
## 什么是压缩
压缩会将**较早的对话总结**为一条紧凑的摘要条目,并保持近期消息不变。摘要存储在会话历史中,因此后续请求使用的是:
- 压缩摘要
- 压缩点之后的近期消息
压缩会**持久化**到会话的 JSONL 历史记录中。
## 配置
有关 `agents.defaults.compaction` 设置,请参阅[压缩配置与模式](/concepts/compaction)。
## 自动压缩(默认开启)
当会话接近或超过模型的上下文窗口时OpenClaw 会触发自动压缩,并可能使用压缩后的上下文重试原始请求。
你会看到:
- 详细模式下显示 `🧹 Auto-compaction complete`
- `/status` 显示 `🧹 Compactions: <count>`
在压缩之前OpenClaw 可以运行一次**静默记忆刷写**轮次,将持久化笔记写入磁盘。详情及配置请参阅[记忆](/concepts/memory)。
## 手动压缩
使用 `/compact`(可选附带指令)强制执行一次压缩:
```
/compact Focus on decisions and open questions
```
## 上下文窗口来源
上下文窗口因模型而异。OpenClaw 使用已配置提供商目录中的模型定义来确定限制。
## 压缩与修剪
- **压缩**:总结并**持久化**到 JSONL 中。
- **会话修剪**:仅裁剪旧的**工具结果****在内存中**按请求进行。
有关修剪的详情,请参阅 [/concepts/session-pruning](/concepts/session-pruning)。
## 提示
- 当会话感觉过时或上下文臃肿时,使用 `/compact`
- 大型工具输出已被截断;修剪可以进一步减少工具结果的堆积。
- 如果你需要全新开始,`/new` 或 `/reset` 会启动一个新的会话 ID。

Some files were not shown because too many files have changed in this diff Show more