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 (
"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)
}

11
go.mod
View File

@@ -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

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.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=

View File

@@ -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)
}

55
main.go
View File

@@ -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() {

118
tool.go
View File

@@ -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 {