From 8579328ee4164bfc8d092c63264563fc1df51c5f Mon Sep 17 00:00:00 2001 From: vaporvee Date: Thu, 4 Apr 2024 01:27:59 +0200 Subject: [PATCH] started porting to disgo --- cmd_tag.go | 54 +++++------ go.mod | 11 ++- go.sum | 18 ++++ handlers.go | 256 ++++++++++++++++++++++++++-------------------------- main.go | 55 +++++++---- tool.go | 118 ++++++++---------------- 6 files changed, 254 insertions(+), 258 deletions(-) diff --git a/cmd_tag.go b/cmd_tag.go index 1ea9db3..6daafc8 100644 --- a/cmd_tag.go +++ b/cmd_tag.go @@ -2,22 +2,23 @@ package main import ( "github.com/bwmarrin/discordgo" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/json" "github.com/sirupsen/logrus" ) var cmd_tag Command = Command{ - Definition: discordgo.ApplicationCommand{ + Definition: discord.SlashCommandCreate{ Name: "tag", - DefaultMemberPermissions: int64Ptr(discordgo.PermissionManageServer), + DefaultMemberPermissions: json.NewNullablePtr(discord.PermissionManageGuild), Description: "A command to show and edit saved presaved messages.", - Options: []*discordgo.ApplicationCommandOption{ - { + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionSubCommand{ Name: "get", Description: "A command to get messages saved to the bot.", - Type: discordgo.ApplicationCommandOptionSubCommand, - Options: []*discordgo.ApplicationCommandOption{ - { - Type: discordgo.ApplicationCommandOptionString, + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionString{ Name: "tag", Description: "Your predefined tag for the saved message", Required: true, @@ -25,18 +26,15 @@ var cmd_tag Command = Command{ }, }, }, - { + discord.ApplicationCommandOptionSubCommand{ Name: "add", Description: "A command to add messages saved to the bot.", - Type: discordgo.ApplicationCommandOptionSubCommand, }, - { + discord.ApplicationCommandOptionSubCommand{ Name: "remove", Description: "A command to remove messages saved to the bot.", - Type: discordgo.ApplicationCommandOptionSubCommand, - Options: []*discordgo.ApplicationCommandOption{ - { - Type: discordgo.ApplicationCommandOptionString, + Options: []discord.ApplicationCommandOption{ + discord.ApplicationCommandOptionString{ Name: "tag", Description: "The tag you want to remove", Required: true, @@ -46,10 +44,10 @@ var cmd_tag Command = Command{ }, }, }, - Interact: func(s *discordgo.Session, i *discordgo.InteractionCreate) { - switch i.ApplicationCommandData().Options[0].Name { + Interact: func(e *events.ApplicationCommandInteractionCreate) { + switch *e.SlashCommandInteractionData().SubCommandName { case "get": - GetTagCommand(i, i.ApplicationCommandData().Options[0].Options[0]) + GetTagCommand(e) case "add": AddTagCommand(i, "") case "remove": @@ -61,17 +59,19 @@ var cmd_tag Command = Command{ } }, ModalIDs: []string{"tag_add_modal"}, - ModalSubmit: func(s *discordgo.Session, i *discordgo.InteractionCreate) { - tagName := i.ModalSubmitData().Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value - tagContent := i.ModalSubmitData().Components[1].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value - addTag(i.GuildID, tagName, tagContent) - err := respond(i.Interaction, "Tag \""+tagName+"\" added!", true) + ModalSubmit: func(e *events.ModalSubmitInteractionCreate) { + tagName := e.Data.Text("tag_add_modal_name") + tagContent := e.Data.Text("tag_add_modal_content") + addTag(e.GuildID().String(), tagName, tagContent) + err := e.CreateMessage(discord.NewMessageCreateBuilder(). + SetContent("Tag \"" + tagName + "\" added!").SetEphemeral(true). + Build()) if err != nil { logrus.Error(err) } }, - Autocomplete: func(s *discordgo.Session, i *discordgo.InteractionCreate) { - AutocompleteTag(i) + Autocomplete: func(e *events.AutocompleteInteractionCreate) { + AutocompleteTag(e) }, } @@ -108,8 +108,8 @@ var context_tag Command = Command{ }, } -func GetTagCommand(i *discordgo.InteractionCreate, option *discordgo.ApplicationCommandInteractionDataOption) { - err := respond(i.Interaction, getTagContent(i.GuildID, option.Value.(string)), false) +func GetTagCommand(e *events.ApplicationCommandInteractionCreate) { + err := e.CreateMessage(discord.NewMessageCreateBuilder().SetContent(getTagContent(guildID, option)).SetEphemeral(true).Build()) if err != nil { logrus.Error(err) } diff --git a/go.mod b/go.mod index 222e87f..5dce953 100644 --- a/go.mod +++ b/go.mod @@ -11,9 +11,14 @@ require ( ) require ( - github.com/gorilla/websocket v1.4.2 // indirect - golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect + github.com/disgoorg/disgo v0.17.2 // indirect + github.com/disgoorg/json v1.1.0 // indirect + github.com/disgoorg/snowflake/v2 v2.0.1 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sys v0.16.0 // indirect ) replace github.com/vaporvee/acecore/custom => ./custom diff --git a/go.sum b/go.sum index a7b0048..78e5ddd 100644 --- a/go.sum +++ b/go.sum @@ -3,30 +3,48 @@ github.com/bwmarrin/discordgo v0.27.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/disgoorg/disgo v0.17.2 h1:RxiLq8guMtk+9tArFwve02iya2APQ9yZVtV30ySKNtw= +github.com/disgoorg/disgo v0.17.2/go.mod h1:8r3h9fXSz7BbACxLPsPbtB6LX8gaQFUETgPKV/0gAKQ= +github.com/disgoorg/json v1.1.0 h1:7xigHvomlVA9PQw9bMGO02PHGJJPqvX5AnwlYg/Tnys= +github.com/disgoorg/json v1.1.0/go.mod h1:BHDwdde0rpQFDVsRLKhma6Y7fTbQKub/zdGO5O9NqqA= +github.com/disgoorg/snowflake/v2 v2.0.1 h1:CuUxGLwggUxEswZOmZ+mZ5i0xSumQdXW9tXW7uGqe+0= +github.com/disgoorg/snowflake/v2 v2.0.1/go.mod h1:SPU9c2CNn5DSyb86QcKtdZgix9osEtKrHLW4rMhfLCs= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad h1:qIQkSlF5vAUHxEmTbaqt1hkJ/t6skqEGYiMag343ucI= +github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad/go.mod h1:/pA7k3zsXKdjjAiUhB5CjuKib9KJGCaLvZwtxGC8U0s= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/handlers.go b/handlers.go index 5027b1b..6f917c3 100644 --- a/handlers.go +++ b/handlers.go @@ -5,54 +5,43 @@ import ( "slices" "strings" - "github.com/bwmarrin/discordgo" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/events" + "github.com/disgoorg/snowflake/v2" "github.com/sirupsen/logrus" ) type Command struct { - Definition discordgo.ApplicationCommand - Interact func(s *discordgo.Session, i *discordgo.InteractionCreate) - ComponentInteract func(s *discordgo.Session, i *discordgo.InteractionCreate) - Autocomplete func(s *discordgo.Session, i *discordgo.InteractionCreate) - ModalSubmit func(s *discordgo.Session, i *discordgo.InteractionCreate) + Definition discord.SlashCommandCreate + Interact func(e *events.ApplicationCommandInteractionCreate) + Autocomplete func(e *events.AutocompleteInteractionCreate) + ComponentInteract func(e *events.ComponentInteractionCreate) + ModalSubmit func(e *events.ModalSubmitInteractionCreate) ComponentIDs []string ModalIDs []string - DynamicComponentIDs func() []string DynamicModalIDs func() []string + DynamicComponentIDs func() []string AllowDM bool } var commands []Command = []Command{cmd_form, cmd_ticket_form, cmd_tag, cmd_tag_short, cmd_dadjoke, cmd_ping, cmd_ask, cmd_sticky, cmd_cat, cmd_autojoinroles, cmd_autopublish, context_sticky, context_tag, cmd_userinfo} -func ready(s *discordgo.Session, event *discordgo.Ready) { +func ready(e *events.Ready) { logrus.Info("Starting up...") findAndDeleteUnusedMessages() - removeOldCommandFromAllGuilds(s) + removeOldCommandFromAllGuilds() var existingCommandNames []string - existingCommands, err := s.ApplicationCommands(s.State.User.ID, "") + existingCommands, err := client.Rest().GetGlobalCommands(app.Bot.ID, false) if err != nil { logrus.Errorf("error fetching existing global commands: %v", err) } else { for _, existingCommand := range existingCommands { - existingCommandNames = append(existingCommandNames, existingCommand.Name) - } - } - if slices.Contains(os.Args, "--clean") { - guilds := s.State.Guilds - if err != nil { - logrus.Errorf("error retrieving guilds: %v", err) - } - - for _, guild := range guilds { - _, err := s.ApplicationCommandBulkOverwrite(s.State.User.ID, guild.ID, []*discordgo.ApplicationCommand{}) - if err != nil { - logrus.Errorf("error deleting guild commands: %v", err) - } + existingCommandNames = append(existingCommandNames, existingCommand.Name()) } } for _, command := range commands { if !slices.Contains(existingCommandNames, command.Definition.Name) || slices.Contains(os.Args, "--update="+command.Definition.Name) || slices.Contains(os.Args, "--update=all") || slices.Contains(os.Args, "--clean") { - cmd, err := s.ApplicationCommandCreate(s.State.User.ID, "", &command.Definition) + cmd, err := client.Rest().CreateGlobalCommand(app.Bot.ID, command.Definition) if err != nil { logrus.Errorf("error creating global command '%s': %v", cmd.Name, err) } else { @@ -63,123 +52,138 @@ func ready(s *discordgo.Session, event *discordgo.Ready) { logrus.Info("Successfully started the Bot!") } -func interactionCreate(s *discordgo.Session, i *discordgo.InteractionCreate) { +func applicationCommandInteractionCreate(e *events.ApplicationCommandInteractionCreate) { for _, command := range commands { - switch i.Type { - case discordgo.InteractionApplicationCommand: - if command.Interact != nil && i.ApplicationCommandData().Name == command.Definition.Name { - if !command.AllowDM && i.Interaction.GuildID == "" { - respond(i.Interaction, "This command is not available in DMs.", true) - } else { - command.Interact(s, i) - } - } - case discordgo.InteractionApplicationCommandAutocomplete: - if command.Autocomplete != nil && i.ApplicationCommandData().Name == command.Definition.Name { - if !command.AllowDM && i.Interaction.GuildID == "" { - err := bot.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ - Type: discordgo.InteractionApplicationCommandAutocompleteResult, - Data: &discordgo.InteractionResponseData{ - Choices: nil, - }, - }) - if err != nil { - logrus.Error(err) - } - } else { - command.Autocomplete(s, i) - } - } - case discordgo.InteractionModalSubmit: - if !command.AllowDM && i.Interaction.GuildID == "" { - respond(i.Interaction, "This modal is not available in DMs.", true) + if command.Interact != nil && e.SlashCommandInteractionData().CommandName() == command.Definition.Name { + if !command.AllowDM && e.SlashCommandInteractionData().GuildID().String() == "" { + e.CreateMessage(discord.NewMessageCreateBuilder(). + SetContent("This command is not available in DMs.").SetEphemeral(true). + Build()) } else { - if command.ModalSubmit != nil { - var hasID bool = false - var modalIDs []string - if command.ModalIDs != nil { - modalIDs = command.ModalIDs - } - if command.DynamicModalIDs != nil { - modalIDs = append(command.ModalIDs, command.DynamicModalIDs()...) - } - for _, modalID := range modalIDs { - if strings.HasPrefix(i.ModalSubmitData().CustomID, modalID) { - hasID = true - break - } - } - if hasID { - command.ModalSubmit(s, i) - return // I have no idea why it crashes without that return - } - } - } - case discordgo.InteractionMessageComponent: - if !command.AllowDM && i.Interaction.GuildID == "" { - respond(i.Interaction, "This component is not available in DMs.", true) - } else { - if command.ComponentInteract != nil { - if slices.Contains(command.ComponentIDs, i.MessageComponentData().CustomID) || slices.ContainsFunc(command.DynamicComponentIDs(), func(id string) bool { - var customID string - if strings.ContainsAny(i.MessageComponentData().CustomID, ";") { - customID = strings.TrimSuffix(i.MessageComponentData().CustomID, ";"+strings.Split(i.MessageComponentData().CustomID, ";")[1]) - } else { - customID = i.MessageComponentData().CustomID - } - return id == customID - }) { - command.ComponentInteract(s, i) - } - } + command.Interact(e) } } } } -func removeOldCommandFromAllGuilds(s *discordgo.Session) { - existingCommands, err := s.ApplicationCommands(s.State.User.ID, "") - if err != nil { - logrus.Errorf("error fetching existing commands: %v\n", err) - var commandIDs []string - for _, command := range commands { - commandIDs = append(commandIDs, command.Definition.Name) - } - for _, existingCommand := range existingCommands { - if !slices.Contains(commandIDs, existingCommand.Name) { - logrus.Infof("Deleting command '%s'", existingCommand.Name) - err := s.ApplicationCommandDelete(s.State.User.ID, "", existingCommand.ID) +func autocompleteInteractionCreate(e *events.AutocompleteInteractionCreate) { + for _, command := range commands { + if command.Autocomplete != nil && e.Data.CommandName == command.Definition.Name { + if !command.AllowDM && e.GuildID().String() == "" { + err := e.AutocompleteResult(nil) if err != nil { - logrus.Errorf("error deleting command %s: %v", existingCommand.Name, err) + logrus.Error(err) + } + } else { + command.Autocomplete(e) + } + } + } +} + +func componentInteractionCreate(e *events.ComponentInteractionCreate) { + for _, command := range commands { + if !command.AllowDM && e.GuildID().String() == "" { + e.CreateMessage(discord.NewMessageCreateBuilder(). + SetContent("This component is not available in DMs.").SetEphemeral(true). + Build()) + } else { + if command.ComponentInteract != nil { + if slices.Contains(command.ComponentIDs, e.Data.CustomID()) || slices.ContainsFunc(command.DynamicComponentIDs(), func(id string) bool { + var customID string + if strings.ContainsAny(e.Data.CustomID(), ";") { + customID = strings.TrimSuffix(e.Data.CustomID(), ";"+strings.Split(e.Data.CustomID(), ";")[1]) + } else { + customID = e.Data.CustomID() + } + return id == customID + }) { + command.ComponentInteract(e) } } } } } -func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { - if len(m.Embeds) == 0 || m.Embeds[0].Footer == nil || m.Embeds[0].Footer.Text != "📌 Sticky message" { - if hasSticky(m.GuildID, m.ChannelID) { - stickymessageID := getStickyMessageID(m.GuildID, m.ChannelID) - err := s.ChannelMessageDelete(m.ChannelID, stickymessageID) - stickyMessage, _ := s.ChannelMessageSendEmbed(m.ChannelID, &discordgo.MessageEmbed{ - Type: discordgo.EmbedTypeArticle, - Footer: &discordgo.MessageEmbedFooter{ - Text: "📌 Sticky message", +func modalSubmitInteractionCreate(e *events.ModalSubmitInteractionCreate) { + for _, command := range commands { + if !command.AllowDM && e.GuildID().String() == "" { + e.CreateMessage(discord.NewMessageCreateBuilder(). + SetContent("This modal is not available in DMs.").SetEphemeral(true). + Build()) + } else { + if command.ModalSubmit != nil { + var hasID bool = false + var modalIDs []string + if command.ModalIDs != nil { + modalIDs = command.ModalIDs + } + if command.DynamicModalIDs != nil { + modalIDs = append(command.ModalIDs, command.DynamicModalIDs()...) + } + for _, modalID := range modalIDs { + if strings.HasPrefix(e.Data.CustomID, modalID) { + hasID = true + break + } + } + if hasID { + command.ModalSubmit(e) + return // I have no idea why it crashes without that return + } + } + } + } +} + +func removeOldCommandFromAllGuilds() { + globalCommands, err := client.Rest().GetGlobalCommands(app.Bot.ID, false) + if err != nil { + logrus.Error("error fetching existing global commands: %v", err) + return + } + var commandNames []string + for _, command := range commands { + commandNames = append(commandNames, command.Definition.Name) + } + + for _, existingCommand := range globalCommands { + if slices.Contains(commandNames, existingCommand.Name()) { + logrus.Info("Deleting command '%s'", existingCommand.Name) + err := client.Rest().DeleteGlobalCommand(app.Bot.ID, existingCommand.ID()) + if err != nil { + logrus.Error("error deleting command %s: %v", existingCommand.Name, err) + } + } + } +} + +func messageCreate(e *events.MessageCreate) { + if len(e.Message.Embeds) == 0 || e.Message.Embeds[0].Footer == nil || e.Message.Embeds[0].Footer.Text != "📌 Sticky message" { + if hasSticky(e.Message.GuildID.String(), e.Message.ChannelID.String()) { + stickymessageID := getStickyMessageID(e.Message.GuildID.String(), e.Message.ChannelID.String()) + err := e.Client().Rest().DeleteMessage(e.ChannelID, snowflake.MustParse(stickymessageID)) + stickyMessage, _ := e.Client().Rest().CreateMessage(e.ChannelID, discord.MessageCreate{ + Embeds: []discord.Embed{ + { + Footer: &discord.EmbedFooter{ + Text: "📌 Sticky message", + }, + Color: hexToDecimal(color["primary"]), + Description: getStickyMessageContent(e.Message.GuildID.String(), e.Message.ChannelID.String()), + }, }, - Color: hexToDecimal(color["primary"]), - Description: getStickyMessageContent(m.GuildID, m.ChannelID), }) if err != nil { logrus.Error(err) } - updateStickyMessageID(m.GuildID, m.ChannelID, stickyMessage.ID) + updateStickyMessageID(e.Message.GuildID.String(), e.Message.ChannelID.String(), stickyMessage.ID.String()) } } - channel, _ := s.Channel(m.ChannelID) - if channel.Type == discordgo.ChannelTypeGuildNews { - if isAutopublishEnabled(m.GuildID, m.ChannelID) { - _, err := s.ChannelMessageCrosspost(m.ChannelID, m.ID) + channel, _ := e.Channel() + if channel.Type() == discord.ChannelTypeGuildNews { + if isAutopublishEnabled(e.GuildID.String(), e.ChannelID.String()) { + _, err := e.Client().Rest().CrosspostMessage(e.ChannelID, e.MessageID) if err != nil { logrus.Error(err) } @@ -187,14 +191,14 @@ func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { } } -func messageDelete(s *discordgo.Session, m *discordgo.MessageDelete) { //TODO: also clear on bot start when message doesn't exist - tryDeleteUnusedMessage(m.ID) +func messageDelete(e *events.MessageDelete) { //TODO: also clear on bot start when message doesn't exist + tryDeleteUnusedMessage(e.MessageID.String()) } -func guildMemberJoin(s *discordgo.Session, m *discordgo.GuildMemberAdd) { - role := getAutoJoinRole(m.GuildID, m.User.Bot) +func guildMemberJoin(e *events.GuildMemberJoin) { + role := getAutoJoinRole(e.GuildID.String(), e.Member.User.Bot) if role != "" { - err := s.GuildMemberRoleAdd(m.GuildID, m.User.ID, role) + err := e.Client().Rest().AddMemberRole(e.GuildID, e.Member.User.ID, snowflake.MustParse(role)) if err != nil { logrus.Error(err) } diff --git a/main.go b/main.go index 46f3537..08e45e5 100644 --- a/main.go +++ b/main.go @@ -1,27 +1,30 @@ package main import ( + "context" + "database/sql" "io" + "net/url" "os" "os/signal" "strconv" "syscall" "time" - "database/sql" - "net/url" - - "github.com/bwmarrin/discordgo" + "github.com/disgoorg/disgo" + "github.com/disgoorg/disgo/bot" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/disgo/gateway" "github.com/joho/godotenv" - _ "github.com/lib/pq" "github.com/sirupsen/logrus" "github.com/vaporvee/acecore/log2webhook" ) -//TODO: add more error handlings - -var db *sql.DB -var bot *discordgo.Session +var ( + app *discord.Application + client bot.Client + db *sql.DB +) func main() { logrusInitFile() @@ -33,30 +36,42 @@ func main() { logrus.Fatal(err) } initTables() - bot, err = discordgo.New("Bot " + os.Getenv("BOT_TOKEN")) + client, err := disgo.New("Bot "+os.Getenv("BOT_TOKEN"), + bot.WithGatewayConfigOpts( + gateway.WithIntents( + gateway.IntentGuilds, + gateway.IntentGuildMessages, + gateway.IntentDirectMessages, + ), + ), + bot.WithEventListenerFunc(ready), + bot.WithEventListenerFunc(applicationCommandInteractionCreate), + bot.WithEventListenerFunc(autocompleteInteractionCreate), + bot.WithEventListenerFunc(messageCreate), + bot.WithEventListenerFunc(messageDelete), + bot.WithEventListenerFunc(guildMemberJoin), + ) if err != nil { logrus.Fatal("error creating Discord session,", err) return } else { logrus.Info("Discord session created") } - bot.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentsGuilds | discordgo.IntentMessageContent | discordgo.IntentGuildMembers - bot.AddHandler(ready) - bot.AddHandler(interactionCreate) - bot.AddHandler(messageCreate) - bot.AddHandler(messageDelete) - bot.AddHandler(guildMemberJoin) - err = bot.Open() - if err != nil { + + if err = client.OpenGateway(context.TODO()); err != nil { logrus.Error("error opening connection,", err) return } - logrus.Infof("Bot is now running as '%s'!", bot.State.User.Username) + app, err := client.Rest().GetCurrentApplication() + if err != nil { + logrus.Error(err) + } + logrus.Infof("Bot is now running as '%s'!", app.Bot.Username) + sc := make(chan os.Signal, 1) signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) <-sc logrus.Info("Shutting down...") - bot.Close() } func logrusInitFile() { diff --git a/tool.go b/tool.go index 1069c7d..e40efcb 100644 --- a/tool.go +++ b/tool.go @@ -9,7 +9,8 @@ import ( "strconv" "strings" - "github.com/bwmarrin/discordgo" + "github.com/disgoorg/disgo/discord" + "github.com/disgoorg/snowflake/v2" "github.com/sirupsen/logrus" ) @@ -34,46 +35,40 @@ type MessageIDs struct { ChannelID string } -func jsonStringShowModal(interaction *discordgo.Interaction, manageID string, formID string, overwrite ...string) { +func jsonStringShowModal(userID string, manageID string, formID string, overwrite ...string) discord.InteractionResponse { var modal ModalJson = getModalByFormID(formID) - var components []discordgo.MessageComponent + var components []discord.ContainerComponent for index, component := range modal.Form { - var style discordgo.TextInputStyle = discordgo.TextInputShort + var style discord.TextInputStyle = discord.TextInputStyleShort if component.IsParagraph { - style = discordgo.TextInputParagraph + style = discord.TextInputStyleParagraph } - components = append(components, discordgo.ActionsRow{ - Components: []discordgo.MessageComponent{ - discordgo.TextInput{ - CustomID: fmt.Sprint(index), - Label: component.Label, - Style: style, - Placeholder: component.Placeholder, - Required: component.Required, - MaxLength: component.MaxLength, - MinLength: component.MinLength, - Value: component.Value, - }, + components = append(components, discord.ActionRowComponent{ + discord.TextInputComponent{ + CustomID: fmt.Sprint(index), + Label: component.Label, + Style: style, + Placeholder: component.Placeholder, + Required: component.Required, + MaxLength: component.MaxLength, + MinLength: &component.MinLength, + Value: component.Value, }, }) } if overwrite != nil && overwrite[0] != "" { modal.Title = overwrite[0] } - var err error - if modal.Title != "" && components != nil { - err = bot.InteractionRespond(interaction, &discordgo.InteractionResponse{ - Type: discordgo.InteractionResponseModal, - Data: &discordgo.InteractionResponseData{ - CustomID: manageID + ":" + interaction.Member.User.ID, - Title: modal.Title, - Components: components, - }, - }) - } - if err != nil { - logrus.Error(err) + + return discord.InteractionResponse{ + Type: discord.InteractionResponseTypeModal, + Data: &discord.ModalCreate{ + CustomID: manageID + ":" + userID, + Title: modal.Title, + Components: components, + }, } + } // Why does the golang compiler care about commands?? @@ -106,22 +101,21 @@ func getModalByFormID(formID string) ModalJson { return modal } -func getHighestRole(guildID string) (*discordgo.Role, error) { - botMember, err := bot.GuildMember(guildID, bot.State.User.ID) +func getHighestRole(guildID string) (*discord.Role, error) { + botmember, err := client.Rest().GetMember(snowflake.MustParse(guildID), app.Bot.ID) if err != nil { return nil, err } - roles, err := bot.GuildRoles(guildID) + roles, err := client.Rest().GetRoles(snowflake.MustParse(guildID)) if err != nil { return nil, err } - - var highestRole *discordgo.Role - for _, roleID := range botMember.Roles { + var highestRole *discord.Role + for _, roleID := range botmember.RoleIDs { for _, role := range roles { if role.ID == roleID { if highestRole == nil || role.Position > highestRole.Position { - highestRole = role + highestRole = &role } break } @@ -130,9 +124,7 @@ func getHighestRole(guildID string) (*discordgo.Role, error) { return highestRole, nil } -func int64Ptr(i int64) *int64 { - return &i -} +func ptr(s string) *string { return &s } func hexToDecimal(hexColor string) int { hexColor = strings.TrimPrefix(hexColor, "#") @@ -173,59 +165,21 @@ func simpleGetFromAPI(key string, url string) interface{} { return result[key] } -func respond(interaction *discordgo.Interaction, content string, ephemeral bool) error { - var flag discordgo.MessageFlags - if ephemeral { - flag = discordgo.MessageFlagsEphemeral - } - err := bot.InteractionRespond(interaction, &discordgo.InteractionResponse{ - Type: discordgo.InteractionResponseChannelMessageWithSource, - Data: &discordgo.InteractionResponseData{ - Content: content, - Flags: flag, - }, - }) - if err != nil { - return err - } - return nil -} - -func respondEmbed(interaction *discordgo.Interaction, embed discordgo.MessageEmbed, ephemeral bool) error { - var flag discordgo.MessageFlags - if ephemeral { - flag = discordgo.MessageFlagsEphemeral - } - err := bot.InteractionRespond(interaction, &discordgo.InteractionResponse{ - Type: discordgo.InteractionResponseChannelMessageWithSource, - Data: &discordgo.InteractionResponseData{ - Flags: flag, - Embeds: []*discordgo.MessageEmbed{ - &embed, - }, - }, - }) - if err != nil { - return err - } - return nil -} - func findAndDeleteUnusedMessages() { for _, message := range getAllSavedMessages() { - _, err := bot.ChannelMessage(message.ChannelID, message.ID) + _, err := client.Rest().GetMessage(snowflake.MustParse(message.ChannelID), snowflake.MustParse(message.ID)) if err != nil { tryDeleteUnusedMessage(message.ID) } } } -func isIDRole(guildID, id string) bool { - _, err1 := bot.GuildMember(guildID, id) +func isIDRole(guildID snowflake.ID, id snowflake.ID) bool { + _, err1 := client.Rest().GetMember(guildID, id) if err1 == nil { return false } - roles, err2 := bot.GuildRoles(guildID) + roles, err2 := client.Rest().GetRoles(guildID) if err2 == nil { for _, role := range roles { if role.ID == id {