mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-15 04:18:44 +00:00
fix(feishu): route thread replies via Lark reply endpoint
Bot responses to messages inside Lark topic threads were dropped
outside the thread because outbound Send always used the new-message
endpoint. This change:
- Adds LarkClient.ReplyMessage() that POSTs to
/open-apis/im/v1/messages/{id}/reply with reply_in_thread=true
- Parses thread_id from im.message.receive_v1 events (distinct from
root_id which fires on any quote reply) and stamps
feishu_reply_target_id into the message metadata
- Propagates the key through cmd/gateway_consumer_normal.go and the
new package-level routingMetaKeys var in internal/channels/events.go
so block replies and retry notifications also land in thread
- Routes sendText, sendMarkdownCard, sendImage, sendFile, and
sendMediaAttachment via a new deliverMessage helper that falls back
to SendMessage with a warning log on reply endpoint errors (e.g.
thread root deleted)
- Adds 10 unit tests covering routing, fallback, content
double-encoding, and the thread_id gate that prevents plain quote
replies from being silently promoted to threads
Closes #818
This commit is contained in:
1 parent
e8e00d1884
commit
bf272d8dbf
13 files changed
+504
-35
No files matched your search
@@ -367,6 +367,15 @@ When enabled, each thread gets an isolated session:
|
||||
- Different threads within the same group maintain separate conversation histories
|
||||
- Disabled by default
|
||||
|
||||
### Thread Reply Routing
|
||||
|
||||
When a message is sent inside a Lark thread (detected via the `thread_id` field in the inbound event), the inbound handler stamps `metadata["feishu_reply_target_id"]` with the triggering message ID. During outbound delivery, the channel routes responses back to the same thread using `LarkClient.ReplyMessage()` which POSTs to `/open-apis/im/v1/messages/{message_id}/reply` with `reply_in_thread: true`.
|
||||
|
||||
- **Automatic thread detection**: No configuration needed; replies are routed based on inbound `thread_id`
|
||||
- **Metadata propagation**: The `feishu_reply_target_id` key is included in the `routingMetaKeys` allowlist so replies, block replies, and placeholder updates all land in the correct thread
|
||||
- **Graceful fallback**: If the reply endpoint fails (e.g., thread root deleted), the channel falls back to `SendMessage()` for the regular chat
|
||||
- **Applies to**: Text, card, image, and file messages
|
||||
|
||||
---
|
||||
|
||||
## 7. Discord
|
||||
|
||||
@@ -32,6 +32,13 @@ All notable changes to GoClaw Gateway are documented here. Format follows [Keep
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
#### Feishu/Lark Thread Reply Routing — Issue #818 (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
|
||||
|
||||
### Testing
|
||||
|
||||
#### Test Coverage Improvement — Wave 1-3 (2026-04-11)
|
||||
|
||||
Reference in new issue
Block a user