Skip to content

feat(feishu): add support for merge_forward message parsing#28707

Merged
Takhoffman merged 2 commits intoopenclaw:mainfrom
tsu-builds:feat/feishu-merge-forward-support
Feb 28, 2026
Merged

feat(feishu): add support for merge_forward message parsing#28707
Takhoffman merged 2 commits intoopenclaw:mainfrom
tsu-builds:feat/feishu-merge-forward-support

Conversation

@tsu-builds
Copy link
Copy Markdown
Contributor

OpenClaw PR: Support Feishu merge_forward message parsing

Summary

This PR adds support for parsing Feishu merge_forward (合并转发) messages. Previously, these messages would only show a placeholder text "Merged and Forwarded Message" without the actual content.

Problem

When a user sends a merged/forwarded message in Feishu:

  1. The websocket event's message.content field only contains the placeholder string "Merged and Forwarded Message"
  2. The actual sub-messages are not included in the websocket payload
  3. This makes it impossible for the agent to see the forwarded content

Solution

  1. Detect merge_forward message type in handleFeishuMessage()
  2. Call the Feishu im.message.get API with the message_id
  3. The API returns all sub-messages in the items array, with upper_message_id pointing to the merge_forward container
  4. Parse and format the sub-messages into readable text

Changes

extensions/feishu/src/bot.ts

  1. Modified parseMessageContent(): Return a loading placeholder for merge_forward type

  2. Added parseMergeForwardContent(): Async function to parse the API response and format sub-messages

  3. Added formatSubMessageContent(): Helper to format individual sub-message content based on type

  4. Modified handleFeishuMessage(): Added logic to fetch and expand merge_forward messages via API

Example Output

Before:

[Merged and Forwarded Message]

After:

[Merged and Forwarded Messages]
- First message content
- Second message content
- [Image]
- Third message content
... and 5 more messages

Testing

Tested with real Feishu merge_forward messages containing:

  • Text messages
  • Rich text (post) messages
  • Images
  • Nested replies

Notes

  • Sub-messages are limited to 50 to prevent excessive API calls
  • Nested merge_forward messages show as [Nested Merged Forward] (no recursive expansion)
  • The API call adds slight latency (~200-500ms) but is necessary since websocket doesn't include sub-message content

@openclaw-barnacle openclaw-barnacle bot added channel: feishu Channel integration: feishu size: S labels Feb 27, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e03338e18d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

}

// Filter to only sub-messages (those with upper_message_id, skip the merge_forward container itself)
const subMessages = items.filter((item) => item.upper_message_id);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict merge-forward expansion to direct child items

The current filter keeps every item with a truthy upper_message_id, which means nested descendants are treated as top-level entries whenever Feishu returns recursive items for nested merge_forward content. In that case, grandchildren from nested forwards are expanded as regular bullets (despite the "[Nested Merged Forward]" placeholder intent), producing duplicated or out-of-scope content; this should filter by the current container message id instead of any non-empty parent id.

Useful? React with 👍 / 👎.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 27, 2026

Greptile Summary

Added support for parsing Feishu merge_forward (合并转发) messages by fetching full message content via API and expanding sub-messages into readable text.

Key changes:

  • Added parseMessageContent() placeholder for merge_forward type
  • Added parseMergeForwardContent() to fetch and format sub-messages from API response (limits to 50 messages)
  • Added formatSubMessageContent() to handle different message types (text, post, image, file, etc.)
  • Modified handleFeishuMessage() to detect merge_forward messages and fetch full content via client.im.message.get()

Issues found:

  • Logic bug in API response handling - see inline comment for fix

Confidence Score: 4/5

  • Safe to merge with one minor logic fix in error handling
  • Found one logic bug in line 682 where empty items array produces misleading error message, but this is a non-critical edge case. The feature implementation is sound with proper error handling, type definitions match existing patterns, and the API integration follows established conventions from send.ts
  • Line 682 in extensions/feishu/src/bot.ts needs the length > 0 check removed

Last reviewed commit: e03338e

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

path: { message_id: event.message.message_id },
})) as { code?: number; data?: { items?: unknown[] } };

if (response.code === 0 && response.data?.items && response.data.items.length > 0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove length > 0 check - causes misleading "could not fetch" error when API returns empty items array. parseMergeForwardContent already handles empty arrays correctly (returns "no sub-messages").

Suggested change
if (response.code === 0 && response.data?.items && response.data.items.length > 0) {
if (response.code === 0 && response.data?.items) {
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/feishu/src/bot.ts
Line: 682

Comment:
Remove `length > 0` check - causes misleading "could not fetch" error when API returns empty items array. `parseMergeForwardContent` already handles empty arrays correctly (returns "no sub-messages").

```suggestion
      if (response.code === 0 && response.data?.items) {
```

How can I resolve this? If you propose a fix, please make it concise.

Takhoffman added a commit to tsu-builds/openclaw that referenced this pull request Feb 28, 2026
tsu-builds and others added 2 commits February 27, 2026 20:42
- Detect merge_forward message type in handleFeishuMessage()
- Fetch sub-messages via im.message.get API (websocket event doesn't include them)
- Parse and format sub-messages into readable text
- Support text, post, image, file, audio, video, sticker message types
- Limit to 50 sub-messages to prevent excessive API calls
- Handle nested merge_forward as placeholder (no recursive expansion)

Fixes: Feishu merged/forwarded messages now display actual content instead of just 'Merged and Forwarded Message' placeholder.
@Takhoffman Takhoffman force-pushed the feat/feishu-merge-forward-support branch from 09da56d to e23aeca Compare February 28, 2026 02:56
@Takhoffman Takhoffman merged commit f53ef73 into openclaw:main Feb 28, 2026
3 checks passed
@Takhoffman
Copy link
Copy Markdown
Contributor

PR #28707 - feat(feishu): add support for merge_forward message parsing (#28707)

Merged via squash.

  • Merge commit: f53ef73
  • Verified: pnpm build, pnpm check, pnpm test:macmini
  • Changes made:
    M CHANGELOG.md
    M extensions/feishu/src/bot.test.ts
    M extensions/feishu/src/bot.ts
  • Why these changes were made:
    Deep review found the feature direction was sound, but merge-forward parsing needed explicit regression coverage and small implementation hardening before landing.
  • Changelog: CHANGELOG.md updated=true required=true opt_out=false

Thanks @tsu-builds!

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e23aeca69f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

}

// Filter to only sub-messages (those with upper_message_id, skip the merge_forward container itself)
const subMessages = items.filter((item) => item.upper_message_id);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Filter merge-forward items by container message ID

items.filter((item) => item.upper_message_id) treats every descendant as a top-level sub-message, so when Feishu returns recursive items (for nested merged forwards or nested replies) grandchildren get flattened into this message body and can duplicate/out-of-scope content. This breaks the intended [Nested Merged Forward] boundary and can feed unrelated nested text to the agent; restrict the expansion to items whose upper_message_id matches the current merge-forward container message ID.

Useful? React with 👍 / 👎.

r4jiv007 pushed a commit to r4jiv007/openclaw that referenced this pull request Feb 28, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
mylukin pushed a commit to mylukin/openclaw that referenced this pull request Feb 28, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit ed8e6f7)
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit ed8e6f7)
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit ed8e6f7)
vincentkoc pushed a commit to Sid-Qin/openclaw that referenced this pull request Feb 28, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
vincentkoc pushed a commit to rylena/rylen-openclaw that referenced this pull request Feb 28, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
newtontech pushed a commit to newtontech/openclaw-fork that referenced this pull request Feb 28, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Mar 1, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Mar 1, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 1, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit f53ef73)
ansh pushed a commit to vibecode/openclaw that referenced this pull request Mar 2, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
safzanpirani pushed a commit to safzanpirani/clawdbot that referenced this pull request Mar 2, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
venjiang pushed a commit to venjiang/openclaw that referenced this pull request Mar 2, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
robertchang-ga pushed a commit to robertchang-ga/openclaw that referenced this pull request Mar 2, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
execute008 pushed a commit to execute008/openclaw that referenced this pull request Mar 2, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 3, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit f53ef73)
dorgonman pushed a commit to kanohorizonia/openclaw that referenced this pull request Mar 3, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
sachinkundu pushed a commit to sachinkundu/openclaw that referenced this pull request Mar 6, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 15, 2026
…#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit f53ef73)
alexey-pelykh added a commit to remoteclaw/remoteclaw that referenced this pull request Mar 15, 2026
…#28707) thanks @tsu-builds (#1461)

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini



(cherry picked from commit f53ef73)

Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: tsu-builds <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants