


























1+import fs from "node:fs";
2+import os from "node:os";
3+import path from "node:path";
14import type {
25AnyMessageContent,
36MiscMessageGenerationOptions,
47WAMessage,
58} from "@whiskeysockets/baileys";
69import { listMessageReceiptPlatformIds } from "openclaw/plugin-sdk/channel-message";
7-import { beforeEach, describe, expect, it, vi } from "vitest";
10+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
811import { resolveWhatsAppOutboundMentions } from "./outbound-mentions.js";
912import { createWebSendApi } from "./send-api.js";
1013@@ -373,3 +376,86 @@ describe("createWebSendApi", () => {
373376);
374377});
375378});
379+380+// Integration tests for issue #67378: createWebSendApi must route outbound
381+// PN-only sends through the LID forward-mapping when authDir is provided,
382+// otherwise messages going to LID-addressed contacts vanish into a
383+// sender-only ghost chat.
384+describe("createWebSendApi LID resolution (issue #67378)", () => {
385+const sendMessage = vi.fn(async () => ({ key: { id: "msg-1" } }));
386+const sendPresenceUpdate = vi.fn(async () => {});
387+let authDir: string;
388+389+beforeEach(() => {
390+vi.clearAllMocks();
391+authDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-wa-lid-"));
392+fs.writeFileSync(path.join(authDir, "lid-mapping-15555550000.json"), JSON.stringify("987654"));
393+});
394+395+afterEach(() => {
396+fs.rmSync(authDir, { recursive: true, force: true });
397+});
398+399+it("resolves PN to LID for sendMessage when authDir is provided", async () => {
400+const api = createWebSendApi({
401+sock: { sendMessage, sendPresenceUpdate },
402+defaultAccountId: "main",
403+ authDir,
404+});
405+await api.sendMessage("+15555550000", "hello");
406+expect(sendMessage).toHaveBeenCalledWith("987654@lid", { text: "hello" });
407+});
408+409+it("falls back to PN s.whatsapp.net when no LID mapping exists", async () => {
410+const api = createWebSendApi({
411+sock: { sendMessage, sendPresenceUpdate },
412+defaultAccountId: "main",
413+ authDir,
414+});
415+await api.sendMessage("+33123456789", "hello");
416+expect(sendMessage).toHaveBeenCalledWith("33123456789@s.whatsapp.net", { text: "hello" });
417+});
418+419+it("resolves PN to LID for sendPoll", async () => {
420+const api = createWebSendApi({
421+sock: { sendMessage, sendPresenceUpdate },
422+defaultAccountId: "main",
423+ authDir,
424+});
425+await api.sendPoll("+15555550000", { question: "Q?", options: ["a", "b"] });
426+expect(sendMessage).toHaveBeenCalledWith(
427+"987654@lid",
428+expect.objectContaining({ poll: expect.any(Object) }),
429+);
430+});
431+432+it("resolves PN to LID for sendComposingTo presence", async () => {
433+const api = createWebSendApi({
434+sock: { sendMessage, sendPresenceUpdate },
435+defaultAccountId: "main",
436+ authDir,
437+});
438+await api.sendComposingTo("+15555550000");
439+expect(sendPresenceUpdate).toHaveBeenCalledWith("composing", "987654@lid");
440+});
441+442+it("skips newsletter composing presence when authDir is provided", async () => {
443+const api = createWebSendApi({
444+sock: { sendMessage, sendPresenceUpdate },
445+defaultAccountId: "main",
446+ authDir,
447+});
448+await api.sendComposingTo("120363401234567890@newsletter");
449+expect(sendPresenceUpdate).not.toHaveBeenCalled();
450+});
451+452+it("preserves legacy behavior (no authDir → PN-only routing)", async () => {
453+const api = createWebSendApi({
454+sock: { sendMessage, sendPresenceUpdate },
455+defaultAccountId: "main",
456+// authDir intentionally omitted
457+});
458+await api.sendMessage("+15555550000", "hello");
459+expect(sendMessage).toHaveBeenCalledWith("15555550000@s.whatsapp.net", { text: "hello" });
460+});
461+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。