mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-14 18:18:37 +00:00
feat(feishu): add /addwriter /removewriter /writers commands
Adds parity with Telegram and Discord for file-writer management commands, closing the UX gap where users saw an error mentioning /addwriter but the Feishu channel had no handler. - New maybeHandleWriterCommand routes /addwriter, /removewriter, /writers from the Feishu inbound flow. Runs at step 5a — after checkGroupPolicy — so commands never bypass allowlist or pairing enforcement. Step 2a rejects slash commands in DM chats early so users get a clear hint without waking the agent pipeline. - Target user is identified via reply-to (fetches parent message sender) or first non-bot @mention. A bare /addwriter with no target shows the usage hint instead of silently self-granting, preventing accidental privilege capture in empty-writer groups. - Refuses to run while botOpenID is unresolved so a @mention of the bot itself cannot be mistaken for a human target. - 10s context timeout on each handler bounds worst-case Lark API latency (parent message lookup, permission store access). - feishu.New() gains variadic Option parameter with WithAgentStore and WithConfigPermStore mirroring Telegram's pattern. The gateway now wires pgStores.Agents and pgStores.ConfigPermissions into Feishu channel on startup. - 12 new unit tests with fakeConfigPermStore and httptest Lark server cover DM rejection, nil-store graceful degradation, bootstrap via self-mention, bare-command usage hint, bot-probe race refusal, non-writer rejection, grant via mention, remove last-writer guard, empty and populated list output, reply-to target resolution via Lark im/v1/messages lookup, and non-command passthrough. 40 total tests in the feishu package, all green with -race. Closes #818.
This commit is contained in:
1 parent
934ab7e485
commit
20de0e332e
7 files changed
+824
-29
No files matched your search
@@ -397,6 +397,29 @@ When a user pastes a Lark docx (document) URL in a message, the channel automati
|
||||
|
||||
**Configuration**: No new config flags. Supported document type and cache tunables (8000 rune limit, 10-URL cap, 5-min TTL, 128-entry cache) are hardcoded.
|
||||
|
||||
### Writer Management Commands
|
||||
|
||||
Group chats support file-write permission management via slash commands. Permissions are scoped to the group via `group:feishu:<chatID>`. DM users who attempt these commands receive a hint that they only work in groups.
|
||||
|
||||
**Commands** (group-only):
|
||||
|
||||
| Command | Description | Requires Target | Permission |
|
||||
|---------|-------------|:---:|:---:|
|
||||
| `/addwriter <@user or reply>` | Grant file_writer permission to target user | Yes | Writers only |
|
||||
| `/removewriter <@user or reply>` | Revoke file_writer permission from target user | Yes | Writers only |
|
||||
| `/writers` | List current group writers with displayName | No | -- |
|
||||
|
||||
**Target specification**: Commands require explicit identification via reply-to or @mention. Bare `/addwriter` without a target is rejected — prevents accidental privilege capture.
|
||||
|
||||
**Bootstrap behavior**: Groups with no writers allow the first writer to grant themselves via `/addwriter @self` (explicit self-mention). This enables initial configuration without external admin intervention.
|
||||
|
||||
**Authorization**:
|
||||
- Only existing writers can manage the writer list (enforce via `IsGroupFileWriter` check)
|
||||
- Last-writer guard: If removing a writer would leave zero writers, operation is rejected with user-facing message
|
||||
- Database errors are fail-open; security issues are logged as `security.writer_check_failed`
|
||||
|
||||
**Implementation**: Timeout of 10 seconds bounds Feishu API calls. Requires `AgentStore` and `ConfigPermissionStore` wired to the Feishu channel via constructor options.
|
||||
|
||||
---
|
||||
|
||||
## 7. Discord
|
||||
|
||||
+5
-12
@@ -34,21 +34,14 @@ All notable changes to GoClaw Gateway are documented here. Format follows [Keep
|
||||
|
||||
### Fixed
|
||||
|
||||
#### Feishu/Lark Thread Reply Routing — Issue #818 Phase 1 (2026-04-11)
|
||||
- **Thread detection**: Inbound messages with `thread_id` now properly route responses back to the same Feishu thread via `/open-apis/im/v1/messages/{id}/reply` endpoint
|
||||
- **Metadata propagation**: New `feishu_reply_target_id` metadata key added to `routingMetaKeys` allowlist so all outbound messages (text, cards, files, reactions) land in the correct thread
|
||||
- **Graceful fallback**: If thread root is deleted, channel falls back to regular `SendMessage()` for robustness
|
||||
#### Feishu/Lark Writer Management Commands — Issue #818 Closed (2026-04-11)
|
||||
- **Issue #818 resolution**: Closes UX gap where users saw `/addwriter` error messages but Feishu had no handler
|
||||
- **Phase 1 — Thread reply routing**: Inbound messages with `thread_id` now properly route responses back to the same Feishu thread via `/open-apis/im/v1/messages/{id}/reply`. New `feishu_reply_target_id` metadata key included in `routingMetaKeys` allowlist. Graceful fallback to `SendMessage()` if thread root deleted
|
||||
- **Phase 2 — Document auto-fetch**: Pasted Lark docx URLs auto-detected and fetched via `/open-apis/docx/v1/documents/{id}/raw_content`. Content injected as `[Lark Doc: URL]` markers. LRU cache (128 entries, 5-min TTL) + 8000-rune truncation per document. Requires `docx:document:readonly` permission + owner grant
|
||||
- **Phase 3 — Writer management commands**: Added `/addwriter <@user or reply>`, `/removewriter`, `/writers` for group file-write permission control. Group-only (DMs rejected early). Requires existing writer authorization. Last-writer guard prevents removing final writer. Empty-writer groups allow bootstrap via explicit `/addwriter @self`. 10s timeout bounds Feishu API calls
|
||||
|
||||
### Added
|
||||
|
||||
#### Feishu/Lark Document URL Auto-Fetch — Issue #818 Phase 2 (2026-04-11)
|
||||
- **Automatic docx fetching**: Users paste Lark docx URLs in chat; channel auto-detects and fetches raw text via `/open-apis/docx/v1/documents/{id}/raw_content`
|
||||
- **Transparent context injection**: Document content embedded as `[Lark Doc: URL] ... [End of Lark Doc]` markers, visible to agent for reasoning
|
||||
- **Smart caching**: LRU cache per channel instance (128 entries, 5-minute TTL) reduces redundant API calls
|
||||
- **Rune-safe truncation**: 8000-rune limit per document prevents token budget overrun
|
||||
- **Access control**: Requires bot app `docx:document:readonly` permission + per-document grant from owner. Access denied displays inline marker with grant instructions
|
||||
- **Safeguards**: Docx-only (sheets/base/wiki deferred), max 10 URLs per message, soft-fail on errors (no message blocks)
|
||||
|
||||
### Testing
|
||||
|
||||
#### Test Coverage Improvement — Wave 1-3 (2026-04-11)
|
||||
|
||||
Reference in new issue
Block a user