mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(whatsapp): preserve injected listener normalization
This commit is contained in:
@@ -27,6 +27,7 @@ import {
|
||||
type ManagedWhatsAppListener,
|
||||
} from "../connection-controller.js";
|
||||
import { resolveWhatsAppInboundPolicy } from "../inbound-policy.js";
|
||||
import { normalizeAdmittedWebInboundMessage } from "../inbound/message-aliases.js";
|
||||
import {
|
||||
readWhatsAppBaileysCacheEntry,
|
||||
type WhatsAppBaileysGroupMetadataCache,
|
||||
@@ -34,7 +35,7 @@ import {
|
||||
} from "../inbound/baileys-cache.js";
|
||||
import type { WhatsAppGroupMetadataCache } from "../inbound/group-metadata-cache.js";
|
||||
import { attachWebInboxToSocket } from "../inbound/monitor.js";
|
||||
import type { AdmittedWebInboundMessage } from "../inbound/types.js";
|
||||
import type { WebInboundMessageInput } from "../inbound/types.js";
|
||||
import {
|
||||
newConnectionId,
|
||||
resolveHeartbeatSeconds,
|
||||
@@ -229,12 +230,13 @@ export async function monitorWebChannel(
|
||||
cfg,
|
||||
channel: "whatsapp",
|
||||
});
|
||||
const shouldDebounce = (msg: AdmittedWebInboundMessage) => {
|
||||
const shouldDebounce = (msg: WebInboundMessageInput) => {
|
||||
const admitted = normalizeAdmittedWebInboundMessage(msg);
|
||||
return shouldDebounceTextInbound({
|
||||
text: msg.payload.commandBody ?? msg.payload.body,
|
||||
text: admitted.payload.commandBody ?? admitted.payload.body,
|
||||
cfg,
|
||||
hasMedia: Boolean(msg.payload.media?.path || msg.payload.media?.type),
|
||||
allowDebounce: !(msg.payload.location || msg.quote?.id || msg.quote?.body),
|
||||
hasMedia: Boolean(admitted.payload.media?.path || admitted.payload.media?.type),
|
||||
allowDebounce: !(admitted.payload.location || admitted.quote?.id || admitted.quote?.body),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -293,11 +295,14 @@ export async function monitorWebChannel(
|
||||
groupMetadataCache,
|
||||
recentMessageKeys,
|
||||
baileysGroupMetaCache,
|
||||
onMessage: async (msg: AdmittedWebInboundMessage) => {
|
||||
onMessage: async (msg: WebInboundMessageInput) => {
|
||||
// Keep the deprecated injected-listener input contract at the WhatsApp edge.
|
||||
// Auto-reply only receives the admitted canonical message.
|
||||
const admitted = normalizeAdmittedWebInboundMessage(msg);
|
||||
const inboundAt = Date.now();
|
||||
controller.noteInbound(inboundAt);
|
||||
statusController.noteInbound(inboundAt);
|
||||
await onMessage(msg);
|
||||
await onMessage(admitted);
|
||||
},
|
||||
onPendingWorkChanged: (pendingWorkCount, at) => {
|
||||
statusController.noteBusy(pendingWorkCount > 0, at);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// WhatsApp tests cover inbound message alias compatibility.
|
||||
import { describe, expect, expectTypeOf, it, vi } from "vitest";
|
||||
import {
|
||||
normalizeAdmittedWebInboundMessage,
|
||||
normalizeWebInboundMessage,
|
||||
withDeprecatedWebInboundMessageFlatAliases,
|
||||
} from "./message-aliases.js";
|
||||
@@ -10,9 +11,16 @@ import {
|
||||
createTestLegacyFlatWebInboundMessage,
|
||||
createTestWhatsAppInboundAdmission,
|
||||
} from "./test-message.test-helper.js";
|
||||
import type { LegacyFlatWebInboundMessage, WebInboundCallbackMessage } from "./types.js";
|
||||
import type {
|
||||
LegacyFlatWebInboundMessage,
|
||||
WebInboundCallbackMessage,
|
||||
WebInboundMessageInput,
|
||||
} from "./types.js";
|
||||
|
||||
type MonitorWebInboxMessage = Parameters<Parameters<typeof monitorWebInbox>[0]["onMessage"]>[0];
|
||||
type MonitorWebChannel = typeof import("../auto-reply/monitor.js").monitorWebChannel;
|
||||
type ListenerFactory = NonNullable<Parameters<MonitorWebChannel>[1]>;
|
||||
type ListenerFactoryMessage = Parameters<Parameters<ListenerFactory>[0]["onMessage"]>[0];
|
||||
|
||||
function createCanonicalMessage(overrides: Partial<WebInboundCallbackMessage> = {}) {
|
||||
return withDeprecatedWebInboundMessageFlatAliases({
|
||||
@@ -109,6 +117,16 @@ describe("WhatsApp inbound flat aliases", () => {
|
||||
}>();
|
||||
});
|
||||
|
||||
it("keeps deprecated flat inputs at both WhatsApp listener boundaries", () => {
|
||||
expectTypeOf<WebInboundMessageInput>().toMatchTypeOf<ListenerFactoryMessage>();
|
||||
|
||||
const admitted = normalizeAdmittedWebInboundMessage(createTestLegacyFlatWebInboundMessage());
|
||||
expect(admitted.admission.ingress).toMatchObject({
|
||||
admission: "dispatch",
|
||||
decisiveGateId: "legacy-flat-compat",
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps deprecated flat aliases live against canonical contexts", async () => {
|
||||
const msg = createCanonicalMessage();
|
||||
const nextReply = vi.fn(async () => createAcceptedWhatsAppSendResult("text", "reply-2"));
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { buildDeprecatedFlatWhatsAppInboundAdmission } from "./admission.js";
|
||||
import {
|
||||
buildDeprecatedFlatWhatsAppInboundAdmission,
|
||||
requireAdmittedWhatsAppInboundMessage,
|
||||
} from "./admission.js";
|
||||
import { resolveWhatsAppGroupConversationId } from "./group-conversation.js";
|
||||
import type {
|
||||
AdmittedWebInboundCallbackMessage,
|
||||
DeprecatedWebInboundAdmissionTopLevelFields,
|
||||
DeprecatedWebInboundMessageFlatAliases,
|
||||
LegacyFlatWebInboundMessage,
|
||||
@@ -454,3 +458,11 @@ export function normalizeWebInboundMessage(msg: WebInboundMessageInput): WebInbo
|
||||
|
||||
return normalizeLegacyFlatWebInboundMessage(msg);
|
||||
}
|
||||
|
||||
export function normalizeAdmittedWebInboundMessage(
|
||||
msg: WebInboundMessageInput,
|
||||
): AdmittedWebInboundCallbackMessage {
|
||||
return requireAdmittedWhatsAppInboundMessage(
|
||||
normalizeWebInboundMessage(msg),
|
||||
) as AdmittedWebInboundCallbackMessage;
|
||||
}
|
||||
|
||||
@@ -7,15 +7,10 @@ import type { WhatsAppIngressLifecycle, WhatsAppReadReceiptTarget } from "./dura
|
||||
import { attachWhatsAppIngressLifecycle } from "./ingress-lifecycle.js";
|
||||
import { withDeprecatedWebInboundMessageFlatAliases } from "./message-aliases.js";
|
||||
import type {
|
||||
AdmittedWebInboundMessage,
|
||||
WebInboundMessage,
|
||||
AdmittedWebInboundCallbackMessage,
|
||||
WebInboundMessageInput,
|
||||
} from "./types.js";
|
||||
|
||||
type AdmittedWebInboundCallbackMessage = WebInboundMessage & {
|
||||
admission: AdmittedWebInboundMessage["admission"];
|
||||
};
|
||||
|
||||
export type WhatsAppQueuedInboundMessage = AdmittedWebInboundCallbackMessage & {
|
||||
debounceKey?: string;
|
||||
debounceKeyTracked?: boolean;
|
||||
|
||||
@@ -5,7 +5,6 @@ import { createSubsystemLogger, defaultRuntime } from "openclaw/plugin-sdk/runti
|
||||
import type { OpenClawConfig } from "../runtime-api.js";
|
||||
import { createWaSocket, waitForWaConnection } from "../session.js";
|
||||
import { resolveWhatsAppSocketTiming, type WhatsAppSocketTimingOptions } from "../socket-timing.js";
|
||||
import { requireAdmittedWhatsAppInboundMessage } from "./admission.js";
|
||||
import {
|
||||
readWhatsAppBaileysCacheEntry,
|
||||
type WhatsAppBaileysGroupMetadataCache,
|
||||
@@ -20,7 +19,7 @@ import {
|
||||
type WhatsAppGroupMetadataCache,
|
||||
} from "./group-metadata-cache.js";
|
||||
import { closeInboundMonitorSocket } from "./lifecycle.js";
|
||||
import { normalizeWebInboundMessage } from "./message-aliases.js";
|
||||
import { normalizeAdmittedWebInboundMessage } from "./message-aliases.js";
|
||||
import {
|
||||
createWhatsAppMessageDeliveryCoordinator,
|
||||
type WhatsAppAppendReplyWindow,
|
||||
@@ -28,8 +27,7 @@ import {
|
||||
import { createWebSendApi } from "./send-api.js";
|
||||
import { createWhatsAppAttachedSocketSession } from "./socket-session.js";
|
||||
import type {
|
||||
AdmittedWebInboundMessage,
|
||||
WebInboundMessage,
|
||||
AdmittedWebInboundCallbackMessage,
|
||||
WebInboundMessageInput,
|
||||
} from "./types.js";
|
||||
|
||||
@@ -39,10 +37,6 @@ function logWhatsAppVerbose(enabled: boolean | undefined, message: string) {
|
||||
}
|
||||
}
|
||||
|
||||
type AdmittedWebInboundCallbackMessage = WebInboundMessage & {
|
||||
admission: AdmittedWebInboundMessage["admission"];
|
||||
};
|
||||
|
||||
type MonitorWebInboxOptions = {
|
||||
cfg: OpenClawConfig;
|
||||
loadConfig?: () => OpenClawConfig;
|
||||
@@ -84,8 +78,13 @@ type MonitorWebInboxOptions = {
|
||||
durableInboundQueue?: WhatsAppDurableInboundQueue;
|
||||
};
|
||||
|
||||
type AttachWebInboxToSocketOptions = Omit<MonitorWebInboxOptions, "socketTiming"> & {
|
||||
type AttachWebInboxToSocketOptions = Omit<
|
||||
MonitorWebInboxOptions,
|
||||
"onMessage" | "shouldDebounce" | "socketTiming"
|
||||
> & {
|
||||
socketTiming: Required<WhatsAppSocketTimingOptions>;
|
||||
onMessage: (msg: WebInboundMessageInput) => Promise<void>;
|
||||
shouldDebounce?: (msg: WebInboundMessageInput) => boolean;
|
||||
};
|
||||
|
||||
export async function attachWebInboxToSocket(
|
||||
@@ -200,12 +199,6 @@ export async function monitorWebInbox(options: MonitorWebInboxOptions) {
|
||||
closeInboundMonitorSocket(sock);
|
||||
throw error;
|
||||
}
|
||||
const normalizeAdmittedWebInboundMessage = (
|
||||
msg: WebInboundMessageInput,
|
||||
): AdmittedWebInboundCallbackMessage =>
|
||||
requireAdmittedWhatsAppInboundMessage(
|
||||
normalizeWebInboundMessage(msg),
|
||||
) as AdmittedWebInboundCallbackMessage;
|
||||
return attachWebInboxToSocket({
|
||||
...options,
|
||||
onMessage: async (msg) => {
|
||||
|
||||
@@ -245,6 +245,10 @@ export type AdmittedWebInboundMessage = Omit<
|
||||
admission: WhatsAppInboundAdmission;
|
||||
};
|
||||
|
||||
export type AdmittedWebInboundCallbackMessage = WebInboundMessage & {
|
||||
admission: WhatsAppInboundAdmission;
|
||||
};
|
||||
|
||||
export type LegacyFlatWebInboundMessage = DeprecatedWebInboundAdmissionTopLevelFields &
|
||||
Pick<WebInboundCallbackMessageCommon, "wasMentioned"> & {
|
||||
admission?: WhatsAppInboundAdmission;
|
||||
|
||||
Reference in New Issue
Block a user