Skip to content

fix(feishu): support Lark private chats as direct messages#31400

Merged
Takhoffman merged 2 commits intoopenclaw:mainfrom
stakeswky:fix/31351-lark-private-chat
Mar 2, 2026
Merged

fix(feishu): support Lark private chats as direct messages#31400
Takhoffman merged 2 commits intoopenclaw:mainfrom
stakeswky:fix/31351-lark-private-chat

Conversation

@stakeswky
Copy link

Summary

  • Treat Lark/Feishu chat_type=private as a direct message path (same handling as p2p).
  • Avoid DM policy/mention logic regressions caused by strict p2p checks.

Root cause

Lark private chats can arrive with chat_type=private, but the Feishu channel only treated DMs as chat_type === "p2p". This prevented private chats from following the intended DM handling path.

Changes

  • Extend Feishu event/context types to include private.
  • Detect direct messages as chat_type !== "group" in mention-forward logic.
  • Use explicit isDirect in message handling so DM policy gating applies to both p2p and private.
  • Normalize reaction synthetic events to p2p|group while remaining type-safe.
  • Update tests for the broadened chat type union.

Validation

pnpm test:extensions -- \
  extensions/feishu/src/bot.checkBotMentioned.test.ts \
  extensions/feishu/src/monitor.reaction.test.ts

Fixes #31351

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 2, 2026

Greptile Summary

This PR broadens the Feishu/Lark channel's concept of a "direct message" from the strictly p2p chat type to also include private, fixing a regression where private-chat messages bypassed DM policy gating and mention-forward detection. The fix is consistent across the type layer (types.ts, bot.ts, monitor.account.ts), the mention logic (mention.ts), and the DM policy gate in handleFeishuMessage.

Key changes:

  • The chat_type union in FeishuMessageEvent, FeishuMessageContext, and FeishuReactionCreatedEvent is widened to "p2p" | "group" | "private".
  • isDirect (!isGroup) is used as the canonical DM predicate in handleFeishuMessage, replacing the direct !isGroup check at the policy gate.
  • isMentionForwardRequest now uses !== "group" to detect DMs, correctly treating private chats the same as p2p.
  • Synthetic reaction events normalize privatep2p to avoid propagating the new type value through the existing reaction handling path.

Confidence Score: 4/5

  • This PR is safe to merge; the logic is correct and well-targeted with one minor type-annotation style concern.
  • The core logic changes are sound: isDirect = !isGroup is semantically equivalent to the prior !isGroup check; !== "group" correctly widens the DM predicate in mention detection; and reaction event normalization prevents private from leaking into downstream handlers. The one deduction is for the unnecessarily wide "p2p" | "group" | "private" annotation on syntheticChatType in monitor.account.ts, which can never actually be "private" at runtime and could mislead future maintainers.
  • No files require special attention beyond the minor type annotation note in extensions/feishu/src/monitor.account.ts.

Last reviewed commit: eeea06b

Copy link
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.

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +96 to +97
const syntheticChatType: "p2p" | "group" | "private" =
event.chat_type === "group" ? "group" : "p2p";
Copy link
Contributor

Choose a reason for hiding this comment

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

Overly-wide type annotation that can never be "private"

The explicit type annotation "p2p" | "group" | "private" is misleading here because the ternary expression can only ever evaluate to "p2p" or "group""private" is normalized away and will never actually be assigned to syntheticChatType. Without the explicit annotation TypeScript would infer the narrower and more accurate "p2p" | "group". Keeping "private" in the annotation suggests to future readers that a synthetic reaction event could carry chat_type === "private", which will never happen.

Suggested change
const syntheticChatType: "p2p" | "group" | "private" =
event.chat_type === "group" ? "group" : "p2p";
const syntheticChatType: "p2p" | "group" =
event.chat_type === "group" ? "group" : "p2p";
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/feishu/src/monitor.account.ts
Line: 96-97

Comment:
**Overly-wide type annotation that can never be `"private"`**

The explicit type annotation `"p2p" | "group" | "private"` is misleading here because the ternary expression can only ever evaluate to `"p2p"` or `"group"``"private"` is normalized away and will never actually be assigned to `syntheticChatType`. Without the explicit annotation TypeScript would infer the narrower and more accurate `"p2p" | "group"`. Keeping `"private"` in the annotation suggests to future readers that a synthetic reaction event could carry `chat_type === "private"`, which will never happen.

```suggestion
  const syntheticChatType: "p2p" | "group" =
    event.chat_type === "group" ? "group" : "p2p";
```

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

@Takhoffman Takhoffman force-pushed the fix/31351-lark-private-chat branch from eeea06b to 9584610 Compare March 2, 2026 23:04
@Takhoffman Takhoffman merged commit 3043e68 into openclaw:main Mar 2, 2026
9 of 10 checks passed
@Takhoffman
Copy link
Contributor

PR #31400 - fix(feishu): support Lark private chats as direct messages (#31400)

Merged after verification.

  • Merge commit: 3043e68
  • Verified: pnpm test -- extensions/feishu/src/bot.checkBotMentioned.test.ts; pnpm build
  • Notes: pnpm check failed on unrelated baseline lint errors in untouched files; pnpm test:macmini was not run after that block.
  • Autoland updates:
    M CHANGELOG.md
  • Changelog: CHANGELOG.md updated=true required=true opt_out=false

dawi369 pushed a commit to dawi369/davis that referenced this pull request Mar 3, 2026
…31400) thanks @stakeswky

Verified:
- pnpm test -- extensions/feishu/src/bot.checkBotMentioned.test.ts
- pnpm build
- pnpm check (blocked by unrelated baseline lint errors in untouched files)
- pnpm test:macmini (not run after pnpm check blocked)

Co-authored-by: stakeswky <64798754+stakeswky@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
OWALabuy pushed a commit to kcinzgg/openclaw that referenced this pull request Mar 4, 2026
…31400) thanks @stakeswky

Verified:
- pnpm test -- extensions/feishu/src/bot.checkBotMentioned.test.ts
- pnpm build
- pnpm check (blocked by unrelated baseline lint errors in untouched files)
- pnpm test:macmini (not run after pnpm check blocked)

Co-authored-by: stakeswky <64798754+stakeswky@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…31400) thanks @stakeswky

Verified:
- pnpm test -- extensions/feishu/src/bot.checkBotMentioned.test.ts
- pnpm build
- pnpm check (blocked by unrelated baseline lint errors in untouched files)
- pnpm test:macmini (not run after pnpm check blocked)

Co-authored-by: stakeswky <64798754+stakeswky@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
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: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: In Lark, communication is only possible through group chat @ mentions and bots; private chat is not supported.

2 participants