You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR ghostwright#33 added the ability for Phantom to reply naturally in Slack threads it has participated in, without needing an @mention. The implementation tracks which threads the bot has replied to in a participatedThreads set on SlackChannel (Socket Mode), and gates on that set in the message event handler.
This feature is Socket Mode only. SlackHttpChannel (HTTP receiver mode) was not updated.
Current behavior
Socket Mode (SlackChannel): After replying in a thread, Phantom will respond to follow-up messages in that thread without being @mentioned. Thread participation is tracked via participatedThreads and called from index.ts via trackThreadParticipation().
HTTP Mode (SlackHttpChannel): The message event handler in slack-http-events.ts still uses the old if (channelType !== "im") return guard, meaning Phantom only responds to DMs - not thread replies in channels, regardless of prior participation.
What needs to change
Three files need updates to bring HTTP mode to parity:
Remove the SlackHttpChannel instanceof guards added as a temporary workaround in PR ghostwright#33's resolution (the two !(slackChannel instanceof SlackHttpChannel) checks around lines 629-639). Once SlackHttpChannel has trackThreadParticipation(), the SlackTransport union will satisfy the call without a guard.
Reply in a thread Phantom has participated in without @mentioning it - it should respond naturally
Post in a channel Phantom has NOT replied in - it should not respond unless @mentioned
Notes
The participatedThreads set is in-memory, so it resets on process restart. This is intentional and consistent with Socket Mode behavior.
SlackHttpChannel uses registerHttpEventHandlers (delegating to EventDispatchHost) rather than registering handlers directly, so the interface update is the critical path for passing state through.
Background
PR ghostwright#33 added the ability for Phantom to reply naturally in Slack threads it has participated in, without needing an @mention. The implementation tracks which threads the bot has replied to in a
participatedThreadsset onSlackChannel(Socket Mode), and gates on that set in themessageevent handler.This feature is Socket Mode only.
SlackHttpChannel(HTTP receiver mode) was not updated.Current behavior
SlackChannel): After replying in a thread, Phantom will respond to follow-up messages in that thread without being @mentioned. Thread participation is tracked viaparticipatedThreadsand called fromindex.tsviatrackThreadParticipation().SlackHttpChannel): Themessageevent handler inslack-http-events.tsstill uses the oldif (channelType !== "im") returnguard, meaning Phantom only responds to DMs - not thread replies in channels, regardless of prior participation.What needs to change
Three files need updates to bring HTTP mode to parity:
1.
src/channels/slack-http-receiver.tsAdd
participatedThreadsand the tracking method:2.
src/channels/slack-http-events.tsUpdate
EventDispatchHostto expose thread participation check:Then update the
messageevent handler (currently around line 89-90) from:To match the Socket Mode logic in
slack.ts:288-294:3.
src/index.tsRemove the
SlackHttpChannelinstanceof guards added as a temporary workaround in PR ghostwright#33's resolution (the two!(slackChannel instanceof SlackHttpChannel)checks around lines 629-639). OnceSlackHttpChannelhastrackThreadParticipation(), theSlackTransportunion will satisfy the call without a guard.Testing
message.channels(and optionallymessage.groups) event subscriptions in the Slack app's Event Subscriptions settings (same requirement as Socket Mode, documented in PR allow phantom to reply to conversations its part of naturally ghostwright/phantom#33)Notes
participatedThreadsset is in-memory, so it resets on process restart. This is intentional and consistent with Socket Mode behavior.SlackHttpChannelusesregisterHttpEventHandlers(delegating toEventDispatchHost) rather than registering handlers directly, so the interface update is the critical path for passing state through.