unbot/main.go
2026-06-01 18:37:01 +02:00

189 lines
4.3 KiB
Go

package main
import (
"context"
"flag"
"log/slog"
"os"
"os/signal"
"syscall"
"github.com/disgoorg/disgo"
"github.com/disgoorg/disgo/bot"
"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/events"
"github.com/disgoorg/disgo/gateway"
"github.com/disgoorg/snowflake/v2"
"github.com/elisiei/unbot/config"
"github.com/elisiei/unbot/db"
"github.com/elisiei/unbot/features"
)
func main() {
configPath := flag.String("config", "config.toml", "path to config file")
flag.Parse()
cfg, err := config.Load(*configPath)
if err != nil {
slog.Error("failed to load config", slog.Any("err", err))
os.Exit(1)
}
database, err := db.Open("unbot.db")
if err != nil {
slog.Error("failed to open database", slog.Any("err", err))
os.Exit(1)
}
dict := features.NewDictionary(database, cfg.Features.Dictionary.Enabled)
starboard, err := features.NewStarboard(
database,
cfg.Features.Starboard.WebhookURL,
cfg.Features.Starboard.ChannelID,
cfg.Features.Starboard.Threshold,
cfg.Features.Starboard.Enabled,
)
if err != nil {
slog.Error("failed to create starboard", slog.Any("err", err))
os.Exit(1)
}
client, err := disgo.New(cfg.Bot.Token,
bot.WithGatewayConfigOpts(
gateway.WithIntents(
gateway.IntentGuilds,
gateway.IntentGuildMessages,
gateway.IntentMessageContent,
gateway.IntentGuildMessageReactions,
),
),
bot.WithEventListenerFunc(func(e *events.AutocompleteInteractionCreate) {
if cfg.Features.Dictionary.Enabled {
dict.HandleAutocomplete(e)
}
}),
bot.WithEventListenerFunc(func(e *events.GuildMessageReactionAdd) {
if cfg.Features.Starboard.Enabled {
starboard.HandleReactionAdd(e)
}
}),
bot.WithEventListenerFunc(func(e *events.GuildMessageReactionRemove) {
if cfg.Features.Starboard.Enabled {
starboard.HandleReactionRemove(e)
}
}),
)
if err != nil {
slog.Error("failed to create client", slog.Any("err", err))
os.Exit(1)
}
xdTracker := features.NewXDTracker(
database,
client,
snowflake.ID(cfg.Bot.GuildID),
cfg.Features.XDTracker.Enabled,
)
client.AddEventListeners(
bot.NewListenerFunc(func(e *events.ApplicationCommandInteractionCreate) {
handleCommand(e, dict, xdTracker, cfg)
}),
bot.NewListenerFunc(func(e *events.MessageCreate) {
if cfg.Features.XDTracker.Enabled {
xdTracker.HandleMessage(e)
}
}),
)
iconChanger := features.NewIconChanger(
client,
cfg.Bot.GuildID,
cfg.Features.IconChanger.ChannelID,
cfg.Features.IconChanger.Interval,
cfg.Features.IconChanger.Enabled,
)
client.AddEventListeners(bot.NewListenerFunc(func(e *events.MessageCreate) {
iconChanger.HandleMessage(e)
}))
iconChanger.Start()
guildID := snowflake.ID(cfg.Bot.GuildID)
var commands []discord.ApplicationCommandCreate
if cfg.Features.Dictionary.Enabled {
commands = append(commands, dict.Command())
}
if cfg.Features.XDTracker.Enabled {
commands = append(commands, xdTracker.Command())
}
if len(commands) > 0 {
if _, err := client.Rest.SetGuildCommands(client.ApplicationID, guildID, commands); err != nil {
slog.Error("failed to register commands", slog.Any("err", err))
os.Exit(1)
}
slog.Info("registered commands")
}
if err := client.OpenGateway(context.TODO()); err != nil {
slog.Error("failed to open gateway", slog.Any("err", err))
os.Exit(1)
}
slog.Info("bot is running")
go xdTracker.BackfillHistory()
go iconChanger.BackfillHistory()
s := make(chan os.Signal, 1)
signal.Notify(s, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-s
iconChanger.Stop()
client.Close(context.TODO())
}
func handleCommand(e *events.ApplicationCommandInteractionCreate, dict *features.Dictionary, xd *features.XDTracker, cfg *config.Config) {
data := e.SlashCommandInteractionData()
switch data.CommandName() {
case "dict":
if !cfg.Features.Dictionary.Enabled {
return
}
opts := data.All()
if len(opts) == 0 {
return
}
subCmd := opts[0].Name
switch subCmd {
case "add":
dict.HandleAdd(e)
case "get":
dict.HandleGet(e)
case "remove":
dict.HandleRemove(e)
case "list":
dict.HandleList(e)
}
case "xd":
if !cfg.Features.XDTracker.Enabled {
return
}
opts := data.All()
if len(opts) == 0 {
xd.HandleStats(e)
return
}
subCmd := opts[0].Name
switch subCmd {
case "leaderboard":
xd.HandleLeaderboard(e)
case "stats":
xd.HandleStats(e)
}
}
}