fix(whatsapp): preserve group message IDs and normalize reaction participants
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Auto-reply: prefer `RawBody` for command/directive parsing (WhatsApp + Discord) and prevent fallback runs from clobbering concurrent session updates. (#643) — thanks @mcinteerj.
|
- Auto-reply: prefer `RawBody` for command/directive parsing (WhatsApp + Discord) and prevent fallback runs from clobbering concurrent session updates. (#643) — thanks @mcinteerj.
|
||||||
|
- WhatsApp: fix group reactions by preserving message IDs and sender JIDs in history; normalize participant phone numbers to JIDs in outbound reactions. (#640) — thanks @mcinteerj.
|
||||||
- Cron: `wakeMode: "now"` waits for heartbeat completion (and retries when the main lane is busy). (#666) — thanks @roshanasingh4.
|
- Cron: `wakeMode: "now"` waits for heartbeat completion (and retries when the main lane is busy). (#666) — thanks @roshanasingh4.
|
||||||
- Agents/OpenAI: fix Responses tool-only → follow-up turn handling (avoid standalone `reasoning` items that trigger 400 “required following item”).
|
- Agents/OpenAI: fix Responses tool-only → follow-up turn handling (avoid standalone `reasoning` items that trigger 400 “required following item”).
|
||||||
- Sandbox: add `clawdbot sandbox explain` (effective policy inspector + fix-it keys); improve “sandbox jail” tool-policy/elevated errors with actionable config key paths; link to docs.
|
- Sandbox: add `clawdbot sandbox explain` (effective policy inspector + fix-it keys); improve “sandbox jail” tool-policy/elevated errors with actionable config key paths; link to docs.
|
||||||
@@ -41,7 +42,6 @@
|
|||||||
- Telegram: serialize media-group processing to avoid missed albums under load.
|
- Telegram: serialize media-group processing to avoid missed albums under load.
|
||||||
- Signal: handle `dataMessage.reaction` events (signal-cli SSE) to avoid broken attachment errors. (#637) — thanks @neist.
|
- Signal: handle `dataMessage.reaction` events (signal-cli SSE) to avoid broken attachment errors. (#637) — thanks @neist.
|
||||||
- Docs: showcase entries for ParentPay, R2 Upload, iOS TestFlight, and Oura Health. (#650) — thanks @henrino3.
|
- Docs: showcase entries for ParentPay, R2 Upload, iOS TestFlight, and Oura Health. (#650) — thanks @henrino3.
|
||||||
|
|
||||||
## 2026.1.9
|
## 2026.1.9
|
||||||
|
|
||||||
### Highlights
|
### Highlights
|
||||||
|
|||||||
@@ -826,7 +826,13 @@ export async function monitorWebProvider(
|
|||||||
DEFAULT_GROUP_HISTORY_LIMIT;
|
DEFAULT_GROUP_HISTORY_LIMIT;
|
||||||
const groupHistories = new Map<
|
const groupHistories = new Map<
|
||||||
string,
|
string,
|
||||||
Array<{ sender: string; body: string; timestamp?: number }>
|
Array<{
|
||||||
|
sender: string;
|
||||||
|
body: string;
|
||||||
|
timestamp?: number;
|
||||||
|
id?: string;
|
||||||
|
senderJid?: string;
|
||||||
|
}>
|
||||||
>();
|
>();
|
||||||
const groupMemberNames = new Map<string, Map<string, string>>();
|
const groupMemberNames = new Map<string, Map<string, string>>();
|
||||||
const sleep =
|
const sleep =
|
||||||
@@ -1104,6 +1110,8 @@ export async function monitorWebProvider(
|
|||||||
sender: string;
|
sender: string;
|
||||||
body: string;
|
body: string;
|
||||||
timestamp?: number;
|
timestamp?: number;
|
||||||
|
id?: string;
|
||||||
|
senderJid?: string;
|
||||||
}>;
|
}>;
|
||||||
suppressGroupHistoryClear?: boolean;
|
suppressGroupHistoryClear?: boolean;
|
||||||
},
|
},
|
||||||
@@ -1123,14 +1131,17 @@ export async function monitorWebProvider(
|
|||||||
if (historyWithoutCurrent.length > 0) {
|
if (historyWithoutCurrent.length > 0) {
|
||||||
const lineBreak = "\\n";
|
const lineBreak = "\\n";
|
||||||
const historyText = historyWithoutCurrent
|
const historyText = historyWithoutCurrent
|
||||||
.map((m) =>
|
.map((m) => {
|
||||||
formatAgentEnvelope({
|
const bodyWithId = m.id
|
||||||
|
? `${m.body}\n[message_id: ${m.id}]`
|
||||||
|
: m.body;
|
||||||
|
return formatAgentEnvelope({
|
||||||
provider: "WhatsApp",
|
provider: "WhatsApp",
|
||||||
from: conversationId,
|
from: conversationId,
|
||||||
timestamp: m.timestamp,
|
timestamp: m.timestamp,
|
||||||
body: `${m.sender}: ${m.body}`,
|
body: `${m.sender}: ${bodyWithId}`,
|
||||||
}),
|
});
|
||||||
)
|
})
|
||||||
.join(lineBreak);
|
.join(lineBreak);
|
||||||
combinedBody = buildHistoryContext({
|
combinedBody = buildHistoryContext({
|
||||||
historyText,
|
historyText,
|
||||||
@@ -1554,11 +1565,19 @@ export async function monitorWebProvider(
|
|||||||
sender: string;
|
sender: string;
|
||||||
body: string;
|
body: string;
|
||||||
timestamp?: number;
|
timestamp?: number;
|
||||||
|
id?: string;
|
||||||
|
senderJid?: string;
|
||||||
}>);
|
}>);
|
||||||
|
const sender =
|
||||||
|
msg.senderName && msg.senderE164
|
||||||
|
? `${msg.senderName} (${msg.senderE164})`
|
||||||
|
: (msg.senderName ?? msg.senderE164 ?? "Unknown");
|
||||||
history.push({
|
history.push({
|
||||||
sender: msg.senderName ?? msg.senderE164 ?? "Unknown",
|
sender,
|
||||||
body: msg.body,
|
body: msg.body,
|
||||||
timestamp: msg.timestamp,
|
timestamp: msg.timestamp,
|
||||||
|
id: msg.id,
|
||||||
|
senderJid: msg.senderJid,
|
||||||
});
|
});
|
||||||
while (history.length > groupHistoryLimit) history.shift();
|
while (history.length > groupHistoryLimit) history.shift();
|
||||||
groupHistories.set(groupHistoryKey, history);
|
groupHistories.set(groupHistoryKey, history);
|
||||||
|
|||||||
@@ -620,7 +620,7 @@ export async function monitorWebInbox(options: {
|
|||||||
remoteJid: jid,
|
remoteJid: jid,
|
||||||
id: messageId,
|
id: messageId,
|
||||||
fromMe,
|
fromMe,
|
||||||
participant,
|
participant: participant ? toWhatsappJid(participant) : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1402,4 +1402,36 @@ describe("web monitor inbox", () => {
|
|||||||
|
|
||||||
await listener.close();
|
await listener.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("normalizes participant phone numbers to JIDs in sendReaction", async () => {
|
||||||
|
const listener = await monitorWebInbox({
|
||||||
|
verbose: false,
|
||||||
|
onMessage: vi.fn(),
|
||||||
|
accountId: ACCOUNT_ID,
|
||||||
|
authDir,
|
||||||
|
});
|
||||||
|
const sock = await createWaSocket();
|
||||||
|
|
||||||
|
await listener.sendReaction(
|
||||||
|
"12345@g.us",
|
||||||
|
"msg123",
|
||||||
|
"👍",
|
||||||
|
false,
|
||||||
|
"+6421000000",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(sock.sendMessage).toHaveBeenCalledWith("12345@g.us", {
|
||||||
|
react: {
|
||||||
|
text: "👍",
|
||||||
|
key: {
|
||||||
|
remoteJid: "12345@g.us",
|
||||||
|
id: "msg123",
|
||||||
|
fromMe: false,
|
||||||
|
participant: "6421000000@s.whatsapp.net",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await listener.close();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user