From 5c6769fa33cc796be01bbb9a41b65928c7e05975 Mon Sep 17 00:00:00 2001 From: pmcholding Date: Sun, 15 Mar 2026 15:34:45 -0300 Subject: [PATCH] fix(whatsapp): use globalThis singleton for active-listener registry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The WhatsApp active-listener Map is duplicated across multiple Rollup chunks, causing proactive sends to fail with "No active WhatsApp Web listener" — setActiveWebListener() and requireActiveWebListener() resolve to different Map instances in different chunks. Use resolveGlobalMap() (from src/shared/global-singleton.ts) to ensure all chunks share a single listener Map via globalThis, matching the pattern applied to Telegram, Slack, Feishu and other extensions in PR #43683. Also removes dead _currentListener variable (written but never read). Fixes #47313 Relates to #14406, #47389 Co-Authored-By: Claude Opus 4.6 (1M context) --- extensions/whatsapp/src/active-listener.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/extensions/whatsapp/src/active-listener.ts b/extensions/whatsapp/src/active-listener.ts index fc8f11fe20e..0e9cf09925b 100644 --- a/extensions/whatsapp/src/active-listener.ts +++ b/extensions/whatsapp/src/active-listener.ts @@ -1,6 +1,7 @@ import { formatCliCommand } from "../../../src/cli/command-format.js"; import type { PollInput } from "../../../src/polls.js"; import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js"; +import { resolveGlobalMap } from "../../../src/shared/global-singleton.js"; export type ActiveWebSendOptions = { gifPlayback?: boolean; @@ -28,9 +29,8 @@ export type ActiveWebListener = { close?: () => Promise; }; -let _currentListener: ActiveWebListener | null = null; - -const listeners = new Map(); +const WA_LISTENERS_KEY = Symbol.for("openclaw.whatsappActiveListeners"); +const listeners = resolveGlobalMap(WA_LISTENERS_KEY); export function resolveWebAccountId(accountId?: string | null): string { return (accountId ?? "").trim() || DEFAULT_ACCOUNT_ID; @@ -73,9 +73,6 @@ export function setActiveWebListener( } else { listeners.set(id, listener); } - if (id === DEFAULT_ACCOUNT_ID) { - _currentListener = listener; - } } export function getActiveWebListener(accountId?: string | null): ActiveWebListener | null {