import type { FeishuMessageEvent } from "./bot.js"; /** * Mention target user info */ export type MentionTarget = { openId: string; name: string; key: string; // Placeholder in original message, e.g. @_user_1 }; /** * Extract mention targets from message event (excluding the bot itself) */ export function extractMentionTargets( event: FeishuMessageEvent, botOpenId?: string, ): MentionTarget[] { const mentions = event.message.mentions ?? []; return mentions .filter((m) => { // Exclude the bot itself if (botOpenId && m.id.open_id === botOpenId) { return false; } // Must have open_id return !!m.id.open_id; }) .map((m) => ({ openId: m.id.open_id!, name: m.name, key: m.key, })); } /** * Check if message is a mention forward request * Rules: * - Group: message mentions bot + at least one other user * - DM: message mentions any user (no need to mention bot) */ export function isMentionForwardRequest(event: FeishuMessageEvent, botOpenId?: string): boolean { const mentions = event.message.mentions ?? []; if (mentions.length === 0) { return false; } const isDirectMessage = event.message.chat_type === "p2p"; const hasOtherMention = mentions.some((m) => m.id.open_id !== botOpenId); if (isDirectMessage) { // DM: trigger if any non-bot user is mentioned return hasOtherMention; } else { // Group: need to mention both bot and other users const hasBotMention = mentions.some((m) => m.id.open_id === botOpenId); return hasBotMention && hasOtherMention; } } /** * Extract message body from text (remove @ placeholders) */ export function extractMessageBody(text: string, allMentionKeys: string[]): string { let result = text; // Remove all @ placeholders for (const key of allMentionKeys) { result = result.replace(new RegExp(key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), ""); } return result.replace(/\s+/g, " ").trim(); } /** * Format @mention for text message */ export function formatMentionForText(target: MentionTarget): string { return `${target.name}`; } /** * Format @everyone for text message */ export function formatMentionAllForText(): string { return `Everyone`; } /** * Format @mention for card message (lark_md) */ export function formatMentionForCard(target: MentionTarget): string { return ``; } /** * Format @everyone for card message */ export function formatMentionAllForCard(): string { return ``; } /** * Build complete message with @mentions (text format) */ export function buildMentionedMessage(targets: MentionTarget[], message: string): string { if (targets.length === 0) { return message; } const mentionParts = targets.map((t) => formatMentionForText(t)); return `${mentionParts.join(" ")} ${message}`; } /** * Build card content with @mentions (Markdown format) */ export function buildMentionedCardContent(targets: MentionTarget[], message: string): string { if (targets.length === 0) { return message; } const mentionParts = targets.map((t) => formatMentionForCard(t)); return `${mentionParts.join(" ")} ${message}`; }