feat(bot): command and event handling

This commit is contained in:
Gustavo "Guz" L. de Mello
2024-08-14 16:47:01 -03:00
parent a50770e6b9
commit 5cd3937bc7
5 changed files with 157 additions and 34 deletions

View File

@@ -1,31 +0,0 @@
package discord
import (
"dislate/internals/guilddb"
"dislate/internals/translator"
"github.com/bwmarrin/discordgo"
)
type Bot struct {
token string
db guilddb.GuildDB
translator translator.Translator
session *discordgo.Session
}
func NewBot(token string, db guilddb.GuildDB, translator translator.Translator) (*Bot, error) {
discord, err := discordgo.New("Bot " + token)
if err != nil {
return &Bot{}, err
}
return &Bot{token, db, translator, discord}, nil
}
func (b *Bot) Start() error {
return b.session.Open()
}
func (b *Bot) Stop() error {
return b.session.Close()
}

View File

@@ -0,0 +1,54 @@
package bot
import (
"dislate/internals/guilddb"
"dislate/internals/translator"
"log"
"github.com/bwmarrin/discordgo"
)
type Bot struct {
token string
db guilddb.GuildDB
translator translator.Translator
session *discordgo.Session
logger *log.Logger
registeredCommands []*discordgo.ApplicationCommand
}
func NewBot(token string, db guilddb.GuildDB, translator translator.Translator, logger *log.Logger) (*Bot, error) {
discord, err := discordgo.New("Bot " + token)
if err != nil {
return &Bot{}, err
}
return &Bot{
token: token,
db: db,
translator: translator,
session: discord,
logger: logger,
registeredCommands: make([]*discordgo.ApplicationCommand, 0),
}, nil
}
func (b *Bot) Start() error {
b.registerHandlers()
if err := b.session.Open(); err != nil {
return err
}
if err := b.registerCommands(); err != nil {
return err
}
return nil
}
func (b *Bot) Stop() error {
if err := b.removeCommands(); err != nil {
return err
}
return b.session.Close()
}

View File

@@ -0,0 +1,66 @@
package bot
import (
"dislate/internals/translator/lang"
"github.com/bwmarrin/discordgo"
)
type command struct {
command *discordgo.ApplicationCommand
handler func(*discordgo.Session, *discordgo.InteractionCreate)
}
func (b *Bot) commands() []command {
cmds := []command{{
&discordgo.ApplicationCommand{
Name: "test-command",
Description: "This is a test command",
},
func(s *discordgo.Session, i *discordgo.InteractionCreate) {
txt, _ := b.translator.Translate(lang.EN, lang.PT, "Hello world!")
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: txt,
},
})
},
}}
return cmds
}
func (b *Bot) registerCommands() error {
cs := b.commands()
rcs := make([]*discordgo.ApplicationCommand, len(cs))
handlers := make(map[string]func(*discordgo.Session, *discordgo.InteractionCreate), len(cs))
for i, v := range cs {
cmd, err := b.session.ApplicationCommandCreate(b.session.State.User.ID, "", v.command)
if err != nil {
return err
}
handlers[cmd.Name] = v.handler
rcs[i] = cmd
}
b.session.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
if h, ok := handlers[i.ApplicationCommandData().Name]; ok {
h(s, i)
}
})
return nil
}
func (b *Bot) removeCommands() error {
for _, v := range b.registeredCommands {
err := b.session.ApplicationCommandDelete(b.session.State.User.ID, "", v.ID)
if err != nil {
return err
}
}
return nil
}

View File

@@ -0,0 +1,34 @@
package bot
import (
"log"
"dislate/internals/guilddb"
"github.com/bwmarrin/discordgo"
)
type handler any
func (b *Bot) handlers() []handler {
hs := []handler{
func(s *discordgo.Session, r *discordgo.Ready) {
for _, g := range r.Guilds {
err := b.db.GuildInsert(guilddb.Guild{ID: g.ID})
if err != nil {
log.Printf("ERROR: Failed to add guild %s to database: %s", g.ID, err)
} else {
log.Printf("Added guild %s", g.ID)
}
}
},
}
return hs
}
func (b *Bot) registerHandlers() {
for _, h := range b.handlers() {
b.session.AddHandler(h)
}
}

View File

@@ -1,7 +1,7 @@
package main
import (
"dislate/internals/discord"
"dislate/internals/discord/bot"
"dislate/internals/guilddb"
"dislate/internals/translator"
"flag"
@@ -17,7 +17,7 @@ const (
GOOGLE_TRANSLATE TranslationProvider = "google-translate"
)
var translation_provider = flag.String("tprovider", string(GOOGLE_TRANSLATE), "Translation provider")
// var translation_provider = flag.String("tprovider", string(GOOGLE_TRANSLATE), "Translation provider")
var database_file = flag.String("db", "file:./guild.db", "SQLite database file/location")
var discord_token = flag.String("token", os.Getenv("DISCORD_TOKEN"), "Discord bot authentication token")
@@ -49,7 +49,7 @@ func main() {
}
log.Print("Database prepared to be used")
bot, err := discord.NewBot(*discord_token, db, translator.NewMockTranslator())
bot, err := bot.NewBot(*discord_token, db, translator.NewMockTranslator(), log.Default())
if err != nil {
log.Printf("ERROR: failed to create discord bot: %s", err)
return