started porting to disgo

This commit is contained in:
2024-04-04 01:27:59 +02:00
parent d952924b17
commit 8579328ee4
6 changed files with 254 additions and 258 deletions

View File

@@ -2,22 +2,23 @@ package main
import ( import (
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/events"
"github.com/disgoorg/json"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
var cmd_tag Command = Command{ var cmd_tag Command = Command{
Definition: discordgo.ApplicationCommand{ Definition: discord.SlashCommandCreate{
Name: "tag", Name: "tag",
DefaultMemberPermissions: int64Ptr(discordgo.PermissionManageServer), DefaultMemberPermissions: json.NewNullablePtr(discord.PermissionManageGuild),
Description: "A command to show and edit saved presaved messages.", Description: "A command to show and edit saved presaved messages.",
Options: []*discordgo.ApplicationCommandOption{ Options: []discord.ApplicationCommandOption{
{ discord.ApplicationCommandOptionSubCommand{
Name: "get", Name: "get",
Description: "A command to get messages saved to the bot.", Description: "A command to get messages saved to the bot.",
Type: discordgo.ApplicationCommandOptionSubCommand, Options: []discord.ApplicationCommandOption{
Options: []*discordgo.ApplicationCommandOption{ discord.ApplicationCommandOptionString{
{
Type: discordgo.ApplicationCommandOptionString,
Name: "tag", Name: "tag",
Description: "Your predefined tag for the saved message", Description: "Your predefined tag for the saved message",
Required: true, Required: true,
@@ -25,18 +26,15 @@ var cmd_tag Command = Command{
}, },
}, },
}, },
{ discord.ApplicationCommandOptionSubCommand{
Name: "add", Name: "add",
Description: "A command to add messages saved to the bot.", Description: "A command to add messages saved to the bot.",
Type: discordgo.ApplicationCommandOptionSubCommand,
}, },
{ discord.ApplicationCommandOptionSubCommand{
Name: "remove", Name: "remove",
Description: "A command to remove messages saved to the bot.", Description: "A command to remove messages saved to the bot.",
Type: discordgo.ApplicationCommandOptionSubCommand, Options: []discord.ApplicationCommandOption{
Options: []*discordgo.ApplicationCommandOption{ discord.ApplicationCommandOptionString{
{
Type: discordgo.ApplicationCommandOptionString,
Name: "tag", Name: "tag",
Description: "The tag you want to remove", Description: "The tag you want to remove",
Required: true, Required: true,
@@ -46,10 +44,10 @@ var cmd_tag Command = Command{
}, },
}, },
}, },
Interact: func(s *discordgo.Session, i *discordgo.InteractionCreate) { Interact: func(e *events.ApplicationCommandInteractionCreate) {
switch i.ApplicationCommandData().Options[0].Name { switch *e.SlashCommandInteractionData().SubCommandName {
case "get": case "get":
GetTagCommand(i, i.ApplicationCommandData().Options[0].Options[0]) GetTagCommand(e)
case "add": case "add":
AddTagCommand(i, "") AddTagCommand(i, "")
case "remove": case "remove":
@@ -61,17 +59,19 @@ var cmd_tag Command = Command{
} }
}, },
ModalIDs: []string{"tag_add_modal"}, ModalIDs: []string{"tag_add_modal"},
ModalSubmit: func(s *discordgo.Session, i *discordgo.InteractionCreate) { ModalSubmit: func(e *events.ModalSubmitInteractionCreate) {
tagName := i.ModalSubmitData().Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value tagName := e.Data.Text("tag_add_modal_name")
tagContent := i.ModalSubmitData().Components[1].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value tagContent := e.Data.Text("tag_add_modal_content")
addTag(i.GuildID, tagName, tagContent) addTag(e.GuildID().String(), tagName, tagContent)
err := respond(i.Interaction, "Tag \""+tagName+"\" added!", true) err := e.CreateMessage(discord.NewMessageCreateBuilder().
SetContent("Tag \"" + tagName + "\" added!").SetEphemeral(true).
Build())
if err != nil { if err != nil {
logrus.Error(err) logrus.Error(err)
} }
}, },
Autocomplete: func(s *discordgo.Session, i *discordgo.InteractionCreate) { Autocomplete: func(e *events.AutocompleteInteractionCreate) {
AutocompleteTag(i) AutocompleteTag(e)
}, },
} }
@@ -108,8 +108,8 @@ var context_tag Command = Command{
}, },
} }
func GetTagCommand(i *discordgo.InteractionCreate, option *discordgo.ApplicationCommandInteractionDataOption) { func GetTagCommand(e *events.ApplicationCommandInteractionCreate) {
err := respond(i.Interaction, getTagContent(i.GuildID, option.Value.(string)), false) err := e.CreateMessage(discord.NewMessageCreateBuilder().SetContent(getTagContent(guildID, option)).SetEphemeral(true).Build())
if err != nil { if err != nil {
logrus.Error(err) logrus.Error(err)
} }

11
go.mod
View File

@@ -11,9 +11,14 @@ require (
) )
require ( require (
github.com/gorilla/websocket v1.4.2 // indirect github.com/disgoorg/disgo v0.17.2 // indirect
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect github.com/disgoorg/json v1.1.0 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // 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 replace github.com/vaporvee/acecore/custom => ./custom

18
go.sum
View File

@@ -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.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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 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 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= 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 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 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 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 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/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 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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 h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= 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.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-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 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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/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/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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/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 h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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=

View File

@@ -5,54 +5,43 @@ import (
"slices" "slices"
"strings" "strings"
"github.com/bwmarrin/discordgo" "github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/events"
"github.com/disgoorg/snowflake/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
type Command struct { type Command struct {
Definition discordgo.ApplicationCommand Definition discord.SlashCommandCreate
Interact func(s *discordgo.Session, i *discordgo.InteractionCreate) Interact func(e *events.ApplicationCommandInteractionCreate)
ComponentInteract func(s *discordgo.Session, i *discordgo.InteractionCreate) Autocomplete func(e *events.AutocompleteInteractionCreate)
Autocomplete func(s *discordgo.Session, i *discordgo.InteractionCreate) ComponentInteract func(e *events.ComponentInteractionCreate)
ModalSubmit func(s *discordgo.Session, i *discordgo.InteractionCreate) ModalSubmit func(e *events.ModalSubmitInteractionCreate)
ComponentIDs []string ComponentIDs []string
ModalIDs []string ModalIDs []string
DynamicComponentIDs func() []string
DynamicModalIDs func() []string DynamicModalIDs func() []string
DynamicComponentIDs func() []string
AllowDM bool 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} 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...") logrus.Info("Starting up...")
findAndDeleteUnusedMessages() findAndDeleteUnusedMessages()
removeOldCommandFromAllGuilds(s) removeOldCommandFromAllGuilds()
var existingCommandNames []string var existingCommandNames []string
existingCommands, err := s.ApplicationCommands(s.State.User.ID, "") existingCommands, err := client.Rest().GetGlobalCommands(app.Bot.ID, false)
if err != nil { if err != nil {
logrus.Errorf("error fetching existing global commands: %v", err) logrus.Errorf("error fetching existing global commands: %v", err)
} else { } else {
for _, existingCommand := range existingCommands { for _, existingCommand := range existingCommands {
existingCommandNames = append(existingCommandNames, existingCommand.Name) 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)
}
} }
} }
for _, command := range commands { 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") { 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 { if err != nil {
logrus.Errorf("error creating global command '%s': %v", cmd.Name, err) logrus.Errorf("error creating global command '%s': %v", cmd.Name, err)
} else { } else {
@@ -63,36 +52,65 @@ func ready(s *discordgo.Session, event *discordgo.Ready) {
logrus.Info("Successfully started the Bot!") logrus.Info("Successfully started the Bot!")
} }
func interactionCreate(s *discordgo.Session, i *discordgo.InteractionCreate) { func applicationCommandInteractionCreate(e *events.ApplicationCommandInteractionCreate) {
for _, command := range commands { for _, command := range commands {
switch i.Type { if command.Interact != nil && e.SlashCommandInteractionData().CommandName() == command.Definition.Name {
case discordgo.InteractionApplicationCommand: if !command.AllowDM && e.SlashCommandInteractionData().GuildID().String() == "" {
if command.Interact != nil && i.ApplicationCommandData().Name == command.Definition.Name { e.CreateMessage(discord.NewMessageCreateBuilder().
if !command.AllowDM && i.Interaction.GuildID == "" { SetContent("This command is not available in DMs.").SetEphemeral(true).
respond(i.Interaction, "This command is not available in DMs.", true) Build())
} else { } else {
command.Interact(s, i) command.Interact(e)
} }
} }
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{ func autocompleteInteractionCreate(e *events.AutocompleteInteractionCreate) {
Type: discordgo.InteractionApplicationCommandAutocompleteResult, for _, command := range commands {
Data: &discordgo.InteractionResponseData{ if command.Autocomplete != nil && e.Data.CommandName == command.Definition.Name {
Choices: nil, if !command.AllowDM && e.GuildID().String() == "" {
}, err := e.AutocompleteResult(nil)
})
if err != nil { if err != nil {
logrus.Error(err) logrus.Error(err)
} }
} else { } else {
command.Autocomplete(s, i) command.Autocomplete(e)
} }
} }
case discordgo.InteractionModalSubmit: }
if !command.AllowDM && i.Interaction.GuildID == "" { }
respond(i.Interaction, "This modal is not available in DMs.", true)
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 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 { } else {
if command.ModalSubmit != nil { if command.ModalSubmit != nil {
var hasID bool = false var hasID bool = false
@@ -104,82 +122,68 @@ func interactionCreate(s *discordgo.Session, i *discordgo.InteractionCreate) {
modalIDs = append(command.ModalIDs, command.DynamicModalIDs()...) modalIDs = append(command.ModalIDs, command.DynamicModalIDs()...)
} }
for _, modalID := range modalIDs { for _, modalID := range modalIDs {
if strings.HasPrefix(i.ModalSubmitData().CustomID, modalID) { if strings.HasPrefix(e.Data.CustomID, modalID) {
hasID = true hasID = true
break break
} }
} }
if hasID { if hasID {
command.ModalSubmit(s, i) command.ModalSubmit(e)
return // I have no idea why it crashes without that return 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)
}
}
}
}
} }
} }
func removeOldCommandFromAllGuilds(s *discordgo.Session) { func removeOldCommandFromAllGuilds() {
existingCommands, err := s.ApplicationCommands(s.State.User.ID, "") globalCommands, err := client.Rest().GetGlobalCommands(app.Bot.ID, false)
if err != nil { if err != nil {
logrus.Errorf("error fetching existing commands: %v\n", err) logrus.Error("error fetching existing global commands: %v", err)
var commandIDs []string return
}
var commandNames []string
for _, command := range commands { for _, command := range commands {
commandIDs = append(commandIDs, command.Definition.Name) commandNames = append(commandNames, command.Definition.Name)
} }
for _, existingCommand := range existingCommands {
if !slices.Contains(commandIDs, existingCommand.Name) { for _, existingCommand := range globalCommands {
logrus.Infof("Deleting command '%s'", existingCommand.Name) if slices.Contains(commandNames, existingCommand.Name()) {
err := s.ApplicationCommandDelete(s.State.User.ID, "", existingCommand.ID) logrus.Info("Deleting command '%s'", existingCommand.Name)
err := client.Rest().DeleteGlobalCommand(app.Bot.ID, existingCommand.ID())
if err != nil { if err != nil {
logrus.Errorf("error deleting command %s: %v", existingCommand.Name, err) logrus.Error("error deleting command %s: %v", existingCommand.Name, err)
}
} }
} }
} }
} }
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { func messageCreate(e *events.MessageCreate) {
if len(m.Embeds) == 0 || m.Embeds[0].Footer == nil || m.Embeds[0].Footer.Text != "📌 Sticky message" { if len(e.Message.Embeds) == 0 || e.Message.Embeds[0].Footer == nil || e.Message.Embeds[0].Footer.Text != "📌 Sticky message" {
if hasSticky(m.GuildID, m.ChannelID) { if hasSticky(e.Message.GuildID.String(), e.Message.ChannelID.String()) {
stickymessageID := getStickyMessageID(m.GuildID, m.ChannelID) stickymessageID := getStickyMessageID(e.Message.GuildID.String(), e.Message.ChannelID.String())
err := s.ChannelMessageDelete(m.ChannelID, stickymessageID) err := e.Client().Rest().DeleteMessage(e.ChannelID, snowflake.MustParse(stickymessageID))
stickyMessage, _ := s.ChannelMessageSendEmbed(m.ChannelID, &discordgo.MessageEmbed{ stickyMessage, _ := e.Client().Rest().CreateMessage(e.ChannelID, discord.MessageCreate{
Type: discordgo.EmbedTypeArticle, Embeds: []discord.Embed{
Footer: &discordgo.MessageEmbedFooter{ {
Footer: &discord.EmbedFooter{
Text: "📌 Sticky message", Text: "📌 Sticky message",
}, },
Color: hexToDecimal(color["primary"]), Color: hexToDecimal(color["primary"]),
Description: getStickyMessageContent(m.GuildID, m.ChannelID), Description: getStickyMessageContent(e.Message.GuildID.String(), e.Message.ChannelID.String()),
},
},
}) })
if err != nil { if err != nil {
logrus.Error(err) 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) channel, _ := e.Channel()
if channel.Type == discordgo.ChannelTypeGuildNews { if channel.Type() == discord.ChannelTypeGuildNews {
if isAutopublishEnabled(m.GuildID, m.ChannelID) { if isAutopublishEnabled(e.GuildID.String(), e.ChannelID.String()) {
_, err := s.ChannelMessageCrosspost(m.ChannelID, m.ID) _, err := e.Client().Rest().CrosspostMessage(e.ChannelID, e.MessageID)
if err != nil { if err != nil {
logrus.Error(err) 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 func messageDelete(e *events.MessageDelete) { //TODO: also clear on bot start when message doesn't exist
tryDeleteUnusedMessage(m.ID) tryDeleteUnusedMessage(e.MessageID.String())
} }
func guildMemberJoin(s *discordgo.Session, m *discordgo.GuildMemberAdd) { func guildMemberJoin(e *events.GuildMemberJoin) {
role := getAutoJoinRole(m.GuildID, m.User.Bot) role := getAutoJoinRole(e.GuildID.String(), e.Member.User.Bot)
if role != "" { 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 { if err != nil {
logrus.Error(err) logrus.Error(err)
} }

55
main.go
View File

@@ -1,27 +1,30 @@
package main package main
import ( import (
"context"
"database/sql"
"io" "io"
"net/url"
"os" "os"
"os/signal" "os/signal"
"strconv" "strconv"
"syscall" "syscall"
"time" "time"
"database/sql" "github.com/disgoorg/disgo"
"net/url" "github.com/disgoorg/disgo/bot"
"github.com/disgoorg/disgo/discord"
"github.com/bwmarrin/discordgo" "github.com/disgoorg/disgo/gateway"
"github.com/joho/godotenv" "github.com/joho/godotenv"
_ "github.com/lib/pq"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/vaporvee/acecore/log2webhook" "github.com/vaporvee/acecore/log2webhook"
) )
//TODO: add more error handlings var (
app *discord.Application
var db *sql.DB client bot.Client
var bot *discordgo.Session db *sql.DB
)
func main() { func main() {
logrusInitFile() logrusInitFile()
@@ -33,30 +36,42 @@ func main() {
logrus.Fatal(err) logrus.Fatal(err)
} }
initTables() 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 { if err != nil {
logrus.Fatal("error creating Discord session,", err) logrus.Fatal("error creating Discord session,", err)
return return
} else { } else {
logrus.Info("Discord session created") logrus.Info("Discord session created")
} }
bot.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentsGuilds | discordgo.IntentMessageContent | discordgo.IntentGuildMembers
bot.AddHandler(ready) if err = client.OpenGateway(context.TODO()); err != nil {
bot.AddHandler(interactionCreate)
bot.AddHandler(messageCreate)
bot.AddHandler(messageDelete)
bot.AddHandler(guildMemberJoin)
err = bot.Open()
if err != nil {
logrus.Error("error opening connection,", err) logrus.Error("error opening connection,", err)
return 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) sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-sc <-sc
logrus.Info("Shutting down...") logrus.Info("Shutting down...")
bot.Close()
} }
func logrusInitFile() { func logrusInitFile() {

98
tool.go
View File

@@ -9,7 +9,8 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/bwmarrin/discordgo" "github.com/disgoorg/disgo/discord"
"github.com/disgoorg/snowflake/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@@ -34,46 +35,40 @@ type MessageIDs struct {
ChannelID string 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 modal ModalJson = getModalByFormID(formID)
var components []discordgo.MessageComponent var components []discord.ContainerComponent
for index, component := range modal.Form { for index, component := range modal.Form {
var style discordgo.TextInputStyle = discordgo.TextInputShort var style discord.TextInputStyle = discord.TextInputStyleShort
if component.IsParagraph { if component.IsParagraph {
style = discordgo.TextInputParagraph style = discord.TextInputStyleParagraph
} }
components = append(components, discordgo.ActionsRow{ components = append(components, discord.ActionRowComponent{
Components: []discordgo.MessageComponent{ discord.TextInputComponent{
discordgo.TextInput{
CustomID: fmt.Sprint(index), CustomID: fmt.Sprint(index),
Label: component.Label, Label: component.Label,
Style: style, Style: style,
Placeholder: component.Placeholder, Placeholder: component.Placeholder,
Required: component.Required, Required: component.Required,
MaxLength: component.MaxLength, MaxLength: component.MaxLength,
MinLength: component.MinLength, MinLength: &component.MinLength,
Value: component.Value, Value: component.Value,
}, },
},
}) })
} }
if overwrite != nil && overwrite[0] != "" { if overwrite != nil && overwrite[0] != "" {
modal.Title = overwrite[0] modal.Title = overwrite[0]
} }
var err error
if modal.Title != "" && components != nil { return discord.InteractionResponse{
err = bot.InteractionRespond(interaction, &discordgo.InteractionResponse{ Type: discord.InteractionResponseTypeModal,
Type: discordgo.InteractionResponseModal, Data: &discord.ModalCreate{
Data: &discordgo.InteractionResponseData{ CustomID: manageID + ":" + userID,
CustomID: manageID + ":" + interaction.Member.User.ID,
Title: modal.Title, Title: modal.Title,
Components: components, Components: components,
}, },
})
}
if err != nil {
logrus.Error(err)
} }
} }
// Why does the golang compiler care about commands?? // Why does the golang compiler care about commands??
@@ -106,22 +101,21 @@ func getModalByFormID(formID string) ModalJson {
return modal return modal
} }
func getHighestRole(guildID string) (*discordgo.Role, error) { func getHighestRole(guildID string) (*discord.Role, error) {
botMember, err := bot.GuildMember(guildID, bot.State.User.ID) botmember, err := client.Rest().GetMember(snowflake.MustParse(guildID), app.Bot.ID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
roles, err := bot.GuildRoles(guildID) roles, err := client.Rest().GetRoles(snowflake.MustParse(guildID))
if err != nil { if err != nil {
return nil, err return nil, err
} }
var highestRole *discord.Role
var highestRole *discordgo.Role for _, roleID := range botmember.RoleIDs {
for _, roleID := range botMember.Roles {
for _, role := range roles { for _, role := range roles {
if role.ID == roleID { if role.ID == roleID {
if highestRole == nil || role.Position > highestRole.Position { if highestRole == nil || role.Position > highestRole.Position {
highestRole = role highestRole = &role
} }
break break
} }
@@ -130,9 +124,7 @@ func getHighestRole(guildID string) (*discordgo.Role, error) {
return highestRole, nil return highestRole, nil
} }
func int64Ptr(i int64) *int64 { func ptr(s string) *string { return &s }
return &i
}
func hexToDecimal(hexColor string) int { func hexToDecimal(hexColor string) int {
hexColor = strings.TrimPrefix(hexColor, "#") hexColor = strings.TrimPrefix(hexColor, "#")
@@ -173,59 +165,21 @@ func simpleGetFromAPI(key string, url string) interface{} {
return result[key] 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() { func findAndDeleteUnusedMessages() {
for _, message := range getAllSavedMessages() { 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 { if err != nil {
tryDeleteUnusedMessage(message.ID) tryDeleteUnusedMessage(message.ID)
} }
} }
} }
func isIDRole(guildID, id string) bool { func isIDRole(guildID snowflake.ID, id snowflake.ID) bool {
_, err1 := bot.GuildMember(guildID, id) _, err1 := client.Rest().GetMember(guildID, id)
if err1 == nil { if err1 == nil {
return false return false
} }
roles, err2 := bot.GuildRoles(guildID) roles, err2 := client.Rest().GetRoles(guildID)
if err2 == nil { if err2 == nil {
for _, role := range roles { for _, role := range roles {
if role.ID == id { if role.ID == id {