snow/discord/discord.go
2023-12-14 19:47:54 +00:00

140 lines
3.4 KiB
Go

package discord
import (
"strings"
"github.com/bwmarrin/discordgo"
"github.com/ectrc/snow/aid"
)
type DiscordCommand struct {
Command *discordgo.ApplicationCommand
Handler func(s *discordgo.Session, i *discordgo.InteractionCreate)
AdminOnly bool
}
type DiscordModal struct {
ID string
Handler func(s *discordgo.Session, i *discordgo.InteractionCreate)
}
type DiscordClient struct {
Client *discordgo.Session
Commands map[string]*DiscordCommand
Modals map[string]*DiscordModal
}
var StaticClient *DiscordClient
func NewDiscordClient(token string) *DiscordClient {
client, err := discordgo.New("Bot " + token)
if err != nil {
panic(err)
}
client.Identify.Intents = discordgo.IntentsAllWithoutPrivileged
return &DiscordClient{
Client: client,
Commands: make(map[string]*DiscordCommand),
Modals: make(map[string]*DiscordModal),
}
}
func IntialiseClient() {
StaticClient = NewDiscordClient(aid.Config.Discord.Token)
StaticClient.Client.AddHandler(StaticClient.readyHandler)
StaticClient.Client.AddHandler(StaticClient.interactionHandler)
addCommands()
if len(StaticClient.Commands) < len(StaticClient.GetRegisteredCommands()) {
StaticClient.UnregisterCommands()
StaticClient.RegisterCommands()
}
err := StaticClient.Client.Open()
if err != nil {
panic(err)
}
}
func (c *DiscordClient) UnregisterCommands() {
commands := c.GetRegisteredCommands()
if commands == nil {
return
}
for _, command := range commands {
err := c.Client.ApplicationCommandDelete(aid.Config.Discord.ID, aid.Config.Discord.Guild, command.ID)
if err != nil {
aid.Print("Failed to delete command: " + command.Name)
}
}
commands = c.GetGlobalRegisteredCommands()
for _, command := range commands {
err := c.Client.ApplicationCommandDelete(aid.Config.Discord.ID, "", command.ID)
if err != nil {
aid.Print("Failed to delete command: " + command.Name)
}
}
}
func (c *DiscordClient) RegisterCommands() {
adminPermission := int64(discordgo.PermissionAdministrator)
update := []*discordgo.ApplicationCommand{}
for _, command := range c.Commands {
if command.AdminOnly {
command.Command.DefaultMemberPermissions = &adminPermission
}
update = append(update, command.Command)
}
_, err := c.Client.ApplicationCommandBulkOverwrite(aid.Config.Discord.ID, aid.Config.Discord.Guild, update)
if err != nil {
aid.Print("Failed to register commands", err)
return
}
}
func (c *DiscordClient) GetRegisteredCommands() []*discordgo.ApplicationCommand {
commands, err := c.Client.ApplicationCommands(aid.Config.Discord.ID, aid.Config.Discord.Guild)
if err != nil {
aid.Print("Failed to get commands")
return nil
}
return commands
}
func (c *DiscordClient) GetGlobalRegisteredCommands() []*discordgo.ApplicationCommand {
commands, err := c.Client.ApplicationCommands(aid.Config.Discord.ID, "")
if err != nil {
aid.Print("Failed to get commands")
return nil
}
return commands
}
func (c *DiscordClient) readyHandler(s *discordgo.Session, event *discordgo.Ready) {
aid.Print("Discord bot is ready")
}
func (c *DiscordClient) interactionHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
switch i.Type {
case discordgo.InteractionApplicationCommand:
if command, ok := c.Commands[i.ApplicationCommandData().Name]; ok {
command.Handler(s, i)
}
case discordgo.InteractionModalSubmit:
if modal, ok := c.Modals[strings.Split(i.ModalSubmitData().CustomID, "://")[0]]; ok {
modal.Handler(s, i)
}
}
}