Merge remote-tracking branch 'origin/main' into codex/pr-12077-matrix-plugin

# Conflicts:
#	extensions/matrix/package.json
#	extensions/matrix/src/matrix/monitor/events.ts
#	extensions/matrix/src/matrix/send.ts
#	pnpm-lock.yaml
This commit is contained in:
Gustavo Madeira Santana
2026-02-25 12:34:29 -05:00
1383 changed files with 67781 additions and 29693 deletions

View File

@@ -397,7 +397,8 @@ Example:
`allowlist` behavior:
- guild must match `channels.discord.guilds` (`id` preferred, slug accepted)
- optional sender allowlists: `users` (IDs or names) and `roles` (role IDs only); if either is configured, senders are allowed when they match `users` OR `roles`
- optional sender allowlists: `users` (stable IDs recommended) and `roles` (role IDs only); if either is configured, senders are allowed when they match `users` OR `roles`
- direct name/tag matching is disabled by default; enable `channels.discord.dangerouslyAllowNameMatching: true` only as break-glass compatibility mode
- names/tags are supported for `users`, but IDs are safer; `openclaw security audit` warns when name/tag entries are used
- if a guild has `channels` configured, non-listed channels are denied
- if a guild has no `channels` block, all channels in that allowlisted guild are allowed
@@ -768,7 +769,7 @@ Default slash command settings:
Notes:
- allowlists can use `pk:<memberId>`
- member display names are matched by name/slug
- member display names are matched by name/slug only when `channels.discord.dangerouslyAllowNameMatching: true`
- lookups use original message ID and are time-window constrained
- if lookup fails, proxied messages are treated as bot messages and dropped unless `allowBots=true`
@@ -918,6 +919,8 @@ Auto-join example:
channelId: "234567890123456789",
},
],
daveEncryption: true,
decryptionFailureTolerance: 24,
tts: {
provider: "openai",
openai: { voice: "alloy" },
@@ -932,6 +935,10 @@ Notes:
- `voice.tts` overrides `messages.tts` for voice playback only.
- Voice is enabled by default; set `channels.discord.voice.enabled=false` to disable it.
- `voice.daveEncryption` and `voice.decryptionFailureTolerance` pass through to `@discordjs/voice` join options.
- `@discordjs/voice` defaults are `daveEncryption=true` and `decryptionFailureTolerance=24` if unset.
- OpenClaw also watches receive decrypt failures and auto-recovers by leaving/rejoining the voice channel after repeated failures in a short window.
- If receive logs repeatedly show `DecryptionFailed(UnencryptedWhenPassthroughDisabled)`, this may be the upstream `@discordjs/voice` receive bug tracked in [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419).
## Voice messages
@@ -1007,6 +1014,18 @@ openclaw logs --follow
If you set `channels.discord.allowBots=true`, use strict mention and allowlist rules to avoid loop behavior.
</Accordion>
<Accordion title="Voice STT drops with DecryptionFailed(...)">
- keep OpenClaw current (`openclaw update`) so the Discord voice receive recovery logic is present
- confirm `channels.discord.voice.daveEncryption=true` (default)
- start from `channels.discord.voice.decryptionFailureTolerance=24` (upstream default) and tune only if needed
- watch logs for:
- `discord voice: DAVE decrypt failures detected`
- `discord voice: repeated decrypt failures; attempting rejoin`
- if failures continue after automatic rejoin, collect logs and compare against [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)
</Accordion>
</AccordionGroup>
## Configuration reference pointers

View File

@@ -153,7 +153,8 @@ Configure your tunnel's ingress rules to only route the webhook path:
Use these identifiers for delivery and allowlists:
- Direct messages: `users/<userId>` (recommended) or raw email `name@example.com` (mutable principal).
- Direct messages: `users/<userId>` (recommended).
- Raw email `name@example.com` is mutable and only used for direct allowlist matching when `channels.googlechat.dangerouslyAllowNameMatching: true`.
- Deprecated: `users/<email>` is treated as a user id, not an email allowlist.
- Spaces: `spaces/<spaceId>`.
@@ -171,7 +172,7 @@ Use these identifiers for delivery and allowlists:
botUser: "users/1234567890", // optional; helps mention detection
dm: {
policy: "pairing",
allowFrom: ["users/1234567890", "name@example.com"],
allowFrom: ["users/1234567890"],
},
groupPolicy: "allowlist",
groups: {
@@ -194,6 +195,7 @@ Notes:
- Service account credentials can also be passed inline with `serviceAccount` (JSON string).
- Default webhook path is `/googlechat` if `webhookPath` isnt set.
- `dangerouslyAllowNameMatching` re-enables mutable email principal matching for allowlists (break-glass compatibility mode).
- Reactions are available via the `reactions` tool and `channels action` when `actions.reactions` is enabled.
- `typingIndicator` supports `none`, `message` (default), and `reaction` (reaction requires user OAuth).
- Attachments are downloaded through the Chat API and stored in the media pipeline (size capped by `mediaMaxMb`).

View File

@@ -1,5 +1,5 @@
---
summary: "Group chat behavior across surfaces (WhatsApp/Telegram/Discord/Slack/Signal/iMessage/Microsoft Teams)"
summary: "Group chat behavior across surfaces (WhatsApp/Telegram/Discord/Slack/Signal/iMessage/Microsoft Teams/Zalo)"
read_when:
- Changing group chat behavior or mention gating
title: "Groups"
@@ -7,7 +7,7 @@ title: "Groups"
# Groups
OpenClaw treats group chats consistently across surfaces: WhatsApp, Telegram, Discord, Slack, Signal, iMessage, Microsoft Teams.
OpenClaw treats group chats consistently across surfaces: WhatsApp, Telegram, Discord, Slack, Signal, iMessage, Microsoft Teams, Zalo.
## Beginner intro (2 minutes)
@@ -183,7 +183,7 @@ Control how group/room messages are handled per channel:
Notes:
- `groupPolicy` is separate from mention-gating (which requires @mentions).
- WhatsApp/Telegram/Signal/iMessage/Microsoft Teams: use `groupAllowFrom` (fallback: explicit `allowFrom`).
- WhatsApp/Telegram/Signal/iMessage/Microsoft Teams/Zalo: use `groupAllowFrom` (fallback: explicit `allowFrom`).
- Discord: allowlist uses `channels.discord.guilds.<id>.channels`.
- Slack: allowlist uses `channels.slack.channels`.
- Matrix: allowlist uses `channels.matrix.groups` (room IDs, aliases, or names). Use `channels.matrix.groupAllowFrom` to restrict senders; per-room `users` allowlists are also supported.

View File

@@ -57,7 +57,8 @@ Config keys:
- Per-channel controls (channel + sender + mention rules): `channels.irc.groups["#channel"]`
- `channels.irc.groupPolicy="open"` allows unconfigured channels (**still mention-gated by default**)
Allowlist entries can use nick or `nick!user@host` forms.
Allowlist entries should use stable sender identities (`nick!user@host`).
Bare nick matching is mutable and only enabled when `channels.irc.dangerouslyAllowNameMatching: true`.
### Common gotcha: `allowFrom` is for DMs, not channels

View File

@@ -101,7 +101,8 @@ Notes:
## Channels (groups)
- Default: `channels.mattermost.groupPolicy = "allowlist"` (mention-gated).
- Allowlist senders with `channels.mattermost.groupAllowFrom` (user IDs or `@username`).
- Allowlist senders with `channels.mattermost.groupAllowFrom` (user IDs recommended).
- `@username` matching is mutable and only enabled when `channels.mattermost.dangerouslyAllowNameMatching: true`.
- Open channels: `channels.mattermost.groupPolicy="open"` (mention-gated).
- Runtime note: if `channels.mattermost` is completely missing, runtime falls back to `groupPolicy="allowlist"` for group checks (even if `channels.defaults.groupPolicy` is set).

View File

@@ -87,7 +87,9 @@ Disable with:
**DM access**
- Default: `channels.msteams.dmPolicy = "pairing"`. Unknown senders are ignored until approved.
- `channels.msteams.allowFrom` accepts AAD object IDs, UPNs, or display names. The wizard resolves names to IDs via Microsoft Graph when credentials allow.
- `channels.msteams.allowFrom` should use stable AAD object IDs.
- UPNs/display names are mutable; direct matching is disabled by default and only enabled with `channels.msteams.dangerouslyAllowNameMatching: true`.
- The wizard can resolve names to IDs via Microsoft Graph when credentials allow.
**Group access**
@@ -454,7 +456,8 @@ Key settings (see `/gateway/configuration` for shared channel patterns):
- `channels.msteams.webhook.port` (default `3978`)
- `channels.msteams.webhook.path` (default `/api/messages`)
- `channels.msteams.dmPolicy`: `pairing | allowlist | open | disabled` (default: pairing)
- `channels.msteams.allowFrom`: allowlist for DMs (AAD object IDs, UPNs, or display names). The wizard resolves names to IDs during setup when Graph access is available.
- `channels.msteams.allowFrom`: DM allowlist (AAD object IDs recommended). The wizard resolves names to IDs during setup when Graph access is available.
- `channels.msteams.dangerouslyAllowNameMatching`: break-glass toggle to re-enable mutable UPN/display-name matching.
- `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).

View File

@@ -171,6 +171,7 @@ For actions/directory reads, user token can be preferred when configured. For wr
- channel allowlist entries and DM allowlist entries are resolved at startup when token access allows
- unresolved entries are kept as configured
- inbound authorization matching is ID-first by default; direct username/slug matching requires `channels.slack.dangerouslyAllowNameMatching: true`
</Tab>
@@ -513,6 +514,7 @@ Primary reference:
High-signal Slack fields:
- mode/auth: `mode`, `botToken`, `appToken`, `signingSecret`, `webhookPath`, `accounts.*`
- DM access: `dm.enabled`, `dmPolicy`, `allowFrom` (legacy: `dm.policy`, `dm.allowFrom`), `dm.groupEnabled`, `dm.groupChannels`
- compatibility toggle: `dangerouslyAllowNameMatching` (break-glass; keep off unless needed)
- channel access: `groupPolicy`, `channels.*`, `channels.*.users`, `channels.*.requireMention`
- threading/history: `replyToMode`, `replyToModeByChatType`, `thread.*`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit`
- delivery: `textChunkLimit`, `chunkMode`, `mediaMaxMb`, `streaming`, `nativeStreaming`

View File

@@ -72,6 +72,7 @@ Config values override env vars.
- `dmPolicy: "allowlist"` is the recommended default.
- `allowedUserIds` accepts a list (or comma-separated string) of Synology user IDs.
- In `allowlist` mode, an empty `allowedUserIds` list is treated as misconfiguration and the webhook route will not start (use `dmPolicy: "open"` for allow-all).
- `dmPolicy: "open"` allows any sender.
- `dmPolicy: "disabled"` blocks DMs.
- Pairing approvals work with:

View File

@@ -7,7 +7,7 @@ title: "Zalo"
# Zalo (Bot API)
Status: experimental. Direct messages only; groups coming soon per Zalo docs.
Status: experimental. DMs are supported; group handling is available with explicit group policy controls.
## Plugin required
@@ -51,7 +51,7 @@ It is a good fit for support or notifications where you want deterministic routi
- A Zalo Bot API channel owned by the Gateway.
- Deterministic routing: replies go back to Zalo; the model never chooses channels.
- DMs share the agent's main session.
- Groups are not yet supported (Zalo docs state "coming soon").
- Groups are supported with policy controls (`groupPolicy` + `groupAllowFrom`) and default to fail-closed allowlist behavior.
## Setup (fast path)
@@ -107,6 +107,16 @@ Multi-account support: use `channels.zalo.accounts` with per-account tokens and
- Pairing is the default token exchange. Details: [Pairing](/channels/pairing)
- `channels.zalo.allowFrom` accepts numeric user IDs (no username lookup available).
## Access control (Groups)
- `channels.zalo.groupPolicy` controls group inbound handling: `open | allowlist | disabled`.
- Default behavior is fail-closed: `allowlist`.
- `channels.zalo.groupAllowFrom` restricts which sender IDs can trigger the bot in groups.
- If `groupAllowFrom` is unset, Zalo falls back to `allowFrom` for sender checks.
- `groupPolicy: "disabled"` blocks all group messages.
- `groupPolicy: "open"` allows any group member (mention-gated).
- Runtime note: if `channels.zalo` is missing entirely, runtime still falls back to `groupPolicy="allowlist"` for safety.
## Long-polling vs webhook
- Default: long-polling (no public URL required).
@@ -130,16 +140,16 @@ Multi-account support: use `channels.zalo.accounts` with per-account tokens and
## Capabilities
| Feature | Status |
| --------------- | ------------------------------ |
| Direct messages | ✅ Supported |
| Groups | ❌ Coming soon (per Zalo docs) |
| Media (images) | ✅ Supported |
| Reactions | ❌ Not supported |
| Threads | ❌ Not supported |
| Polls | ❌ Not supported |
| Native commands | ❌ Not supported |
| Streaming | ⚠️ Blocked (2000 char limit) |
| Feature | Status |
| --------------- | -------------------------------------------------------- |
| Direct messages | ✅ Supported |
| Groups | ⚠️ Supported with policy controls (allowlist by default) |
| Media (images) | ✅ Supported |
| Reactions | ❌ Not supported |
| Threads | ❌ Not supported |
| Polls | ❌ Not supported |
| Native commands | ❌ Not supported |
| Streaming | ⚠️ Blocked (2000 char limit) |
## Delivery targets (CLI/cron)
@@ -172,6 +182,8 @@ Provider options:
- `channels.zalo.tokenFile`: read token from file path.
- `channels.zalo.dmPolicy`: `pairing | allowlist | open | disabled` (default: pairing).
- `channels.zalo.allowFrom`: DM allowlist (user IDs). `open` requires `"*"`. The wizard will ask for numeric IDs.
- `channels.zalo.groupPolicy`: `open | allowlist | disabled` (default: allowlist).
- `channels.zalo.groupAllowFrom`: group sender allowlist (user IDs). Falls back to `allowFrom` when unset.
- `channels.zalo.mediaMaxMb`: inbound/outbound media cap (MB, default 5).
- `channels.zalo.webhookUrl`: enable webhook mode (HTTPS required).
- `channels.zalo.webhookSecret`: webhook secret (8-256 chars).
@@ -186,6 +198,8 @@ Multi-account options:
- `channels.zalo.accounts.<id>.enabled`: enable/disable account.
- `channels.zalo.accounts.<id>.dmPolicy`: per-account DM policy.
- `channels.zalo.accounts.<id>.allowFrom`: per-account allowlist.
- `channels.zalo.accounts.<id>.groupPolicy`: per-account group policy.
- `channels.zalo.accounts.<id>.groupAllowFrom`: per-account group sender allowlist.
- `channels.zalo.accounts.<id>.webhookUrl`: per-account webhook URL.
- `channels.zalo.accounts.<id>.webhookSecret`: per-account webhook secret.
- `channels.zalo.accounts.<id>.webhookPath`: per-account webhook path.