Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion channel/discord/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/gorilla/websocket"
"github.com/monsterxx03/tachi/config"
"github.com/monsterxx03/tachi/pkg/channel"
"github.com/monsterxx03/tachi/pkg/container"
"github.com/monsterxx03/tachi/pkg/httpx"
"github.com/monsterxx03/tachi/pkg/logger"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -108,6 +109,13 @@ type DiscordChannel struct {
// Component callback registry (Phase 2+)
componentHandlers map[string]componentHandler

// Pending AskUserQuestion prompts, keyed by their CustomID token.
// Implemented as a LockedMap: PresentQuestions runs on the agent-turn
// goroutine, component interactions arrive on discordgo goroutines, and
// text-fallback acks come from the manager — all need synchronized
// access, and claim/cleanup rely on atomic LoadAndDelete.
questionStates *container.LockedMap[string, *questionState]

// Slash command handler (injected by Manager via CommandChannel interface)
cmdHandler channel.CommandHandler

Expand Down Expand Up @@ -168,6 +176,7 @@ func NewChannel(cfg DiscordConfig) (*DiscordChannel, error) {
httpClient: httpClient,
cacheDir: cacheDir,
componentHandlers: make(map[string]componentHandler),
questionStates: &container.LockedMap[string, *questionState]{},
memberCache: newMemberCache(),
deduper: newMessageDeduper(),
topicStatus: make(map[string]topicEntry),
Expand Down Expand Up @@ -217,7 +226,10 @@ Platform characteristics:
- Media attachments (images, files) are supported as separate uploads
- Threads are fully supported: the bot can receive and reply inside
Discord threads without @mention by default (configurable via
thread_require_mention)`
thread_require_mention)
- AskUserQuestion renders as interactive buttons / select menus — use it
to ask the user multiple-choice questions and get answers through UI
clicks (questions without options fall back to a text reply)`
}

// Send implements channel.MessageSender for proactive message delivery
Expand Down Expand Up @@ -484,6 +496,8 @@ func (ch *DiscordChannel) onInteractionCreate(handler channel.MessageHandler) an
ch.handleSlashCommand(s, i)
case discordgo.InteractionApplicationCommandAutocomplete:
ch.handleAutocomplete(s, i)
case discordgo.InteractionMessageComponent:
ch.handleComponentInteraction(s, i, handler)
}
}
}
Expand Down
Loading
Loading