feat(events): reaction-add/remove handlers - #4
Merged
Conversation
When a configured ✅ reaction lands on the configured message, grant the role. When it is removed, revoke the role if on_remove=revoke (default keep). Handler decisions are unit-tested via the shared matcher; the live event wiring is verified end-to-end. - src/events/shared.ts: pure matcher + emoji-string helpers - src/events/reactionAdd.ts, reactionRemove.ts: handlers - src/client.ts: add GuildMessageReactions intent + Partials.User alongside Message/Channel/Reaction (Partials.User is required for MESSAGE_REACTION_REMOVE on uncached users — the gateway payload only ships user_id, not a member object like the add event) - src/rest.ts, src/sweep.ts: add removeMemberRole to DiscordRestLike - src/index.ts: register both handlers - test/events/shared.test.ts: 11 tests for emoji + matcher Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/events/shared.ts— pure helpers:emojiToString(unicode vs custom format) andfindMatchingVerification.src/events/reactionAdd.ts— on a matching reaction, fetch the member, skip if they already have the role, otherwise grant it.src/events/reactionRemove.ts— on a matching reaction removal, no-op if `on_remove: keep`, otherwise revoke if they hold the role.src/client.ts— adds the `GuildMessageReactions` intent. Crucially also adds `Partials.User` alongside the existing Message/Channel/Reaction partials, because `MESSAGE_REACTION_REMOVE` only ships `user_id` (no member object like the add event does). Without `Partials.User`, discord.js silently drops the remove event for any uncached user — including everyone the bot has never seen before.Implements step 5 of `docs/exec-plans/v1.md`.
Test plan
Follow-ups
🤖 Generated with Claude Code