From cf59c2d8e000f3d76d0d232166b8c76e4f5bce96 Mon Sep 17 00:00:00 2001 From: "Gustavo \"Guz\" L. de Mello" Date: Mon, 19 Aug 2024 20:24:51 -0300 Subject: [PATCH] feat(commands): handling of message components --- internals/discord/bot/commands.go | 40 ++++++++++++++++++++-- internals/discord/bot/commands/channels.go | 7 +++- internals/discord/bot/commands/commands.go | 7 ++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/internals/discord/bot/commands.go b/internals/discord/bot/commands.go index 5954da3..610fcd5 100644 --- a/internals/discord/bot/commands.go +++ b/internals/discord/bot/commands.go @@ -17,6 +17,7 @@ func (b *Bot) registerCommands() error { } handlers := make(map[string]func(*dgo.Session, *dgo.InteractionCreate), len(cs)) + componentsHandlers := make(map[string]func(*dgo.Session, *dgo.InteractionCreate)) for _, v := range cs { var cmd *dgo.ApplicationCommand @@ -50,6 +51,34 @@ func (b *Bot) registerCommands() error { } } + for _, c := range v.Components() { + cj, err := c.Info().MarshalJSON() + if err != nil { + return errors.Join(fmt.Errorf("Failed to marshal command"), err) + } + + var v struct { + CustomID string `json:"custom_id"` + } + if err := json.Unmarshal(cj, &v); err != nil { + return errors.Join(fmt.Errorf("Failed to unmarshal command"), err) + } + + componentsHandlers[v.CustomID] = func(s *dgo.Session, ic *dgo.InteractionCreate) { + b.logger.Debug("Handling message component", + slog.String("id", ic.Interaction.ID), + slog.String("custom_id", ic.Interaction.MessageComponentData().CustomID), + ) + err := c.Handle(s, ic) + if err != nil { + b.logger.Error("Failed to handle message component", + slog.String("custom_id", ic.Interaction.MessageComponentData().CustomID), + slog.String("err", err.Error()), + ) + } + } + } + handlers[cmd.Name] = func(s *dgo.Session, ic *dgo.InteractionCreate) { b.logger.Debug("Handling command", slog.String("id", ic.Interaction.ID), @@ -106,8 +135,15 @@ func (b *Bot) registerCommands() error { } b.session.AddHandler(func(s *dgo.Session, i *dgo.InteractionCreate) { - if h, ok := handlers[i.ApplicationCommandData().Name]; ok { - h(s, i) + switch i.Interaction.Type { + case dgo.InteractionApplicationCommand: + if h, ok := handlers[i.ApplicationCommandData().Name]; ok { + h(s, i) + } + case dgo.InteractionMessageComponent: + if h, ok := componentsHandlers[i.MessageComponentData().CustomID]; ok { + h(s, i) + } } }) diff --git a/internals/discord/bot/commands/channels.go b/internals/discord/bot/commands/channels.go index 8a73dbc..f43ee92 100644 --- a/internals/discord/bot/commands/channels.go +++ b/internals/discord/bot/commands/channels.go @@ -11,7 +11,6 @@ import ( dgo "github.com/bwmarrin/discordgo" ) - type ManageChannel struct { db gdb.GuildDB } @@ -34,6 +33,9 @@ func (c ManageChannel) Subcommands() []Command { func (c ManageChannel) Handle(s *dgo.Session, i *dgo.InteractionCreate) error { return nil } +func (c ManageChannel) Components() []Component { + return []Component{} +} type ChannelsInfo struct { db gdb.GuildDB @@ -95,6 +97,9 @@ func (c ChannelsInfo) Handle(s *dgo.Session, ic *dgo.InteractionCreate) error { return nil } +func (c ChannelsInfo) Components() []Component { + return []Component{} +} func (c ChannelsInfo) Subcommands() []Command { return []Command{} } diff --git a/internals/discord/bot/commands/commands.go b/internals/discord/bot/commands/commands.go index 240a6b6..68c447e 100644 --- a/internals/discord/bot/commands/commands.go +++ b/internals/discord/bot/commands/commands.go @@ -8,7 +8,14 @@ type Command interface { Info() *dgo.ApplicationCommand Handle(s *dgo.Session, i *dgo.InteractionCreate) error Subcommands() []Command + Components() []Component } + +type Component interface { + Info() dgo.MessageComponent + Handle(s *dgo.Session, i *dgo.InteractionCreate) error +} + func getOptions(i *dgo.InteractionCreate) map[string]*dgo.ApplicationCommandInteractionDataOption { opts := i.ApplicationCommandData().Options m := make(map[string]*dgo.ApplicationCommandInteractionDataOption, len(opts))