-
Notifications
You must be signed in to change notification settings - Fork 60
Description
Bug Description
handleGatewayReaction and handleForwardedReaction in the Discord adapter produce channel-level thread IDs for reactions on messages inside threads. The threadId on ReactionEvent is a 3-segment ID (discord:{guildId}:{channelId}) even when the reacted message is in a thread, where it should be 4-segment (discord:{guildId}:{parentChannelId}:{threadId}).
Steps to Reproduce
- Register a reaction handler:
chat.onReaction(["x"], (event) => { console.log(event.threadId); }) - Send a message that triggers the bot to reply in a Discord thread
- React with ❌ on a message inside that thread
- Observe
event.threadId— it'sdiscord:{guildId}:{threadChannelId}(3 segments) instead ofdiscord:{guildId}:{parentChannelId}:{threadChannelId}(4 segments)
Expected Behavior
event.threadId should be the full 4-segment ID (discord:{guildId}:{parentChannelId}:{threadId}) when the reaction is on a message inside a thread, matching the format produced by handleGatewayMessage.
Actual Behavior
event.threadId is a 3-segment channel-level ID (discord:{guildId}:{channelId}) — the thread snowflake is placed in the channel slot and the parent channel is lost. This means event.threadId from onReaction doesn't match the threadId used by onNewMention/onSubscribedMessage for the same thread.
Code Sample
// handleGatewayReaction currently (packages/adapter-discord/src/index.ts ~L1664):
const threadId = this.encodeThreadId({ guildId, channelId, threadId: undefined });
// Should resolve thread context like handleGatewayMessage does (~L1555):
const isInThread = reaction.message.channel?.isThread?.();
let parentChannelId = channelId;
let discordThreadId;
if (isInThread && "parentId" in reaction.message.channel && reaction.message.channel.parentId) {
discordThreadId = channelId;
parentChannelId = reaction.message.channel.parentId;
}
const threadId = this.encodeThreadId({ guildId, channelId: parentChannelId, threadId: discordThreadId });Chat SDK Version
4.15.0
Node.js Version
No response
Platform Adapter
Discord
Operating System
macOS
Additional Context
Both handleGatewayReaction (~L1664) and handleForwardedReaction (~L547) are affected. The fix pattern already
Note: handleGatewayReaction's type signature narrows reaction.message to { id: string; channelId: string; guildId: string | null }, which doesn't include channel. But at runtime, the caller passes the full discord.js MessageReaction object, so reaction.message.channel (with .isThread() and .parentId) is available. The type signature needs to be widened to include channel for the fix to typecheck.exists in handleGatewayMessage (~L1555) which uses message.channel.isThread() and channel.parentId to resolve the correct thread context.
I (claude) patched this locally and it worked as expected