feat(lib,bot): command registration handleling
This commit is contained in:
42
lib/bot.go
42
lib/bot.go
@@ -6,6 +6,10 @@ import (
|
||||
|
||||
type Bot struct {
|
||||
session *discordgo.Session
|
||||
|
||||
chatCommandHandlers chatCommandHandlers
|
||||
messageCommandHandlers messageCommandHandlers
|
||||
userCommandHandlers userCommandHandlers
|
||||
}
|
||||
|
||||
func Start(token string) (*Bot, error) {
|
||||
@@ -22,8 +26,13 @@ func Start(token string) (*Bot, error) {
|
||||
|
||||
bot := &Bot{
|
||||
session: s,
|
||||
chatCommandHandlers: chatCommandHandlers{},
|
||||
messageCommandHandlers: messageCommandHandlers{},
|
||||
userCommandHandlers: userCommandHandlers{},
|
||||
}
|
||||
|
||||
bot.session.AddHandler(bot.handleInteraction)
|
||||
|
||||
return bot, nil
|
||||
}
|
||||
|
||||
@@ -34,6 +43,35 @@ func (b *Bot) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bot) HandleCommand(c Command) {
|
||||
b.commands = append(b.commands, c)
|
||||
func (b *Bot) handleInteraction(s *discordgo.Session, ic *discordgo.InteractionCreate) {
|
||||
var err error
|
||||
|
||||
switch ic.Type {
|
||||
case discordgo.InteractionApplicationCommand:
|
||||
err = b.handleApplicationCommand(s, ic)
|
||||
}
|
||||
|
||||
_, err = s.ChannelMessageSend(ic.ChannelID, err.Error())
|
||||
panic(err) // TODO: handle error
|
||||
}
|
||||
|
||||
func (b *Bot) handleApplicationCommand(
|
||||
s *discordgo.Session,
|
||||
ic *discordgo.InteractionCreate,
|
||||
) error {
|
||||
data := ic.ApplicationCommandData()
|
||||
|
||||
var err error
|
||||
|
||||
if data.CommandType == discordgo.ChatApplicationCommand {
|
||||
err = b.chatCommandHandlers[sessionCommandID{data.ID, ic.GuildID}].Handle(
|
||||
ChatCommandCtx{},
|
||||
)
|
||||
} else if data.CommandType == discordgo.MessageApplicationCommand {
|
||||
err = b.messageCommandHandlers[sessionCommandID{data.ID, ic.GuildID}].Handle(MessageCommandCtx{})
|
||||
} else if data.CommandType == discordgo.UserApplicationCommand {
|
||||
err = b.userCommandHandlers[sessionCommandID{data.ID, ic.GuildID}].Handle(UserCommandCtx{})
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
147
lib/bot_commands.go
Normal file
147
lib/bot_commands.go
Normal file
@@ -0,0 +1,147 @@
|
||||
package bot
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
type commandID struct {
|
||||
Name string
|
||||
GuildID string
|
||||
}
|
||||
|
||||
type sessionCommandID struct {
|
||||
ID string
|
||||
GuildID string
|
||||
}
|
||||
|
||||
type (
|
||||
chatCommandHandlers map[sessionCommandID]Handler[ChatCommandCtx]
|
||||
messageCommandHandlers map[sessionCommandID]Handler[MessageCommandCtx]
|
||||
userCommandHandlers map[sessionCommandID]Handler[UserCommandCtx]
|
||||
)
|
||||
|
||||
func (b *Bot) MustHandleCommand(c Command, guildID ...string) {
|
||||
if err := b.HandleCommand(c, guildID...); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) HandleCommand(c Command, guildID ...string) error {
|
||||
var g string
|
||||
if len(guildID) > 0 {
|
||||
g = guildID[0]
|
||||
}
|
||||
|
||||
if err := c.Validate(); err != nil {
|
||||
return fmt.Errorf("failed to handle command %q: %v", c.ApplicationCommand().Name, err)
|
||||
}
|
||||
|
||||
sessionCmd, err := b.sessionCommand(c.ApplicationCommand().Name, g)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return b.updateCommand(c, sessionCmd, g)
|
||||
}
|
||||
|
||||
func (b *Bot) updateCommand(
|
||||
botCmd Command,
|
||||
sessionCmd *discordgo.ApplicationCommand,
|
||||
guildID ...string,
|
||||
) error {
|
||||
var err error
|
||||
|
||||
var g string
|
||||
if len(guildID) > 0 {
|
||||
g = guildID[0]
|
||||
}
|
||||
|
||||
if sessionCmd == nil {
|
||||
sessionCmd, err = b.session.ApplicationCommandCreate(
|
||||
b.session.State.User.ID,
|
||||
g,
|
||||
botCmd.ApplicationCommand(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
sessionCmd, err = b.session.ApplicationCommandEdit(
|
||||
b.session.State.User.ID,
|
||||
g,
|
||||
sessionCmd.ID,
|
||||
botCmd.ApplicationCommand(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch botCmd.ApplicationCommand().Type {
|
||||
case discordgo.ChatApplicationCommand:
|
||||
if c, ok := botCmd.(*ChatCommand); ok {
|
||||
b.chatCommandHandlers[sessionCommandID{sessionCmd.ID, g}] = c.Handler
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
case discordgo.MessageApplicationCommand:
|
||||
if c, ok := botCmd.(*MessageCommand); ok {
|
||||
b.messageCommandHandlers[sessionCommandID{sessionCmd.ID, g}] = c.Handler
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
case discordgo.UserApplicationCommand:
|
||||
if c, ok := botCmd.(*UserCommand); ok {
|
||||
b.userCommandHandlers[sessionCommandID{sessionCmd.ID, g}] = c.Handler
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bot) sessionCommand(
|
||||
name string,
|
||||
guildID ...string,
|
||||
) (*discordgo.ApplicationCommand, error) {
|
||||
var g string
|
||||
if len(guildID) > 0 {
|
||||
g = guildID[0]
|
||||
}
|
||||
|
||||
sessionCmds, err := b.sessionCommands(g)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd, ok := sessionCmds[commandID{Name: name, GuildID: g}]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (b *Bot) sessionCommands(
|
||||
guildID ...string,
|
||||
) (map[commandID]*discordgo.ApplicationCommand, error) {
|
||||
var g string
|
||||
if len(guildID) > 0 {
|
||||
g = guildID[0]
|
||||
}
|
||||
|
||||
appCmds, err := b.session.ApplicationCommands(b.session.State.User.ID, g)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmds := make(map[commandID]*discordgo.ApplicationCommand, len(appCmds))
|
||||
for _, c := range appCmds {
|
||||
cmds[commandID{Name: c.Name, GuildID: g}] = c
|
||||
}
|
||||
|
||||
return cmds, err
|
||||
}
|
||||
Reference in New Issue
Block a user