fix(auto-reply): prevent sender spoofing in group prompts

This commit is contained in:
Peter Steinberger
2026-02-10 00:35:56 -06:00
parent 8ff1618bfc
commit 53273b490b
42 changed files with 405 additions and 243 deletions

View File

@@ -224,7 +224,8 @@ describe("broadcast groups", () => {
};
expect(payload.Body).toContain("Chat messages since your last reply");
expect(payload.Body).toContain("Alice (+111): hello group");
expect(payload.Body).toContain("[message_id: g1]");
// Message id hints are not included in prompts anymore.
expect(payload.Body).not.toContain("[message_id:");
expect(payload.Body).toContain("@bot ping");
expect(payload.SenderName).toBe("Bob");
expect(payload.SenderE164).toBe("+222");

View File

@@ -164,7 +164,8 @@ describe("web auto-reply", () => {
const payload = resolver.mock.calls[0][0];
expect(payload.Body).toContain("Chat messages since your last reply");
expect(payload.Body).toContain("Alice (+111): hello group");
expect(payload.Body).toContain("[message_id: g1]");
// Message id hints are not included in prompts anymore.
expect(payload.Body).not.toContain("[message_id:");
expect(payload.Body).toContain("@bot ping");
expect(payload.SenderName).toBe("Bob");
expect(payload.SenderE164).toBe("+222");

View File

@@ -156,21 +156,17 @@ export async function processMessage(params: {
sender: m.sender,
body: m.body,
timestamp: m.timestamp,
messageId: m.id,
}));
combinedBody = buildHistoryContextFromEntries({
entries: historyEntries,
currentMessage: combinedBody,
excludeLast: false,
formatEntry: (entry) => {
const bodyWithId = entry.messageId
? `${entry.body}\n[message_id: ${entry.messageId}]`
: entry.body;
return formatInboundEnvelope({
channel: "WhatsApp",
from: conversationId,
timestamp: entry.timestamp,
body: bodyWithId,
body: entry.body,
chatType: "group",
senderLabel: entry.sender,
envelope: envelopeOptions,
@@ -271,8 +267,21 @@ export async function processMessage(params: {
? (resolveIdentityNamePrefix(params.cfg, params.route.agentId) ?? "[openclaw]")
: undefined);
const inboundHistory =
params.msg.chatType === "group"
? (params.groupHistory ?? params.groupHistories.get(params.groupHistoryKey) ?? []).map(
(entry) => ({
sender: entry.sender,
body: entry.body,
timestamp: entry.timestamp,
}),
)
: undefined;
const ctxPayload = finalizeInboundContext({
Body: combinedBody,
BodyForAgent: params.msg.body,
InboundHistory: inboundHistory,
RawBody: params.msg.body,
CommandBody: params.msg.body,
From: params.msg.from,