


















@@ -78,6 +78,31 @@ const groupNameCache = new Map<string, { name: string; expiresAt: number }>();
7878const GROUP_NAME_CACHE_TTL_MS = 30 * 60 * 1000; // 30 minutes
7979const GROUP_NAME_CACHE_MAX_SIZE = 500; // hard cap
808081+type FeishuGroupSessionScope = "group" | "group_sender" | "group_topic" | "group_topic_sender";
82+83+function resolveConfiguredFeishuGroupSessionScope(params: {
84+groupConfig?: {
85+groupSessionScope?: FeishuGroupSessionScope;
86+topicSessionMode?: "enabled" | "disabled";
87+};
88+feishuCfg?: {
89+groupSessionScope?: FeishuGroupSessionScope;
90+topicSessionMode?: "enabled" | "disabled";
91+};
92+}): FeishuGroupSessionScope {
93+const legacyTopicSessionMode =
94+params.groupConfig?.topicSessionMode ?? params.feishuCfg?.topicSessionMode ?? "disabled";
95+return (
96+params.groupConfig?.groupSessionScope ??
97+params.feishuCfg?.groupSessionScope ??
98+(legacyTopicSessionMode === "enabled" ? "group_topic" : "group")
99+);
100+}
101+102+function isFeishuTopicSessionScope(scope: FeishuGroupSessionScope): boolean {
103+return scope === "group_topic" || scope === "group_topic_sender";
104+}
105+81106function evictGroupNameCache(): void {
82107const now = Date.now();
83108for (const [key, val] of groupNameCache) {
@@ -503,6 +528,36 @@ export async function handleFeishuMessage(params: {
503528const groupConfig = isGroup
504529 ? resolveFeishuGroupConfig({ cfg: feishuCfg, groupId: ctx.chatId })
505530 : undefined;
531+const groupSessionScope = isGroup
532+ ? resolveConfiguredFeishuGroupSessionScope({ groupConfig, feishuCfg })
533+ : null;
534+let effectiveThreadId = ctx.threadId;
535+if (
536+isGroup &&
537+ctx.chatType === "topic_group" &&
538+!effectiveThreadId &&
539+isFeishuTopicSessionScope(groupSessionScope ?? "group")
540+) {
541+try {
542+const messageInfo = await getMessageFeishu({
543+ cfg,
544+accountId: account.accountId,
545+messageId: ctx.messageId,
546+});
547+const hydratedThreadId = messageInfo?.threadId?.trim();
548+if (hydratedThreadId) {
549+ctx = { ...ctx, threadId: hydratedThreadId };
550+effectiveThreadId = hydratedThreadId;
551+log(
552+`feishu[${account.accountId}]: hydrated topic thread_id=${hydratedThreadId} for message=${ctx.messageId}`,
553+);
554+}
555+} catch (err) {
556+log(
557+`feishu[${account.accountId}]: failed to hydrate topic thread_id for message=${ctx.messageId}: ${String(err)}`,
558+);
559+}
560+}
506561const effectiveGroupSenderAllowFrom = isGroup
507562 ? (groupConfig?.allowFrom?.length ?? 0) > 0
508563 ? (groupConfig?.allowFrom ?? [])
@@ -514,7 +569,7 @@ export async function handleFeishuMessage(params: {
514569senderOpenId: ctx.senderOpenId,
515570messageId: ctx.messageId,
516571rootId: ctx.rootId,
517-threadId: ctx.threadId,
572+threadId: effectiveThreadId,
518573chatType: ctx.chatType,
519574 groupConfig,
520575 feishuCfg,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。