Lynxie/app/app.go
Fluffy-Bean 2e5f4bce11 Update pipeline
And commit half-baked code restructure
2025-04-28 22:32:30 +01:00

152 lines
2.9 KiB
Go

package app
import (
"fmt"
"log"
"os"
"os/signal"
"strings"
"syscall"
"github.com/Fluffy-Bean/lynxie/internal/color"
"github.com/bwmarrin/discordgo"
)
type Callback func(h *Handler, args []string) Error
type Config struct {
BotPrefix string
BotToken string
BotIntents discordgo.Intent
CommandExtras map[string]string
}
type App struct {
Config Config
Commands map[string]Callback
CommandAliases map[string]string
}
func NewApp(config Config) *App {
return &App{
Config: config,
Commands: make(map[string]Callback),
CommandAliases: make(map[string]string),
}
}
func (a *App) RegisterCommand(cmd string, f Callback) {
a.Commands[cmd] = f
}
func (a *App) RegisterCommandAlias(alias, cmd string) {
a.CommandAliases[alias] = cmd
}
func (a *App) Run() {
dg, err := discordgo.New("Bot " + a.Config.BotToken)
if err != nil {
fmt.Println("error creating Discord session,", err)
return
}
dg.AddHandler(a.handler)
dg.Identify.Intents = a.Config.BotIntents
err = dg.Open()
if err != nil {
fmt.Println("error opening connection,", err)
return
}
fmt.Println("Bot is now running. Press CTRL-C to exit.")
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-sc
dg.Close()
}
type Handler struct {
Session *discordgo.Session
Message *discordgo.MessageCreate
Reference *discordgo.MessageReference
}
func (a *App) handler(session *discordgo.Session, message *discordgo.MessageCreate) {
h := &Handler{
Session: session,
Message: message,
Reference: &discordgo.MessageReference{
ChannelID: message.ChannelID,
MessageID: message.ID,
},
}
if h.Message.Author.ID == h.Session.State.User.ID {
return
}
if h.Message.Author.Bot {
return
}
var cmd string
var args string
cmd = h.Message.Content
cmd = strings.TrimPrefix(cmd, a.Config.BotPrefix)
cmd, args, _ = strings.Cut(cmd, " ")
alias, ok := a.CommandAliases[cmd]
if ok {
cmd = alias
}
callback, ok := a.Commands[cmd]
if !ok {
// Falling back to default help command
if cmd == "help" {
printHelp(a, h)
}
return
}
h.Session.ChannelTyping(h.Message.ChannelID)
err := callback(h, strings.Split(args, " "))
if !err.Ok() {
printError(a, h, err)
}
}
func printHelp(a *App, h *Handler) {
var commands []string
for cmd := range a.Commands {
commands = append(commands, cmd)
}
h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{
Embed: &discordgo.MessageEmbed{
Title: "Help",
Description: strings.Join(commands, "\n"),
Color: color.RGBToDiscord(255, 255, 255),
},
Reference: h.Reference,
})
}
func printError(a *App, h *Handler, e Error) {
log.Println(e.Err)
h.Session.ChannelMessageSendComplex(h.Message.ChannelID, &discordgo.MessageSend{
Embed: &discordgo.MessageEmbed{
Title: "Error",
Description: e.Msg,
Color: color.RGBToDiscord(255, 0, 0),
},
Reference: h.Reference,
})
}