fix(feishu): avoid mention forwarding when bot open id is unavailable (#100891)

* fix(feishu): avoid forwarding mentions without bot open id

* fix(feishu): require bot identity for mention forwarding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
xingzhou 2026-07-07 01:54:02 +08:00 committed by GitHub
parent c432c8c014
commit f805bb4e02
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 22 additions and 6 deletions

View file

@ -140,6 +140,17 @@ describe("parseFeishuMessageEvent mentionedBot", () => {
expect(ctx.mentionedBot).toBe(false);
});
it.each([undefined, "", " "])(
"does not create mention-forward targets when botOpenId is %j",
(botOpenId) => {
const event = makeEvent("p2p", [
{ key: "@_user_1", name: "Alice", id: { open_id: "ou_alice" } },
]);
const ctx = parseFeishuMessageEvent(event, botOpenId);
expect(ctx.mentionTargets).toBeUndefined();
},
);
it("returns mentionedBot=false when botOpenId is empty string (probe failed)", () => {
const event = makeEvent("group", [
{ key: "@_user_1", name: "Alice", id: { open_id: "ou_alice" } },

View file

@ -319,8 +319,9 @@ export function parseFeishuMessageEvent(
};
// Detect mention forward request: message mentions bot + at least one other user
if (isMentionForwardRequest(event, botOpenId)) {
const mentionTargets = extractMentionTargets(event, botOpenId);
const mentionForwardBotOpenId = botOpenId?.trim();
if (mentionForwardBotOpenId && isMentionForwardRequest(event, mentionForwardBotOpenId)) {
const mentionTargets = extractMentionTargets(event, mentionForwardBotOpenId);
if (mentionTargets.length > 0) {
ctx.mentionTargets = mentionTargets;
}

View file

@ -28,7 +28,7 @@ export function isFeishuBroadcastMention(mention: FeishuMentionLike): boolean {
*/
export function extractMentionTargets(
event: FeishuMessageEvent,
botOpenId?: string,
botOpenId: string,
): MentionTarget[] {
const mentions = event.message.mentions ?? [];
@ -38,7 +38,7 @@ export function extractMentionTargets(
return false;
}
// Exclude the bot itself
if (botOpenId && m.id.open_id === botOpenId) {
if (m.id.open_id === botOpenId) {
return false;
}
// Must have open_id
@ -62,17 +62,21 @@ export function isMentionForwardRequest(event: FeishuMessageEvent, botOpenId?: s
if (mentions.length === 0) {
return false;
}
const normalizedBotOpenId = botOpenId?.trim();
if (!normalizedBotOpenId) {
return false;
}
const isDirectMessage = !isFeishuGroupChatType(event.message.chat_type);
const userMentions = mentions.filter((m) => !isFeishuBroadcastMention(m));
const hasOtherMention = userMentions.some((m) => m.id.open_id !== botOpenId);
const hasOtherMention = userMentions.some((m) => m.id.open_id !== normalizedBotOpenId);
if (isDirectMessage) {
// DM: trigger if any non-bot user is mentioned
return hasOtherMention;
}
// Group: need to mention both bot and other users
const hasBotMention = userMentions.some((m) => m.id.open_id === botOpenId);
const hasBotMention = userMentions.some((m) => m.id.open_id === normalizedBotOpenId);
return hasBotMention && hasOtherMention;
}