#15994: feat(signal): add unsend, poll create, poll vote, and poll terminate actions
docs
channel: signal
gateway
size: XL
trusted-contributor
Cluster:
Slack and Signal Enhancements
## Summary
Signal supported `send` and `react` message actions, but not `unsend`, even though signal-cli exposes `remoteDelete`. That meant agents and users could not retract mistaken or sensitive messages through OpenClaw.
This PR adds Signal `unsend` support end-to-end and keeps it consistent with existing action-gating behavior.
## What Changed
### Signal remote delete transport
- `src/signal/send.ts`: Added `sendRemoteDeleteSignal(to, targetTimestamp, opts)`.
- `src/signal/send.ts`: Reuses existing Signal target parsing and account context resolution.
- `src/signal/send.ts`: Maps recipient/group/username targets to the `remoteDelete` RPC payload.
- `src/signal/send.ts`: Rejects invalid timestamps (`<= 0`, non-finite) before RPC.
### Signal action integration and capability surface
- `src/channels/plugins/actions/signal.ts`: `listActions` now includes `unsend` when at least one configured Signal account allows `actions.unsend`.
- `src/channels/plugins/actions/signal.ts`: Added `action === "unsend"` handler with `actions.unsend` gate enforcement, recipient/group validation (`recipient` or `to`), positive numeric `messageId` validation, and dispatch to `sendRemoteDeleteSignal`.
- `src/channels/dock.ts`: Marked Signal capabilities with `unsend: true` so capability surfaces advertise support.
### Config and test coverage
- `src/config/types.signal.ts`: Added typed `actions.unsend?: boolean` in Signal account config.
- `src/signal/send.test.ts`: Added coverage for payload mapping for recipient/group/username targets, timestamp validation, and success return.
- `src/channels/plugins/actions/actions.test.ts`: Updated Signal action-list expectations to include `unsend`.
## Design Notes
- The RPC call is implemented in `src/signal/send.ts` (not inline in the adapter) to keep Signal transport and target mapping centralized and reusable.
- `actions.unsend` uses the same gate pattern as other actions (`createActionGate`), preserving backward-compatible defaults.
- Strict timestamp validation fails early and avoids invalid `remoteDelete` calls, but intentionally rejects non-numeric message identifiers.
## Testing
- Ran: `pnpm test src/signal/send.test.ts src/channels/plugins/actions/actions.test.ts`
- Result: 2 test files passed, 49 tests passed.
## AI Disclosure
- [x] AI-assisted
- [x] Fully tested
## Related Issues
- #15536
---
Closes #15536
Closes #22259
Most Similar PRs
#20722: fix(signal): use correct JSON-RPC param names for sendReaction
by arjunblj · 2026-02-19
67.6%
#20732: fix(signal): forward replyTo as quoteTimestamp/quoteAuthor for nati...
by arjunblj · 2026-02-19
66.7%
#9701: feat: handle Signal message edits with [edited] marker (#9656)
by divol89 · 2026-02-05
64.2%
#17818: Fix Signal reaction notification missing sender (support legacy 'so...
by Clawborn · 2026-02-16
64.0%
#15956: feat(signal): enhanced inbound message handling
by heyhudson · 2026-02-14
63.3%
#8271: feat(signal): Add full quoted message context support
by ProofOfReach · 2026-02-03
62.7%
#19398: feat(signal): support native signal-cli JSON-RPC WebSocket
by jxstanford · 2026-02-17
62.1%
#16704: Signal: reduce REST lock contention in send/receive loop
by hashpuppy · 2026-02-15
62.0%
#12984: fix(signal): fall back to JSON-RPC for health check on signal-cli 0...
by omair445 · 2026-02-10
60.5%
#15853: feat: add option to suppress media placeholder text
by MisterGuy420 · 2026-02-14
60.4%