fix(whatsapp): propagate fromMe through inbound message pipeline

The `fromMe` flag from Baileys' WAMessage.key was only used for
access-control filtering and then discarded.  This meant agents
could not distinguish owner-sent messages from contact messages
in DM conversations (everything appeared as from the contact).

Add `fromMe` to `WebInboundMessage`, store it during message
construction, and thread it through `buildInboundLine` →
`formatInboundEnvelope` so DM transcripts prefix owner messages
with `(self):`.

Closes #32061

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
scoootscooob
2026-03-02 12:58:55 -08:00
committed by Peter Steinberger
parent 866bd91c65
commit 73e6dc361e
5 changed files with 33 additions and 1 deletions

View File

@@ -144,6 +144,29 @@ describe("formatInboundEnvelope", () => {
expect(body).toBe("[Telegram Alice] follow-up message");
});
it("prefixes DM body with (self) when fromMe is true", () => {
const body = formatInboundEnvelope({
channel: "WhatsApp",
from: "+1555",
body: "outbound msg",
chatType: "direct",
fromMe: true,
});
expect(body).toBe("[WhatsApp +1555] (self): outbound msg");
});
it("does not prefix group messages with (self) when fromMe is true", () => {
const body = formatInboundEnvelope({
channel: "WhatsApp",
from: "Family Chat",
body: "hello",
chatType: "group",
senderLabel: "Alice",
fromMe: true,
});
expect(body).toBe("[WhatsApp Family Chat] Alice: hello");
});
it("resolves envelope options from config", () => {
const options = resolveEnvelopeFormatOptions({
agents: {

View File

@@ -197,12 +197,18 @@ export function formatInboundEnvelope(params: {
sender?: SenderLabelParams;
previousTimestamp?: number | Date;
envelope?: EnvelopeFormatOptions;
fromMe?: boolean;
}): string {
const chatType = normalizeChatType(params.chatType);
const isDirect = !chatType || chatType === "direct";
const resolvedSenderRaw = params.senderLabel?.trim() || resolveSenderLabel(params.sender ?? {});
const resolvedSender = resolvedSenderRaw ? sanitizeEnvelopeHeaderPart(resolvedSenderRaw) : "";
const body = !isDirect && resolvedSender ? `${resolvedSender}: ${params.body}` : params.body;
const body =
isDirect && params.fromMe
? `(self): ${params.body}`
: !isDirect && resolvedSender
? `${resolvedSender}: ${params.body}`
: params.body;
return formatAgentEnvelope({
channel: params.channel,
from: params.from,

View File

@@ -43,5 +43,6 @@ export function buildInboundLine(params: {
},
previousTimestamp,
envelope,
fromMe: msg.fromMe,
});
}

View File

@@ -323,6 +323,7 @@ export async function monitorWebInbox(options: {
mentionedJids: mentionedJids ?? undefined,
selfJid,
selfE164,
fromMe: Boolean(msg.key?.fromMe),
location: location ?? undefined,
sendComposing,
reply,

View File

@@ -31,6 +31,7 @@ export type WebInboundMessage = {
mentionedJids?: string[];
selfJid?: string | null;
selfE164?: string | null;
fromMe?: boolean;
location?: NormalizedLocation;
sendComposing: () => Promise<void>;
reply: (text: string) => Promise<void>;