* feat(whatsapp): subscribe to inbound reaction events Subscribe to Baileys `messages.reaction` events and surface them as system events for the agent session. Follows the same pattern used by Signal and Slack: listen → parse → route → enqueueSystemEvent. - Add `WebInboundReaction` type and `onReaction` callback to monitor - Parse emoji, sender JID, target message ID from Baileys event - Route via `resolveAgentRoute` and enqueue as system event - Handle self-reaction attribution (reactionKey.fromMe → selfJid) - Skip reaction removals (empty emoji) and status/broadcast JIDs - Outer + inner try/catch for resilience against malformed events - 13 unit tests (monitor-level + system event wiring) - Changelog entry and docs updates Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * revert changelog entry to avoid merge conflicts The inbound reaction feature is internal plumbing, not user-facing enough to warrant a changelog entry that will conflict with active PRs. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(whatsapp): handle reaction removals and improve sender detection - Emit reaction events with isRemoval flag instead of skipping them - Fall back to chatJid for DM sender when reaction.key is missing - Add chatType and accountId to reaction logs for observability - Update tests to reflect new removal handling behavior Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(whatsapp): gate reactions by DM/group access controls Address Codex review - reactions now respect the same access controls as messages (dmPolicy, allowlists, etc). Self-reactions bypass the check since they're our own actions, not inbound events. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: remove unused senderName field from reaction type Baileys reaction events don't include push names, so this field was dead interface pollution. (Cursor review) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(whatsapp): update reaction docs + suppress pairing for reactions - Update docs: reaction removals now emit events with isRemoval=true - Pass no-op sendMessage to access control to prevent pairing messages being sent when unknown users react (pairing is for messages, not reactions) (Cursor review) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Nick Sullivan <nick@technick.ai> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1.1 KiB
1.1 KiB
| summary | read_when | |
|---|---|---|
| Reaction semantics shared across channels |
|
Reaction tooling
Shared reaction semantics across channels:
emojiis required when adding a reaction.emoji=""removes the bot's reaction(s) when supported.remove: trueremoves the specified emoji when supported (requiresemoji).
Channel notes:
- Discord/Slack: empty
emojiremoves all of the bot's reactions on the message;remove: trueremoves just that emoji. - Google Chat: empty
emojiremoves the app's reactions on the message;remove: trueremoves just that emoji. - Telegram: empty
emojiremoves the bot's reactions;remove: truealso removes reactions but still requires a non-emptyemojifor tool validation. - WhatsApp: empty
emojiremoves the bot reaction;remove: truemaps to empty emoji (still requiresemoji). - Signal: inbound reaction notifications emit system events when
channels.signal.reactionNotificationsis enabled. - WhatsApp: inbound reaction notifications are always surfaced as system events (no configuration required).