some fixes and added logging

This commit is contained in:
2024-03-16 23:53:34 +01:00
parent 220eddce6f
commit c14400f74a
17 changed files with 318 additions and 162 deletions

View File

@@ -1,6 +1,9 @@
package main
import "github.com/bwmarrin/discordgo"
import (
"github.com/bwmarrin/discordgo"
"github.com/sirupsen/logrus"
)
var cmd_ask Command = Command{
Definition: discordgo.ApplicationCommand{
@@ -16,11 +19,14 @@ var cmd_ask Command = Command{
},
},
Interact: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
respondEmbed(i.Interaction, discordgo.MessageEmbed{
err := respondEmbed(i.Interaction, discordgo.MessageEmbed{
Type: discordgo.EmbedTypeImage,
Color: hexToDecimal(color["primary"]),
Image: &discordgo.MessageEmbedImage{
URL: simpleGetFromAPI("image", "https://yesno.wtf/api").(string),
}}, false)
if err != nil {
logrus.Error("Failed to respond with embed: ", err)
}
},
}

View File

@@ -1,6 +1,9 @@
package main
import "github.com/bwmarrin/discordgo"
import (
"github.com/bwmarrin/discordgo"
"github.com/sirupsen/logrus"
)
var cmd_autojoinroles Command = Command{
Definition: discordgo.ApplicationCommand{
@@ -40,7 +43,10 @@ var cmd_autojoinroles Command = Command{
if len(i.ApplicationCommandData().Options[0].Options) == 1 {
var givenRole *discordgo.Role = i.ApplicationCommandData().Options[0].Options[0].RoleValue(s, i.GuildID)
role = givenRole.ID
botrole, _ := getHighestRole(i.GuildID)
botrole, err := getHighestRole(i.GuildID)
if err != nil {
logrus.Error(err)
}
if givenRole.Position >= botrole.Position {
content = "<@&" + role + "> is not below the Bot's current highest role(<@&" + botrole.ID + ">). That makes it unable to manage it."
} else {
@@ -53,7 +59,10 @@ var cmd_autojoinroles Command = Command{
} else if setAutoJoinRole(i.GuildID, option, role) {
content = "Deleted auto join role for " + option + "s"
}
respond(i.Interaction, content, true)
err := respond(i.Interaction, content, true)
if err != nil {
logrus.Error(err)
}
purgeUnusedAutoJoinRoles(i.GuildID)
},
}

View File

@@ -1,6 +1,9 @@
package main
import "github.com/bwmarrin/discordgo"
import (
"github.com/bwmarrin/discordgo"
"github.com/sirupsen/logrus"
)
var cmd_autopublish Command = Command{
Definition: discordgo.ApplicationCommand{
@@ -11,12 +14,21 @@ var cmd_autopublish Command = Command{
channel, _ := s.State.Channel(i.ChannelID)
if channel.Type == discordgo.ChannelTypeGuildNews {
if toggleAutoPublish(i.GuildID, i.ChannelID) {
respond(i.Interaction, "Autopublishing is now disabled on <#"+i.ChannelID+">", true)
err := respond(i.Interaction, "Autopublishing is now disabled on <#"+i.ChannelID+">", true)
if err != nil {
logrus.Error(err)
}
} else {
respond(i.Interaction, "Autopublishing is now enabled on <#"+i.ChannelID+">", true)
err := respond(i.Interaction, "Autopublishing is now enabled on <#"+i.ChannelID+">", true)
if err != nil {
logrus.Error(err)
}
}
} else {
respond(i.Interaction, "This is not an announcement channel!", true)
err := respond(i.Interaction, "This is not an announcement channel!", true)
if err != nil {
logrus.Error(err)
}
}
},
}

View File

@@ -6,6 +6,7 @@ import (
"net/http"
"github.com/bwmarrin/discordgo"
"github.com/sirupsen/logrus"
)
var cmd_cat Command = Command{
@@ -16,12 +17,17 @@ var cmd_cat Command = Command{
Interact: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
cat, err := GetCatImageURL()
if err == nil {
respondEmbed(i.Interaction, discordgo.MessageEmbed{
err := respondEmbed(i.Interaction, discordgo.MessageEmbed{
Type: discordgo.EmbedTypeImage,
Color: hexToDecimal(color["primary"]),
Image: &discordgo.MessageEmbedImage{
URL: cat,
}}, false)
if err != nil {
logrus.Error(err)
}
} else {
logrus.Error(err)
}
},
}

View File

@@ -2,6 +2,7 @@ package main
import (
"github.com/bwmarrin/discordgo"
"github.com/sirupsen/logrus"
)
var cmd_dadjoke Command = Command{
@@ -10,6 +11,9 @@ var cmd_dadjoke Command = Command{
Description: "Gives you a random joke that is as bad as your dad would tell them",
},
Interact: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
respond(i.Interaction, simpleGetFromAPI("joke", "https://icanhazdadjoke.com/").(string), false)
err := respond(i.Interaction, simpleGetFromAPI("joke", "https://icanhazdadjoke.com/").(string), false)
if err != nil {
logrus.Error(err)
}
},
}

View File

@@ -2,12 +2,12 @@ package main
import (
"bytes"
"log"
"os"
"strings"
"github.com/bwmarrin/discordgo"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
)
var fileData []byte
@@ -79,7 +79,7 @@ var cmd_form Command = Command{
case "help":
fileData, _ = os.ReadFile("./form_templates/form_demo.json")
fileReader := bytes.NewReader(fileData)
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "NOT SUPPORTED YET!(use `/form add` instead)\n\nGet the example file edit it (make sure to have a unique \"form_type\") and submit it via `/form create`.\nOr use the demo button to get an idea of how the example would look like.",
@@ -107,13 +107,18 @@ var cmd_form Command = Command{
},
},
})
if err != nil {
logrus.Error(err)
}
case "custom":
respond(i.Interaction, "Feature not available yet use `/form add` instead", true)
err := respond(i.Interaction, "Feature not available yet use `/form add` instead", true)
if err != nil {
logrus.Error(err)
}
case "add":
var title, formID, overwriteTitle, acceptChannelID string
var modsCanComment bool
options := i.ApplicationCommandData().Options[0]
for _, opt := range options.Options {
switch opt.Name {
case "type":
@@ -140,7 +145,6 @@ var cmd_form Command = Command{
title = val
}
}
var exists bool = true
var formManageID uuid.UUID = uuid.New()
for exists {
@@ -148,7 +152,7 @@ var cmd_form Command = Command{
exists = getFormManageIdExists(formManageID)
}
message, _ := s.ChannelMessageSendComplex(i.ChannelID, &discordgo.MessageSend{
message, err := s.ChannelMessageSendComplex(i.ChannelID, &discordgo.MessageSend{
Embed: &discordgo.MessageEmbed{
Color: hexToDecimal(color["primary"]),
Title: title,
@@ -171,8 +175,14 @@ var cmd_form Command = Command{
},
},
})
if err != nil {
logrus.Error(err)
}
addFormButton(i.GuildID, i.ChannelID, message.ID, formManageID.String(), formID, options.Options[0].ChannelValue(s).ID, overwriteTitle, acceptChannelID, modsCanComment)
respond(i.Interaction, "Successfully added form button!", true)
err = respond(i.Interaction, "Successfully added form button!", true)
if err != nil {
logrus.Error(err)
}
}
},
ComponentInteract: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
@@ -219,12 +229,18 @@ var cmd_form Command = Command{
},
})
if err != nil {
log.Println(err)
logrus.Error(err)
} else {
respond(i.Interaction, "Submited!", true)
err = respond(i.Interaction, "Submited!", true)
if err != nil {
logrus.Error(err)
}
}
} else {
respond(i.Interaction, "The form data would be send to a specified channel. 🤲", true)
err := respond(i.Interaction, "The form data would be send to a specified channel. 🤲", true)
if err != nil {
logrus.Error(err)
}
}
}
},
@@ -243,12 +259,15 @@ var cmd_form Command = Command{
Value: "template_general",
},
}
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionApplicationCommandAutocompleteResult,
Data: &discordgo.InteractionResponseData{
Choices: choices,
},
})
if err != nil {
logrus.Error(err)
}
},
}

View File

@@ -6,6 +6,7 @@ import (
"time"
"github.com/bwmarrin/discordgo"
"github.com/sirupsen/logrus"
)
var cmd_ping Command = Command{
@@ -22,7 +23,7 @@ var cmd_ping Command = Command{
resp, err := client.Get("https://discord.com/api/v9/gateway/bot")
if err != nil {
fmt.Println("Error:", err)
logrus.Error(err)
return
}
defer resp.Body.Close()
@@ -36,10 +37,13 @@ var cmd_ping Command = Command{
} else {
ping_color = "red"
}
respondEmbed(i.Interaction, discordgo.MessageEmbed{
err = respondEmbed(i.Interaction, discordgo.MessageEmbed{
Title: s.State.User.Username + " ping",
Description: fmt.Sprintf("# %.2fms", ping.Seconds()*1000),
Type: discordgo.EmbedTypeArticle,
Color: hexToDecimal(color[ping_color])}, true)
if err != nil {
logrus.Error(err)
}
},
}

View File

@@ -1,9 +1,8 @@
package main
import (
"log"
"github.com/bwmarrin/discordgo"
"github.com/sirupsen/logrus"
)
var cmd_sticky Command = Command{
@@ -27,7 +26,7 @@ var cmd_sticky Command = Command{
Interact: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
switch i.ApplicationCommandData().Options[0].Name {
case "add":
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseModal,
Data: &discordgo.InteractionResponseData{
CustomID: "sticky_modal",
@@ -49,13 +48,25 @@ var cmd_sticky Command = Command{
},
},
})
if err != nil {
logrus.Error(err)
}
case "remove":
if hasSticky(i.GuildID, i.ChannelID) {
s.ChannelMessageDelete(i.ChannelID, getStickyMessageID(i.GuildID, i.ChannelID))
err := s.ChannelMessageDelete(i.ChannelID, getStickyMessageID(i.GuildID, i.ChannelID))
if err != nil {
logrus.Error(err)
}
removeSticky(i.GuildID, i.ChannelID)
respond(i.Interaction, "The sticky message was removed from this channel!", true)
err = respond(i.Interaction, "The sticky message was removed from this channel!", true)
if err != nil {
logrus.Error(err)
}
} else {
respond(i.Interaction, "This channel has no sticky message!", true)
err := respond(i.Interaction, "This channel has no sticky message!", true)
if err != nil {
logrus.Error(err)
}
}
}
},
@@ -71,12 +82,18 @@ var cmd_sticky Command = Command{
Description: text,
})
if err != nil {
log.Println(err)
logrus.Error(err)
}
if addSticky(i.GuildID, i.ChannelID, text, message.ID) {
respond(i.Interaction, "Sticky message in this channel was updated!", true)
err := respond(i.Interaction, "Sticky message in this channel was updated!", true)
if err != nil {
logrus.Error(err)
}
} else {
respond(i.Interaction, "Message sticked to the channel!", true)
err := respond(i.Interaction, "Message sticked to the channel!", true)
if err != nil {
logrus.Error(err)
}
}
},
}

View File

@@ -1,9 +1,8 @@
package main
import (
"log"
"github.com/bwmarrin/discordgo"
"github.com/sirupsen/logrus"
)
var cmd_tag Command = Command{
@@ -50,9 +49,9 @@ var cmd_tag Command = Command{
Interact: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
switch i.ApplicationCommandData().Options[0].Name {
case "get":
GetTagCommand(s, i, i.ApplicationCommandData().Options[0].Options[0])
GetTagCommand(i, i.ApplicationCommandData().Options[0].Options[0])
case "add":
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseModal,
Data: &discordgo.InteractionResponseData{
CustomID: "tag_add_modal" + i.Interaction.Member.User.ID,
@@ -86,9 +85,15 @@ var cmd_tag Command = Command{
},
},
})
if err != nil {
logrus.Error(err)
}
case "remove":
removeTag(i.GuildID, i.ApplicationCommandData().Options[0].Options[0].StringValue())
respond(i.Interaction, "Tag removed!", true)
err := respond(i.Interaction, "Tag removed!", true)
if err != nil {
logrus.Error(err)
}
}
},
ModalIDs: []string{"tag_add_modal"},
@@ -96,10 +101,13 @@ var cmd_tag Command = Command{
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)
respond(i.Interaction, "Tag \""+tagName+"\" added!", true)
err := respond(i.Interaction, "Tag \""+tagName+"\" added!", true)
if err != nil {
logrus.Error(err)
}
},
Autocomplete: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
AutocompleteTag(s, i)
AutocompleteTag(i)
},
}
@@ -118,31 +126,37 @@ var cmd_tag_short Command = Command{
},
},
Interact: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
GetTagCommand(s, i, i.ApplicationCommandData().Options[0])
GetTagCommand(i, i.ApplicationCommandData().Options[0])
},
Autocomplete: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
AutocompleteTag(s, i)
AutocompleteTag(i)
},
}
func GetTagCommand(s *discordgo.Session, i *discordgo.InteractionCreate, option *discordgo.ApplicationCommandInteractionDataOption) {
respond(i.Interaction, getTagContent(i.GuildID, option.Value.(string)), false)
func GetTagCommand(i *discordgo.InteractionCreate, option *discordgo.ApplicationCommandInteractionDataOption) {
err := respond(i.Interaction, getTagContent(i.GuildID, option.Value.(string)), false)
if err != nil {
logrus.Error(err)
}
}
func AutocompleteTag(s *discordgo.Session, i *discordgo.InteractionCreate) {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
func AutocompleteTag(i *discordgo.InteractionCreate) {
err := bot.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionApplicationCommandAutocompleteResult,
Data: &discordgo.InteractionResponseData{
Choices: generateTagChoices(i.GuildID),
},
})
if err != nil {
logrus.Error(err)
}
}
func generateTagChoices(guildID string) []*discordgo.ApplicationCommandOptionChoice {
choices := []*discordgo.ApplicationCommandOptionChoice{}
IDs, err := getTagIDs(guildID)
if err != nil {
log.Println("Error getting tag keys:", err)
logrus.Error(err)
return choices
}
for _, id := range IDs {

View File

@@ -1,33 +0,0 @@
package main
import (
"encoding/json"
"io"
"log"
"net/http"
)
func simpleGetFromAPI(key string, url string) interface{} {
client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Println("Error creating request:", err)
}
req.Header.Set("Accept", "application/json")
resp, err := client.Do(req)
if err != nil {
log.Println("Error making request:", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Println("Error reading response body:", err)
}
var result map[string]interface{}
err = json.Unmarshal(body, &result)
if err != nil {
log.Println("Error decoding JSON:", err)
}
return result[key]
}

3
go.mod
View File

@@ -11,6 +11,7 @@ require (
require (
github.com/gorilla/websocket v1.4.2 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
)

11
go.sum
View File

@@ -1,5 +1,7 @@
github.com/bwmarrin/discordgo v0.27.1 h1:ib9AIc/dom1E/fSIulrBwnez0CToJE113ZGt4HoliGY=
github.com/bwmarrin/discordgo v0.27.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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=
@@ -8,11 +10,20 @@ 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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
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/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
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/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
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/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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,13 +1,12 @@
package main
import (
"fmt"
"log"
"os"
"slices"
"strings"
"github.com/bwmarrin/discordgo"
"github.com/sirupsen/logrus"
)
type Command struct {
@@ -25,7 +24,7 @@ type Command struct {
var commands []Command = []Command{cmd_form, cmd_tag, cmd_tag_short, cmd_dadjoke, cmd_ping, cmd_ask, cmd_sticky, cmd_cat, cmd_autojoinroles, cmd_autopublish}
func ready(s *discordgo.Session, event *discordgo.Ready) {
fmt.Print("\nStarting up...")
logrus.Info("\nStarting up...")
findAndDeleteUnusedMessages()
removeOldCommandFromAllGuilds(s)
var existingCommandNames []string
@@ -35,28 +34,28 @@ func ready(s *discordgo.Session, event *discordgo.Ready) {
existingCommandNames = append(existingCommandNames, existingCommand.Name)
}
if err != nil {
fmt.Printf("error fetching existing commands for guild %s: %v\n", guild.Name, err)
logrus.Errorf("error fetching existing commands for guild %s: %v\n", guild.Name, err)
continue
}
for _, command := range commands {
if !slices.Contains(existingCommandNames, command.Definition.Name) || slices.Contains(os.Args, "--update="+command.Definition.Name) {
cmd, err := s.ApplicationCommandCreate(s.State.User.ID, guild.ID, &command.Definition)
fmt.Printf("\nAdded command \"%s\"", cmd.Name)
logrus.Infof("\nAdded command \"%s\"", cmd.Name)
if err != nil {
fmt.Println("error creating command,", err)
logrus.Error("error creating command,", err)
continue
}
}
}
}
fmt.Print("\nSuccessfully started the Bot!")
logrus.Info("\nSuccessfully started the Bot!")
}
func guildCreate(s *discordgo.Session, event *discordgo.GuildCreate) {
for _, command := range commands {
_, err := s.ApplicationCommandCreate(s.State.User.ID, event.Guild.ID, &command.Definition)
if err != nil {
log.Printf("error creating command for guild %s: %v\n", event.Guild.Name, err)
logrus.Errorf("error creating command for guild %s: %v\n", event.Guild.Name, err)
}
}
}
@@ -107,7 +106,7 @@ func removeOldCommandFromAllGuilds(s *discordgo.Session) {
for _, guild := range s.State.Guilds {
existingCommands, err := s.ApplicationCommands(s.State.User.ID, guild.ID)
if err != nil {
fmt.Printf("error fetching existing commands for guild %s: %v\n", guild.Name, err)
logrus.Errorf("error fetching existing commands for guild %s: %v\n", guild.Name, err)
continue
}
var commandIDs []string
@@ -116,10 +115,10 @@ func removeOldCommandFromAllGuilds(s *discordgo.Session) {
}
for _, existingCommand := range existingCommands {
if !slices.Contains(commandIDs, existingCommand.Name) {
fmt.Printf("\nDeleting command \"%s\"", existingCommand.Name)
logrus.Infof("\nDeleting command \"%s\"", existingCommand.Name)
err := s.ApplicationCommandDelete(s.State.User.ID, guild.ID, existingCommand.ID)
if err != nil {
fmt.Printf("error deleting command %s for guild %s: %v\n", existingCommand.Name, guild.Name, err)
logrus.Errorf("error deleting command %s for guild %s: %v\n", existingCommand.Name, guild.Name, err)
}
}
}
@@ -129,7 +128,7 @@ func removeOldCommandFromAllGuilds(s *discordgo.Session) {
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) {
s.ChannelMessageDelete(m.ChannelID, getStickyMessageID(m.GuildID, m.ChannelID))
err := s.ChannelMessageDelete(m.ChannelID, getStickyMessageID(m.GuildID, m.ChannelID))
stickyMessage, _ := s.ChannelMessageSendEmbed(m.ChannelID, &discordgo.MessageEmbed{
Type: discordgo.EmbedTypeArticle,
Footer: &discordgo.MessageEmbedFooter{
@@ -138,13 +137,19 @@ func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
Color: hexToDecimal(color["primary"]),
Description: getStickyMessageContent(m.GuildID, m.ChannelID),
})
if err != nil {
logrus.Error(err)
}
updateStickyMessageID(m.GuildID, m.ChannelID, stickyMessage.ID)
}
}
channel, _ := s.Channel(m.ChannelID)
if channel.Type == discordgo.ChannelTypeGuildNews {
if isAutopublishEnabled(m.GuildID, m.ChannelID) {
s.ChannelMessageCrosspost(m.ChannelID, m.ID)
_, err := s.ChannelMessageCrosspost(m.ChannelID, m.ID)
if err != nil {
logrus.Error(err)
}
}
}
}
@@ -156,6 +161,6 @@ func messageDelete(s *discordgo.Session, m *discordgo.MessageDelete) { //TODO: a
func guildMemberJoin(s *discordgo.Session, m *discordgo.GuildMemberAdd) {
err := s.GuildMemberRoleAdd(m.GuildID, m.User.ID, getAutoJoinRole(m.GuildID, m.User.Bot))
if err != nil {
log.Println(err)
logrus.Error(err)
}
}

5
logs/bot.1710629569.log Normal file
View File

@@ -0,0 +1,5 @@
{"file":"/home/vaporvee/acecore/main.go:40","func":"main.main","level":"info","msg":"Discord session created","time":"2024-03-16T23:52:49+01:00"}
{"file":"/home/vaporvee/acecore/main.go:54","func":"main.main","level":"info","msg":"\nBot is now running as \"acecore [DEV]\"!","time":"2024-03-16T23:52:49+01:00"}
{"file":"/home/vaporvee/acecore/handlers.go:27","func":"main.ready","level":"info","msg":"\nStarting up...","time":"2024-03-16T23:52:49+01:00"}
{"file":"/home/vaporvee/acecore/handlers.go:51","func":"main.ready","level":"info","msg":"\nSuccessfully started the Bot!","time":"2024-03-16T23:52:50+01:00"}
{"file":"/home/vaporvee/acecore/main.go:58","func":"main.main","level":"info","msg":"\nShutting down...","time":"2024-03-16T23:53:10+01:00"}

46
main.go
View File

@@ -1,11 +1,12 @@
package main
import (
"fmt"
"log"
"io"
"os"
"os/signal"
"strconv"
"syscall"
"time"
"database/sql"
"net/url"
@@ -13,6 +14,7 @@ import (
"github.com/bwmarrin/discordgo"
"github.com/joho/godotenv"
_ "github.com/lib/pq"
"github.com/sirupsen/logrus"
)
//TODO: add more error handlings
@@ -21,21 +23,21 @@ var db *sql.DB
var bot *discordgo.Session
func main() {
godotenv.Load()
logrusInitFile()
var err error
godotenv.Load()
connStr := "postgresql://" + os.Getenv("DB_USER") + ":" + url.QueryEscape(os.Getenv("DB_PASSWORD")) + "@" + os.Getenv("DB_SERVER") + ":" + string(os.Getenv("DB_PORT")) + "/" + os.Getenv("DB_NAME") + "?sslmode=disable&application_name=Discord Bot"
db, err = sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
logrus.Fatal(err)
}
initTables()
bot, err = discordgo.New("Bot " + os.Getenv("BOT_TOKEN"))
if err != nil {
fmt.Println("error creating Discord session,", err)
logrus.Fatal("error creating Discord session,", err)
return
} else {
fmt.Println("Discord session created")
logrus.Info("Discord session created")
}
bot.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentsGuilds | discordgo.IntentMessageContent | discordgo.IntentGuildMembers
bot.AddHandler(ready)
@@ -46,13 +48,37 @@ func main() {
bot.AddHandler(guildMemberJoin)
err = bot.Open()
if err != nil {
fmt.Println("error opening connection,", err)
logrus.Error("error opening connection,", err)
return
}
fmt.Printf("\nBot is now running as \"%s\"!", bot.State.User.Username)
logrus.Infof("\nBot is now running as \"%s\"!", bot.State.User.Username)
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-sc
fmt.Println("\nShutting down...")
logrus.Info("\nShutting down...")
bot.Close()
}
func logrusInitFile() {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetFormatter(&logrus.JSONFormatter{})
logrus.SetReportCaller(true)
timestamp := time.Now().Unix()
var file_name string = "logs/bot." + strconv.FormatInt(timestamp, 10) + ".log"
if _, err := os.Stat("logs"); os.IsNotExist(err) {
err := os.Mkdir("logs", 0755)
if err != nil {
logrus.Error(err)
return
}
}
log, err := os.OpenFile(file_name, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
logrus.Error(err)
return
}
mw := io.MultiWriter(os.Stdout, log)
logrus.SetOutput(mw)
}

View File

@@ -4,6 +4,7 @@ import (
"log"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
)
func initTables() {
@@ -74,12 +75,12 @@ func addTag(guildID, tagName, tagContent string) bool {
id = uuid.New()
err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM tags WHERE guild_id = $1 AND tag_id = $2)", guildID, id).Scan(&exists)
if err != nil {
log.Println(err)
logrus.Error(err)
}
}
_, err := db.Exec("INSERT INTO tags (guild_id, tag_name, tag_content, tag_id) VALUES ($1, $2, $3, $4)", guildID, tagName, tagContent, id)
if err != nil {
log.Println(err)
logrus.Error(err)
}
return exists
@@ -88,12 +89,12 @@ func removeTag(guildID string, tagID string) {
var exists bool
err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM tags WHERE guild_id = $1 AND tag_id = $2)", guildID, tagID).Scan(&exists)
if err != nil {
log.Println(err)
logrus.Error(err)
}
if exists {
_, err = db.Exec("DELETE FROM tags WHERE guild_id = $1 AND tag_id = $2", guildID, tagID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
}
}
@@ -135,12 +136,12 @@ func addSticky(guildID string, channelID string, messageContent string, messageI
if exists {
_, err := db.Exec("UPDATE sticky SET message_content = $1 WHERE guild_id = $2 AND channel_id = $3", messageContent, guildID, channelID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
} else {
_, err := db.Exec("INSERT INTO sticky (guild_id, channel_id, message_id, message_content) VALUES ($1, $2, $3, $4)", guildID, channelID, messageID, messageContent)
if err != nil {
log.Println(err)
logrus.Error(err)
}
}
return exists
@@ -150,7 +151,7 @@ func hasSticky(guildID string, channelID string) bool {
var exists bool
err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM sticky WHERE guild_id = $1 AND channel_id = $2)", guildID, channelID).Scan(&exists)
if err != nil {
log.Println(err)
logrus.Error(err)
}
return exists
}
@@ -161,7 +162,7 @@ func getStickyMessageID(guildID string, channelID string) string {
if exists {
err := db.QueryRow("SELECT message_id FROM sticky WHERE guild_id = $1 AND channel_id = $2", guildID, channelID).Scan(&messageID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
}
return messageID
@@ -172,7 +173,7 @@ func getStickyMessageContent(guildID string, channelID string) string {
if exists {
err := db.QueryRow("SELECT message_content FROM sticky WHERE guild_id = $1 AND channel_id = $2", guildID, channelID).Scan(&messageID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
}
return messageID
@@ -183,7 +184,7 @@ func updateStickyMessageID(guildID string, channelID string, messageID string) {
if exists {
_, err := db.Exec("UPDATE sticky SET message_id = $1 WHERE guild_id = $2 AND channel_id = $3", messageID, guildID, channelID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
}
}
@@ -191,7 +192,7 @@ func updateStickyMessageID(guildID string, channelID string, messageID string) {
func removeSticky(guildID string, channelID string) {
_, err := db.Exec("DELETE FROM sticky WHERE guild_id = $1 AND channel_id = $2", guildID, channelID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
}
@@ -199,7 +200,7 @@ func getFormManageIdExists(id uuid.UUID) bool {
var exists bool
err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM form_manage WHERE form_manage_id = $1)", id).Scan(&exists)
if err != nil {
log.Println(err)
logrus.Error(err)
}
return exists
}
@@ -207,7 +208,7 @@ func getFormManageIdExists(id uuid.UUID) bool {
func addFormButton(guildID string, channelID string, messageID string, formManageID string, formType string, resultChannelID string, overwriteTitle string, acceptChannelID string, modsCanComment bool) {
_, err := db.Exec("INSERT INTO form_manage (guild_id, form_manage_id, channel_id, message_id, form_type, result_channel_id, overwrite_title, accept_channel_id, mods_can_comment) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", guildID, formManageID, channelID, messageID, formType, resultChannelID, overwriteTitle, acceptChannelID, modsCanComment)
if err != nil {
log.Println(err)
logrus.Error(err)
}
}
@@ -218,7 +219,7 @@ func getFormManageIDs() []string {
var IDs []string
rows, err := db.Query("SELECT form_manage_id FROM form_manage")
if err != nil {
log.Println(err)
logrus.Error(err)
return nil
}
defer rows.Close()
@@ -226,14 +227,14 @@ func getFormManageIDs() []string {
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
log.Println(err)
logrus.Error(err)
return nil
}
IDs = append(IDs, id)
}
if err := rows.Err(); err != nil {
log.Println(err)
logrus.Error(err)
return nil
}
return IDs
@@ -243,7 +244,7 @@ func getFormType(formManageID string) string {
var formType string
err := db.QueryRow("SELECT form_type FROM form_manage WHERE form_manage_id = $1", formManageID).Scan(&formType)
if err != nil {
log.Println(err)
logrus.Error(err)
}
return formType
}
@@ -252,19 +253,19 @@ func getFormResultValues(formManageID string) FormResult {
var result FormResult
err := db.QueryRow("SELECT overwrite_title FROM form_manage WHERE form_manage_id = $1", formManageID).Scan(&result.OverwriteTitle)
if err != nil {
log.Println(err)
logrus.Error(err)
}
err = db.QueryRow("SELECT result_channel_id FROM form_manage WHERE form_manage_id = $1", formManageID).Scan(&result.ResultChannelID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
err = db.QueryRow("SELECT accept_channel_id FROM form_manage WHERE form_manage_id = $1", formManageID).Scan(&result.AcceptChannelID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
err = db.QueryRow("SELECT mods_can_comment FROM form_manage WHERE form_manage_id = $1", formManageID).Scan(&result.ModsCanComment)
if err != nil {
log.Println(err)
logrus.Error(err)
}
return result
}
@@ -273,7 +274,7 @@ func getFormOverwriteTitle(formManageID string) string {
var overwriteTitle string
err := db.QueryRow("SELECT overwrite_title FROM form_manage WHERE form_manage_id = $1", formManageID).Scan(&overwriteTitle)
if err != nil {
log.Println(err)
logrus.Error(err)
}
return overwriteTitle
}
@@ -283,21 +284,21 @@ func setAutoJoinRole(guildID string, option string, roleID string) bool {
var autojoinroles_exists bool
err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM autojoinroles WHERE guild_id = $1)", guildID).Scan(&autojoinroles_exists)
if err != nil {
log.Println(err)
logrus.Error(err)
}
err = db.QueryRow("SELECT EXISTS (SELECT 1 FROM autojoinroles WHERE guild_id = $1 AND "+option+"_role IS NOT NULL AND "+option+"_role != '')", guildID).Scan(&role_exists)
if err != nil {
log.Println(err)
logrus.Error(err)
}
if autojoinroles_exists {
_, err = db.Exec("UPDATE autojoinroles SET "+option+"_role = $1 WHERE guild_id = $2", roleID, guildID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
} else {
_, err = db.Exec("INSERT INTO autojoinroles (guild_id, "+option+"_role) VALUES ($1, $2)", guildID, roleID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
}
return role_exists
@@ -306,7 +307,7 @@ func setAutoJoinRole(guildID string, option string, roleID string) bool {
func purgeUnusedAutoJoinRoles(guildID string) {
_, err := db.Exec("DELETE FROM autojoinroles WHERE guild_id = $1 AND user_role = '' OR user_role IS NULL AND bot_role = '' OR bot_role IS NULL", guildID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
}
@@ -320,7 +321,7 @@ func getAutoJoinRole(guildID string, isBot bool) string {
}
err := db.QueryRow("SELECT "+isBotString+"_role FROM autojoinroles WHERE guild_id = $1", guildID).Scan(&role)
if err != nil {
log.Println(err, guildID)
logrus.Error(err, guildID)
}
return role
}
@@ -329,17 +330,17 @@ func toggleAutoPublish(guildID string, newsChannelID string) bool {
var exists bool
err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM autopublish WHERE guild_id = $1 AND news_channel_id = $2)", guildID, newsChannelID).Scan(&exists)
if err != nil {
log.Print(err)
logrus.Error(err)
}
if exists {
_, err := db.Exec("DELETE FROM autopublish WHERE guild_id = $1 AND news_channel_id = $2", guildID, newsChannelID)
if err != nil {
log.Print(err)
logrus.Error(err)
}
} else {
_, err := db.Exec("INSERT INTO autopublish (guild_id, news_channel_id) VALUES ($1, $2)", guildID, newsChannelID)
if err != nil {
log.Print(err)
logrus.Error(err)
}
}
return exists
@@ -349,7 +350,7 @@ func isAutopublishEnabled(guildID string, newsChannelID string) bool {
var enabled bool
err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM autopublish WHERE guild_id = $1 AND news_channel_id = $2)", guildID, newsChannelID).Scan(&enabled)
if err != nil {
log.Print(err)
logrus.Error(err)
}
return enabled
}
@@ -357,7 +358,7 @@ func isAutopublishEnabled(guildID string, newsChannelID string) bool {
func tryDeleteUnusedMessage(messageID string) {
_, err := db.Exec("DELETE FROM form_manage WHERE message_id = $1", messageID)
if err != nil {
log.Println(err)
logrus.Error(err)
}
}
@@ -365,20 +366,20 @@ func getAllSavedMessages() []MessageIDs {
var savedMessages []MessageIDs
rows, err := db.Query("SELECT message_id, channel_id FROM form_manage")
if err != nil {
log.Print(err)
logrus.Error(err)
return nil
}
defer rows.Close()
for rows.Next() {
var messageID, channelID string
if err := rows.Scan(&messageID, &channelID); err != nil {
log.Print(err)
logrus.Error(err)
continue
}
savedMessages = append(savedMessages, MessageIDs{ID: messageID, ChannelID: channelID})
}
if err := rows.Err(); err != nil {
log.Print(err)
logrus.Error(err)
}
return savedMessages
}

91
tool.go
View File

@@ -1,14 +1,16 @@
package main
import (
"embed"
"encoding/json"
"fmt"
"log"
"os"
"io"
"net/http"
"strconv"
"strings"
"github.com/bwmarrin/discordgo"
"github.com/sirupsen/logrus"
)
type ModalJsonField struct {
@@ -58,33 +60,47 @@ func jsonStringShowModal(interaction *discordgo.Interaction, manageID string, fo
if overwrite[0] != "" {
modal.Title = overwrite[0]
}
err := bot.InteractionRespond(interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseModal,
Data: &discordgo.InteractionResponseData{
CustomID: manageID + ":" + interaction.Member.User.ID,
Title: modal.Title,
Components: components,
},
})
var err error
if 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 {
log.Print(err)
logrus.Error(err)
}
}
// Why does the golang compiler care about commands??
//
//go:embed form_templates/*.json
var formTemplates embed.FS
func getModalByFormID(formID string) ModalJson {
var modal ModalJson
//TODO: add custom forms
entries, err := os.ReadDir("./form_templates")
entries, err := formTemplates.ReadDir("form_templates")
if err != nil {
log.Print(err)
logrus.Error(err)
return modal
}
for _, entry := range entries {
if strings.HasPrefix(entry.Name(), formID) {
json_file, err := os.ReadFile("./form_templates/" + entry.Name())
jsonFile, err := formTemplates.ReadFile("form_templates/" + entry.Name())
if err != nil {
log.Print(err)
logrus.Error(err)
continue
}
json.Unmarshal(json_file, &modal)
err = json.Unmarshal(jsonFile, &modal)
if err != nil {
logrus.Error(err)
continue
}
break
}
}
return modal
@@ -128,26 +144,55 @@ func hexToDecimal(hexColor string) int {
return int(decimal)
}
func respond(interaction *discordgo.Interaction, content string, ephemeral bool) {
func simpleGetFromAPI(key string, url string) interface{} {
client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
logrus.Error("Error creating request:", err)
}
req.Header.Set("Accept", "application/json")
resp, err := client.Do(req)
if err != nil {
logrus.Error("Error making request:", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
logrus.Error("Error reading response body:", err)
}
var result map[string]interface{}
err = json.Unmarshal(body, &result)
if err != nil {
logrus.Error("Error decoding JSON:", err)
}
return result[key]
}
func respond(interaction *discordgo.Interaction, content string, ephemeral bool) error {
var flag discordgo.MessageFlags
if ephemeral {
flag = discordgo.MessageFlagsEphemeral
}
bot.InteractionRespond(interaction, &discordgo.InteractionResponse{
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) {
func respondEmbed(interaction *discordgo.Interaction, embed discordgo.MessageEmbed, ephemeral bool) error {
var flag discordgo.MessageFlags
if ephemeral {
flag = discordgo.MessageFlagsEphemeral
}
bot.InteractionRespond(interaction, &discordgo.InteractionResponse{
err := bot.InteractionRespond(interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Flags: flag,
@@ -156,6 +201,10 @@ func respondEmbed(interaction *discordgo.Interaction, embed discordgo.MessageEmb
},
},
})
if err != nil {
return err
}
return nil
}
func findAndDeleteUnusedMessages() {