
























@@ -2,6 +2,7 @@ import type {
22AnyMessageContent,
33MiscMessageGenerationOptions,
44proto,
5+GroupMetadata,
56WAMessage,
67WASocket,
78} from "@whiskeysockets/baileys";
@@ -45,6 +46,53 @@ import type { WebInboundMessage, WebListenerCloseReason } from "./types.js";
45464647const LOGGED_OUT_STATUS = DisconnectReason?.loggedOut ?? 401;
4748const RECONNECT_IN_PROGRESS_ERROR = "no active socket - reconnection in progress";
49+const GROUP_META_TTL_MS = 5 * 60 * 1000; // 5 minutes
50+export const WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES = 500;
51+52+export type WhatsAppGroupMetadataCacheEntry = {
53+subject?: string;
54+expires: number;
55+};
56+export type WhatsAppGroupMetadataCache = Map<string, WhatsAppGroupMetadataCacheEntry>;
57+type LocalGroupMetadataCacheEntry = WhatsAppGroupMetadataCacheEntry & {
58+participants?: string[];
59+};
60+61+function rememberGroupMetadataCacheEntry<T extends WhatsAppGroupMetadataCacheEntry>(
62+cache: Map<string, T>,
63+jid: string,
64+entry: T,
65+): void {
66+if (cache.has(jid)) {
67+cache.delete(jid);
68+}
69+cache.set(jid, entry);
70+71+while (cache.size > WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES) {
72+const oldest = cache.keys().next();
73+if (oldest.done) {
74+break;
75+}
76+cache.delete(oldest.value);
77+}
78+}
79+80+function readGroupMetadataCacheEntry<T extends WhatsAppGroupMetadataCacheEntry>(
81+cache: Map<string, T>,
82+jid: string,
83+): T | null {
84+const entry = cache.get(jid);
85+if (!entry) {
86+return null;
87+}
88+if (entry.expires <= Date.now()) {
89+cache.delete(jid);
90+return null;
91+}
92+cache.delete(jid);
93+cache.set(jid, entry);
94+return entry;
95+}
48964997function logWhatsAppVerbose(enabled: boolean | undefined, message: string) {
5098if (!enabled) {
@@ -98,6 +146,8 @@ export type MonitorWebInboxOptions = {
98146};
99147/** Abort in-flight reconnect waits when shutdown becomes terminal. */
100148disconnectRetryAbortSignal?: AbortSignal;
149+/** Shared group metadata cache used only for inbound metadata fallback after fetch failures. */
150+groupMetadataCache?: WhatsAppGroupMetadataCache;
101151};
102152103153export async function attachWebInboxToSocket(
@@ -234,11 +284,8 @@ export async function attachWebInboxToSocket(
234284inboundConsoleLog.error(`Failed handling inbound web message: ${String(err)}`);
235285},
236286});
237-const groupMetaCache = new Map<
238-string,
239-{ subject?: string; participants?: string[]; expires: number }
240->();
241-const GROUP_META_TTL_MS = 5 * 60 * 1000; // 5 minutes
287+const groupMetadataCache = options.groupMetadataCache ?? new Map();
288+const groupMetaCache = new Map<string, LocalGroupMetadataCacheEntry>();
242289const lidLookup = sock.signalRepository?.lidMapping;
243290244291const resolveInboundJid = async (jid: string | null | undefined): Promise<string | null> =>
@@ -306,30 +353,54 @@ export async function attachWebInboxToSocket(
306353}
307354};
308355356+const summarizeGroupMeta = async (meta: GroupMetadata) => {
357+const participants =
358+(
359+await Promise.all(
360+meta.participants?.map(async (p) => {
361+const mapped = await resolveInboundJid(p.id);
362+return mapped ?? p.id;
363+}) ?? [],
364+)
365+).filter(Boolean) ?? [];
366+return {
367+subject: meta.subject,
368+ participants,
369+expires: Date.now() + GROUP_META_TTL_MS,
370+};
371+};
372+373+const summarizeGroupMetaForReconnectCache = (
374+meta: GroupMetadata,
375+): WhatsAppGroupMetadataCacheEntry => ({
376+subject: meta.subject,
377+expires: Date.now() + GROUP_META_TTL_MS,
378+});
379+309380const getGroupMeta = async (jid: string) => {
310-const cached = groupMetaCache.get(jid);
311-if (cached && cached.expires > Date.now()) {
381+const cached = readGroupMetadataCacheEntry(groupMetaCache, jid);
382+if (cached) {
312383return cached;
313384}
314385try {
315386const meta = await sock.groupMetadata(jid);
316-const participants =
317-(
318-await Promise.all(
319-meta.participants?.map(async (p) => {
320-const mapped = await resolveInboundJid(p.id);
321-return mapped ?? p.id;
322-}) ?? [],
323-)
324-).filter(Boolean) ?? [];
325-const entry = {
326-subject: meta.subject,
327- participants,
328-expires: Date.now() + GROUP_META_TTL_MS,
329-};
330-groupMetaCache.set(jid, entry);
387+const entry = await summarizeGroupMeta(meta);
388+rememberGroupMetadataCacheEntry(groupMetadataCache, jid, {
389+subject: entry.subject,
390+expires: entry.expires,
391+});
392+rememberGroupMetadataCacheEntry(groupMetaCache, jid, entry);
331393return entry;
332394} catch (err) {
395+const hydrated = readGroupMetadataCacheEntry(groupMetadataCache, jid);
396+if (hydrated) {
397+rememberGroupMetadataCacheEntry(groupMetaCache, jid, hydrated);
398+logWhatsAppVerbose(
399+options.verbose,
400+`Using cached group metadata for ${jid} after fetch failure: ${String(err)}`,
401+);
402+return hydrated;
403+}
333404logWhatsAppVerbose(
334405options.verbose,
335406`Failed to fetch group metadata for ${jid}: ${String(err)}`,
@@ -733,6 +804,15 @@ export async function attachWebInboxToSocket(
733804void (async () => {
734805try {
735806const groups = await sock.groupFetchAllParticipating();
807+for (const [jid, meta] of Object.entries(groups ?? {})) {
808+if (meta) {
809+rememberGroupMetadataCacheEntry(
810+groupMetadataCache,
811+jid,
812+summarizeGroupMetaForReconnectCache(meta),
813+);
814+}
815+}
736816logWhatsAppVerbose(
737817options.verbose,
738818`Hydrated ${Object.keys(groups ?? {}).length} participating groups on connect`,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。