#20722: fix(signal): use correct JSON-RPC param names for sendReaction
channel: signal
size: XS
Cluster:
Signal Reaction Fixes
## Summary
- Problem: Signal reactions via `message action=react` can be dropped because OpenClaw sends the wrong JSON-RPC parameter names to the signal-cli daemon.
- Why it matters: reactions are a primary low-noise interaction mode; drops look like the agent ignored the message.
- What changed: align `sendReaction` RPC params to signal-cli JSON-RPC (`recipient` / `groupId` / `remove`).
- What did NOT change: no config defaults, no new endpoints, no behavior changes for non-Signal channels.
## Root cause
OpenClaw talks to signal-cli’s JSON-RPC daemon over HTTP (`POST /api/v1/rpc`). The daemon maps CLI args to JSON-RPC params in camelCase; for `sendReaction`, the target args are:
- positional `recipient` (multi-value)
- `--group-id` (multi-value)
- `--remove` (flag)
So the JSON-RPC params are `recipient`, `groupId`, and `remove`.
OpenClaw was sending `recipients` / `groupIds` (plural), so the daemon didn’t receive a recipient/group target and the reaction never delivered.
References:
- signal-cli JSON-RPC HTTP endpoints: https://github.com/AsamK/signal-cli/blob/master/man/signal-cli-jsonrpc.5.adoc
- sendReaction command args: https://github.com/AsamK/signal-cli/blob/master/src/main/java/org/asamk/signal/commands/SendReactionCommand.java
## Changes
- `recipient: [<uuid|e164>]` instead of `recipients: [...]`
- `groupId: "<base64>"` instead of `groupIds: [...]`
- keep `remove: true` for reaction removal (matches `--remove`)
- update unit tests to assert the exact param shape
- formatting-only: reorder one import in `src/browser/extension-relay.ts` to satisfy `pnpm format:check` with the repo’s pinned oxfmt
## Test plan
- `pnpm check`
- `npx vitest run src/signal/send-reactions.test.ts`
## Manual verification (not in CI)
Not run against a live Signal daemon in this PR.
Suggested quick check:
1. DM: `message action=react channel=signal target=uuid:<peer> messageId=<ts> emoji=🔥`
2. Group: `message action=react channel=signal target=signal:group:<id> targetAuthor=uuid:<sender> messageId=<ts> emoji=✅`
3. Removal: same call with `remove=true`
## AI assistance
AI-assisted (Cursor). I reviewed the code paths and updated targeted unit tests.
Most Similar PRs
#7660: fix(signal): route group reactions to group sessions
by ClawdadBot · 2026-02-03
71.9%
#17818: Fix Signal reaction notification missing sender (support legacy 'so...
by Clawborn · 2026-02-16
71.8%
#17453: fix(signal): make group reactions deterministic from inbound sender...
by akalypse · 2026-02-15
71.8%
#12984: fix(signal): fall back to JSON-RPC for health check on signal-cli 0...
by omair445 · 2026-02-10
68.4%
#20236: fix(telegram): make reaction handling soft-fail and message-id resi...
by PeterShanxin · 2026-02-18
68.2%
#15994: feat(signal): add unsend, poll create, poll vote, and poll terminat...
by heyhudson · 2026-02-14
67.6%
#20860: feat(reactions): add configurable immediate reaction dispatch system
by davidrudduck · 2026-02-19
67.1%
#20732: fix(signal): forward replyTo as quoteTimestamp/quoteAuthor for nati...
by arjunblj · 2026-02-19
66.7%
#6089: fix(slack): add reactionNotifications config check to reactions han...
by jontsai · 2026-02-01
66.6%
#9734: fix(telegram): correct sender identification for channel messages (...
by divol89 · 2026-02-05
66.3%