continued on forms

This commit is contained in:
2024-03-08 19:10:25 +01:00
parent b253845a1d
commit 1ea34f11b6
13 changed files with 127 additions and 106 deletions

View File

@@ -16,7 +16,7 @@ var cmd_ask Command = Command{
},
},
Interact: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
respondEmbed(s, i.Interaction, discordgo.MessageEmbed{
respondEmbed(i.Interaction, discordgo.MessageEmbed{
Type: discordgo.EmbedTypeImage,
Color: hexToDecimal(color["primary"]),
Image: &discordgo.MessageEmbedImage{

View File

@@ -40,7 +40,7 @@ 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(s, i.GuildID)
botrole, _ := getHighestRole(i.GuildID)
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 +53,7 @@ var cmd_autojoinroles Command = Command{
} else if setAutoJoinRole(i.GuildID, option, role) {
content = "Deleted auto join role for " + option + "s"
}
respond(s, i.Interaction, content, true)
respond(i.Interaction, content, true)
purgeUnusedAutoJoinRoles(i.GuildID)
},
}

View File

@@ -11,12 +11,12 @@ var cmd_autopublish Command = Command{
channel, _ := s.State.Channel(i.ChannelID)
if channel.Type == discordgo.ChannelTypeGuildNews {
if toggleAutoPublish(i.GuildID, i.ChannelID) {
respond(s, i.Interaction, "Autopublishing is now disabled on <#"+i.ChannelID+">", true)
respond(i.Interaction, "Autopublishing is now disabled on <#"+i.ChannelID+">", true)
} else {
respond(s, i.Interaction, "Autopublishing is now enabled on <#"+i.ChannelID+">", true)
respond(i.Interaction, "Autopublishing is now enabled on <#"+i.ChannelID+">", true)
}
} else {
respond(s, i.Interaction, "This is not an announcement channel!", true)
respond(i.Interaction, "This is not an announcement channel!", true)
}
},
}

View File

@@ -15,7 +15,7 @@ var cmd_cat Command = Command{
Description: "Random cat pictures",
},
Interact: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
respondEmbed(s, i.Interaction, discordgo.MessageEmbed{
respondEmbed(i.Interaction, discordgo.MessageEmbed{
Type: discordgo.EmbedTypeImage,
Color: hexToDecimal(color["primary"]),
Image: &discordgo.MessageEmbedImage{

View File

@@ -10,6 +10,6 @@ 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(s, i.Interaction, simpleGetFromAPI("joke", "https://icanhazdadjoke.com/").(string), false)
respond(i.Interaction, simpleGetFromAPI("joke", "https://icanhazdadjoke.com/").(string), false)
},
}

View File

@@ -13,8 +13,9 @@ var fileData []byte
var cmd_form Command = Command{
Definition: discordgo.ApplicationCommand{
Name: "form",
Description: "Create custom forms right inside Discord",
Name: "form",
DefaultMemberPermissions: int64Ptr(discordgo.PermissionManageChannels),
Description: "Create custom forms right inside Discord",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionSubCommand,
@@ -118,7 +119,7 @@ var cmd_form Command = Command{
},
})
case "custom":
respond(s, i.Interaction, "Feature not available yet use `/form add` instead", true)
respond(i.Interaction, "Feature not available yet use `/form add` instead", true)
case "add":
var title, formID, overwriteTitle, acceptChannelID string
var modsCanComment bool
@@ -180,63 +181,22 @@ var cmd_form Command = Command{
},
})
addFormButton(i.GuildID, i.ChannelID, message.ID, formManageID.String(), formID, options.Options[0].ChannelValue(s).ID, overwriteTitle, acceptChannelID, modsCanComment)
respond(s, i.Interaction, "Successfully added form button!", true)
respond(i.Interaction, "Successfully added form button!", true)
}
},
ComponentInteract: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
if strings.HasPrefix(i.Interaction.MessageComponentData().CustomID, "form:") {
respond(s, i.Interaction, getFormType(strings.TrimPrefix(i.Interaction.MessageComponentData().CustomID, "form:")), true)
jsonStringShowModal(i.Interaction, i.Interaction.MessageComponentData().CustomID, getFormType(strings.TrimPrefix(i.Interaction.MessageComponentData().CustomID, "form:")))
}
if i.Interaction.MessageComponentData().CustomID == "form_demo" {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseModal,
Data: &discordgo.InteractionResponseData{
CustomID: "form_demo" + i.Interaction.Member.User.ID,
Title: "Demo form",
Components: []discordgo.MessageComponent{
discordgo.ActionsRow{
Components: []discordgo.MessageComponent{
discordgo.TextInput{
CustomID: "demo_short",
Label: "This is a simple textline",
Style: discordgo.TextInputShort,
Placeholder: "...and it is required!",
Value: "",
Required: true,
MaxLength: 20,
MinLength: 0,
},
},
},
discordgo.ActionsRow{
Components: []discordgo.MessageComponent{
discordgo.TextInput{
CustomID: "demo_paragraph",
Label: "This is a paragraph",
Style: discordgo.TextInputParagraph,
Placeholder: "...and it is not required!",
Value: "We already have some input here",
Required: false,
MaxLength: 2000,
MinLength: 0,
},
},
},
},
},
})
jsonStringShowModal(i.Interaction, "form_demo", "form_demo")
}
},
ModalIDs: getFormTypes(),
ModalSubmit: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
respond(s, i.Interaction, "The form data would be send to a specified channel. 🤲", true)
respond(i.Interaction, "The form data would be send to a specified channel. 🤲", true)
},
Autocomplete: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
choices := []*discordgo.ApplicationCommandOptionChoice{
{
Name: "Feedback",
Value: "template_feedback",
},
{
Name: "Support Ticket",
Value: "template_ticket",

View File

@@ -36,7 +36,7 @@ var cmd_ping Command = Command{
} else {
ping_color = "red"
}
respondEmbed(s, i.Interaction, discordgo.MessageEmbed{
respondEmbed(i.Interaction, discordgo.MessageEmbed{
Title: s.State.User.Username + " ping",
Description: fmt.Sprintf("# %.2fms", ping.Seconds()*1000),
Type: discordgo.EmbedTypeArticle,

View File

@@ -53,9 +53,9 @@ var cmd_sticky Command = Command{
if hasSticky(i.GuildID, i.ChannelID) {
s.ChannelMessageDelete(i.ChannelID, getStickyMessageID(i.GuildID, i.ChannelID))
removeSticky(i.GuildID, i.ChannelID)
respond(s, i.Interaction, "The sticky message was removed from this channel!", true)
respond(i.Interaction, "The sticky message was removed from this channel!", true)
} else {
respond(s, i.Interaction, "This channel has no sticky message!", true)
respond(i.Interaction, "This channel has no sticky message!", true)
}
}
},
@@ -74,9 +74,9 @@ var cmd_sticky Command = Command{
log.Println(err)
}
if addSticky(i.GuildID, i.ChannelID, text, message.ID) {
respond(s, i.Interaction, "Sticky message in this channel was updated!", true)
respond(i.Interaction, "Sticky message in this channel was updated!", true)
} else {
respond(s, i.Interaction, "Message sticked to the channel!", true)
respond(i.Interaction, "Message sticked to the channel!", true)
}
},
}

View File

@@ -9,7 +9,7 @@ import (
var cmd_tag Command = Command{
Definition: discordgo.ApplicationCommand{
Name: "tag",
DefaultMemberPermissions: int64Ptr(discordgo.PermissionManageServer),
DefaultMemberPermissions: int64Ptr(discordgo.PermissionManageMessages),
Description: "A command to show and edit saved presaved messages.",
Options: []*discordgo.ApplicationCommandOption{
{
@@ -50,7 +50,7 @@ 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{
Type: discordgo.InteractionResponseModal,
@@ -88,7 +88,7 @@ var cmd_tag Command = Command{
})
case "remove":
removeTag(i.GuildID, i.ApplicationCommandData().Options[0].Options[0].StringValue())
respond(s, i.Interaction, "Tag removed!", true)
respond(i.Interaction, "Tag removed!", true)
}
},
ModalIDs: []string{"tag_add_modal"},
@@ -96,10 +96,10 @@ 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(s, i.Interaction, "Tag \""+tagName+"\" added!", true)
respond(i.Interaction, "Tag \""+tagName+"\" added!", true)
},
Autocomplete: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
AutocompleteTag(s, i)
AutocompleteTag(i)
},
}
@@ -118,19 +118,19 @@ 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(s, i.Interaction, getTagContent(i.GuildID, option.Value.(string)), false)
func GetTagCommand(i *discordgo.InteractionCreate, option *discordgo.ApplicationCommandInteractionDataOption) {
respond(i.Interaction, getTagContent(i.GuildID, option.Value.(string)), false)
}
func AutocompleteTag(s *discordgo.Session, i *discordgo.InteractionCreate) {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
func AutocompleteTag(i *discordgo.InteractionCreate) {
bot.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionApplicationCommandAutocompleteResult,
Data: &discordgo.InteractionResponseData{
Choices: generateTagChoices(i.GuildID),

View File

@@ -12,7 +12,7 @@
{
"label": "Ticket information",
"is_paragraph": true,
"placeholder": "Fill in what you need or have issues with and a moderator will reply.",
"placeholder": "Fill in for what you need help or have issues with and a moderator will reply.",
"required": true,
"max_length": 2000
}

View File

@@ -11,13 +11,15 @@ import (
)
type Command struct {
Definition discordgo.ApplicationCommand
Interact func(s *discordgo.Session, i *discordgo.InteractionCreate)
ComponentInteract func(s *discordgo.Session, i *discordgo.InteractionCreate)
ComponentIDs []string
Autocomplete func(s *discordgo.Session, i *discordgo.InteractionCreate)
ModalSubmit func(s *discordgo.Session, i *discordgo.InteractionCreate)
ModalIDs []string
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)
ComponentIDs []string
ModalIDs []string
DynamicComponentIDs func() []string
DynamicModalIDs func() []string
}
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}
@@ -61,15 +63,21 @@ func interactionCreate(s *discordgo.Session, i *discordgo.InteractionCreate) {
command.Autocomplete(s, i)
}
case discordgo.InteractionModalSubmit:
var hasID bool = false
if command.ModalSubmit != nil {
for _, modalID := range command.ModalIDs {
if strings.HasPrefix(i.ModalSubmitData().CustomID, modalID) {
hasID = true
}
// FIXME: Makes it dynamic i don't know why it isn't otherwise
if command.Definition.Name == "form" {
command.ModalIDs = getFormButtonIDs()
}
if hasID {
command.ModalSubmit(s, i)
var hasID bool = false
if command.ModalSubmit != nil {
for _, modalID := range command.ModalIDs {
if strings.HasPrefix(i.ModalSubmitData().CustomID, modalID) {
hasID = true
}
}
if hasID {
command.ModalSubmit(s, i)
}
}
}
case discordgo.InteractionMessageComponent:

19
main.go
View File

@@ -18,6 +18,7 @@ import (
//TODO: add more error handlings
var db *sql.DB
var bot *discordgo.Session
func main() {
godotenv.Load()
@@ -29,27 +30,27 @@ func main() {
log.Fatal(err)
}
initTables()
discord, err := discordgo.New("Bot " + os.Getenv("BOT_TOKEN"))
bot, err = discordgo.New("Bot " + os.Getenv("BOT_TOKEN"))
if err != nil {
fmt.Println("error creating Discord session,", err)
return
} else {
fmt.Println("Discord session created")
}
discord.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentsGuilds | discordgo.IntentMessageContent | discordgo.IntentGuildMembers
discord.AddHandler(ready)
discord.AddHandler(interactionCreate)
discord.AddHandler(messageCreate)
discord.AddHandler(guildMemberJoin)
err = discord.Open()
bot.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentsGuilds | discordgo.IntentMessageContent | discordgo.IntentGuildMembers
bot.AddHandler(ready)
bot.AddHandler(interactionCreate)
bot.AddHandler(messageCreate)
bot.AddHandler(guildMemberJoin)
err = bot.Open()
if err != nil {
fmt.Println("error opening connection,", err)
return
}
fmt.Printf("\nBot is now running as \"%s\"!", discord.State.User.Username)
fmt.Printf("\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...")
discord.Close()
bot.Close()
}

72
tool.go
View File

@@ -2,6 +2,9 @@ package main
import (
"encoding/json"
"fmt"
"log"
"os"
"strconv"
"strings"
@@ -23,17 +26,66 @@ type ModalJson struct {
Form []ModalJsonField `json:"form"`
}
func jsonStringShowModal(jsonString string, id string) {
var modal ModalJson
json.Unmarshal([]byte(jsonString), &modal)
func jsonStringShowModal(interaction *discordgo.Interaction, manageID string, formID string) {
var modal ModalJson = getModalByFormID(formID)
var components []discordgo.MessageComponent
for index, component := range modal.Form {
var style discordgo.TextInputStyle = discordgo.TextInputShort
if component.IsParagraph {
style = discordgo.TextInputParagraph
}
components = append(components, discordgo.ActionsRow{
Components: []discordgo.MessageComponent{
discordgo.TextInput{
CustomID: fmt.Sprint(index),
Label: component.Label,
Style: style,
Required: component.Required,
MaxLength: component.MaxLength,
MinLength: component.MinLength,
Value: component.Value,
},
},
})
}
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)
}
}
func getHighestRole(s *discordgo.Session, guildID string) (*discordgo.Role, error) {
botMember, err := s.GuildMember(guildID, s.State.User.ID)
func getModalByFormID(formID string) ModalJson {
var modal ModalJson
//TODO: add custom forms
entries, err := os.ReadDir("./form_templates")
if err != nil {
log.Print(err)
}
for _, entry := range entries {
if strings.HasPrefix(entry.Name(), formID) {
json_file, err := os.ReadFile("./form_templates/" + entry.Name())
if err != nil {
log.Print(err)
}
json.Unmarshal(json_file, &modal)
}
}
return modal
}
func getHighestRole(guildID string) (*discordgo.Role, error) {
botMember, err := bot.GuildMember(guildID, bot.State.User.ID)
if err != nil {
return nil, err
}
roles, err := s.GuildRoles(guildID)
roles, err := bot.GuildRoles(guildID)
if err != nil {
return nil, err
}
@@ -66,12 +118,12 @@ func hexToDecimal(hexColor string) int {
return int(decimal)
}
func respond(s *discordgo.Session, interaction *discordgo.Interaction, content string, ephemeral bool) {
func respond(interaction *discordgo.Interaction, content string, ephemeral bool) {
var flag discordgo.MessageFlags
if ephemeral {
flag = discordgo.MessageFlagsEphemeral
}
s.InteractionRespond(interaction, &discordgo.InteractionResponse{
bot.InteractionRespond(interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: content,
@@ -80,12 +132,12 @@ func respond(s *discordgo.Session, interaction *discordgo.Interaction, content s
})
}
func respondEmbed(s *discordgo.Session, interaction *discordgo.Interaction, embed discordgo.MessageEmbed, ephemeral bool) {
func respondEmbed(interaction *discordgo.Interaction, embed discordgo.MessageEmbed, ephemeral bool) {
var flag discordgo.MessageFlags
if ephemeral {
flag = discordgo.MessageFlagsEphemeral
}
s.InteractionRespond(interaction, &discordgo.InteractionResponse{
bot.InteractionRespond(interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Flags: flag,