feat(whatsapp): context-aware emoji reactions via shared resolveReactionMessageId#57226
feat(whatsapp): context-aware emoji reactions via shared resolveReactionMessageId#57226
Conversation
Greptile SummaryThis PR wires the shared Key behaviors:
Confidence Score: 5/5Safe to merge — implementation is correct, all guard conditions are sound, and previous review concerns are resolved. The fallback logic is well-guarded: cross-chat and cross-provider contexts both suppress the fallback, and the error path correctly produces a 400 ToolInputError rather than a 500. All seven unit tests trace correctly through the implementation (verified by manual trace). The two previously flagged test defects — missing currentChannelProvider in the cross-chat test and missing currentChannelId in the happy-path tests — are both fixed in the current revision. No P0 or P1 findings remain. No files require special attention.
|
| Filename | Overview |
|---|---|
| extensions/whatsapp/src/channel.ts | Adds toolContext to handleAction, computes isWhatsAppSource, normalizedTarget, normalizedCurrent, and isCrossChat to gate context fallback, then delegates messageId resolution to resolveReactionMessageId. Logic is correct and safe. |
| extensions/whatsapp/src/channel.test.ts | Seven new unit tests added for messageId resolution; all test paths trace correctly through the channel.ts logic. Previous concerns about missing currentChannelProvider (cross-chat test) and missing currentChannelId (happy-path tests) are resolved in this revision. |
Reviews (4): Last reviewed commit: "WhatsApp: use shared resolveReactionMess..." | Re-trigger Greptile
7655593 to
65096c2
Compare
|
@greptile please re-review this PR. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 65096c22b0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
65096c2 to
9e57bfe
Compare
|
Both review comments addressed:
@greptile please re-review this PR. |
…ions Wire the shared resolveReactionMessageId helper into the WhatsApp channel adapter, matching the pattern already used by Telegram, Signal, and Discord. The model can now react to the current inbound message without explicitly providing a messageId. Safety guards: - Only falls back to context when the source is WhatsApp - Suppresses fallback when targeting a different chat (normalized comparison) - Throws ToolInputError (400) instead of plain Error (500) when messageId is missing, preserving gateway error mapping
9e57bfe to
e6580d7
Compare
|
@greptile please re-review this PR. |
|
🤖 We're reviewing this PR with Aisle We're running a security check on the changes in this PR now. This usually takes a few minutes. ⌛ Progress:
Latest run failed. Keeping previous successful results. Trace ID: Last updated on: 2026-03-30T09:47:26Z |
…ions (openclaw#57226) Wire the shared resolveReactionMessageId helper into the WhatsApp channel adapter, matching the pattern already used by Telegram, Signal, and Discord. The model can now react to the current inbound message without explicitly providing a messageId. Safety guards: - Only falls back to context when the source is WhatsApp - Suppresses fallback when targeting a different chat (normalized comparison) - Throws ToolInputError (400) instead of plain Error (500) when messageId is missing, preserving gateway error mapping
…ions (openclaw#57226) Wire the shared resolveReactionMessageId helper into the WhatsApp channel adapter, matching the pattern already used by Telegram, Signal, and Discord. The model can now react to the current inbound message without explicitly providing a messageId. Safety guards: - Only falls back to context when the source is WhatsApp - Suppresses fallback when targeting a different chat (normalized comparison) - Throws ToolInputError (400) instead of plain Error (500) when messageId is missing, preserving gateway error mapping
…ions (openclaw#57226) Wire the shared resolveReactionMessageId helper into the WhatsApp channel adapter, matching the pattern already used by Telegram, Signal, and Discord. The model can now react to the current inbound message without explicitly providing a messageId. Safety guards: - Only falls back to context when the source is WhatsApp - Suppresses fallback when targeting a different chat (normalized comparison) - Throws ToolInputError (400) instead of plain Error (500) when messageId is missing, preserving gateway error mapping
…ions (openclaw#57226) Wire the shared resolveReactionMessageId helper into the WhatsApp channel adapter, matching the pattern already used by Telegram, Signal, and Discord. The model can now react to the current inbound message without explicitly providing a messageId. Safety guards: - Only falls back to context when the source is WhatsApp - Suppresses fallback when targeting a different chat (normalized comparison) - Throws ToolInputError (400) instead of plain Error (500) when messageId is missing, preserving gateway error mapping
Summary
messageId, unlike Telegram, Signal, and Discord which auto-resolve it from inbound context via the sharedresolveReactionMessageIdhelper.message({ action: "react", emoji: "👍" })to react to the current inbound message — it must echo back the message ID from context, which it often fails to do.resolveReactionMessageIdfromopenclaw/plugin-sdk/channel-actionsinto the WhatsApphandleActionadapter with safety guards for cross-chat and cross-provider scenarios.sendReactionWhatsApp,send-api.ts), no schema changes (message-tool.ts), no config changes. Thereactaction was already declared bydescribeMessageTool.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause / Regression History (if applicable)
N/A — This is a new feature, not a fix. WhatsApp reactions were added (551a8d5, Jan 6 2026) with
messageId: requiredand never updated when Telegram got the context fallback (c1b75ab, Feb 23 2026) or when the shared helper was extracted (7066d5e, Mar 2 2026).Regression Test Plan (if applicable)
extensions/whatsapp/src/channel.test.tsmessageIdwins over context fallbackmessageIdfalls back totoolContext.currentMessageId(WhatsApp source only)messageIdconverted to stringmessageIdwith no context throwsToolInputError(400, not 500)whatsapp:+1555vs+1555)channel.tswhere the fallback logic lives, mocking the runtime to verify parameter resolution.User-visible / Behavior Changes
message({ action: "react", emoji: "👍" })without providingmessageId— it auto-resolves from context.messageIdstill works as before (no breaking change).messagetool to be available (e.g.messagingprofile ortools.alsoAllow: ["message"]).Diagram (if applicable)
Security Impact (required)
reactaction was already declared and gated bychannels.whatsapp.actions.reactionsmessageId.Repro + Verification
Environment
tools.profile: "messaging",channels.whatsapp.actions.reactions: true(default)Steps
message({ action: "react", emoji: "👍" })— nomessageIdneededExpected
Actual
Evidence
Live-tested on OpenClaw 2026.3.28 (cherry-picked) with WhatsApp DM. Gateway logs confirm
tool=messagecalled and reaction delivered. 7 new unit tests inchannel.test.tscover fallback, cross-chat guard, cross-provider guard, and error type preservation.Human Verification (required)
tovscurrentChannelIdwith prefix normalization), cross-provider source (Telegram context), missing messageId without context (ToolInputError 400)participantfield — pre-existing limitation, not introduced by this change)Review Conversations
Compatibility / Migration
messageIdstill works identicallyRisks and Mitigations
messageIdis auto-resolved butparticipantis missing (needed for group message keys).participantenrichment from context is a follow-up enhancement.