diff --git a/Bot/Commands/reactionrole.go b/Bot/Commands/reactionrole.go index 50ebb41..d3cc212 100644 --- a/Bot/Commands/reactionrole.go +++ b/Bot/Commands/reactionrole.go @@ -3,7 +3,6 @@ package commands import ( "encoding/json" "fmt" - "log" "os" "strings" @@ -55,21 +54,43 @@ func manageRolesPerm() *int64 { // Only members with the "Manage Roles" permission may use this command. var ReactionRoleCommand = &discordgo.ApplicationCommand{ Name: "reactionrole", - Description: "Setup a reaction role message using buttons. Provide a number (max 10) for role-button pairs", + Description: "Setup a reaction role message using buttons. Provide up to 5 roles.", DefaultMemberPermissions: manageRolesPerm(), Options: []*discordgo.ApplicationCommandOption{ { - Type: discordgo.ApplicationCommandOptionInteger, - Name: "count", - Description: "Number of role-button pairs to setup (max 10)", + Type: discordgo.ApplicationCommandOptionRole, // type 8 + Name: "role1", + Description: "The first role", Required: true, - MinValue: func(v float64) *float64 { return &v }(1), - MaxValue: func(v float64) float64 { return v }(10), + }, + { + Type: discordgo.ApplicationCommandOptionRole, + Name: "role2", + Description: "The second role", + Required: false, + }, + { + Type: discordgo.ApplicationCommandOptionRole, + Name: "role3", + Description: "The third role", + Required: false, + }, + { + Type: discordgo.ApplicationCommandOptionRole, + Name: "role4", + Description: "The fourth role", + Required: false, + }, + { + Type: discordgo.ApplicationCommandOptionRole, + Name: "role5", + Description: "The fifth role", + Required: false, }, { Type: discordgo.ApplicationCommandOptionString, Name: "style", - Description: "Button style", + Description: "Button style (primary, secondary, success, danger)", Required: false, Choices: []*discordgo.ApplicationCommandOptionChoice{ { @@ -144,7 +165,7 @@ func memberHasManageRoles(s *discordgo.Session, guildID string, member *discordg } func HandleReactionRole(s *discordgo.Session, i *discordgo.InteractionCreate) { - // Ensure the command is used in a guild and member data is present. + // Standard guild and permission checks. if i.GuildID == "" || i.Member == nil { helpers.HandleError(s, i, fmt.Errorf("command must be used in a guild")) return @@ -154,7 +175,6 @@ func HandleReactionRole(s *discordgo.Session, i *discordgo.InteractionCreate) { helpers.HandleError(s, i, fmt.Errorf("failed to check user permissions: %w", err)) return } - if !hasPerm { s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, @@ -168,54 +188,48 @@ func HandleReactionRole(s *discordgo.Session, i *discordgo.InteractionCreate) { options := i.ApplicationCommandData().Options - // Extract count (required - type Integer) - countOpt := helpers.GetOption(options, "count") - if countOpt == nil { - helpers.HandleError(s, i, fmt.Errorf("missing count option")) - return - } - count := int(countOpt.IntValue()) + // Collect role IDs from the role options. + var roles []*discordgo.Role + for _, optName := range []string{"role1", "role2", "role3", "role4", "role5"} { + if opt := helpers.GetOption(options, optName); opt != nil { + roles = append(roles, opt.RoleValue(s, i.GuildID)) + } + } - // Determine style based on the "style" option; default to "primary" - style := "primary" - if opt := helpers.GetOption(options, "style"); opt != nil { - if val := opt.StringValue(); val != "" { - style = val - } - } + if len(roles) == 0 { + helpers.HandleError(s, i, fmt.Errorf("at least one role must be provided")) + return + } - // Extract target message ID from the "message_id" option if available. - targetMsgID := "" - if opt := helpers.GetOption(options, "message_id"); opt != nil { - if val := opt.StringValue(); val != "" { - targetMsgID = val - // Store the target message ID keyed by the user's ID. - reactionRoleTarget[i.Member.User.ID] = targetMsgID - } - } + // Determine style; default to primary. + style := "primary" + if opt := helpers.GetOption(options, "style"); opt != nil { + if val := opt.StringValue(); val != "" { + style = val + } + } - // Build modal components: for each pair, add two text inputs (each in its own action row). + // Extract target message ID, if provided. + targetMsgID := "" + if opt := helpers.GetOption(options, "message_id"); opt != nil { + if val := opt.StringValue(); val != "" { + targetMsgID = val + // Store the target message ID keyed by the user's ID. + reactionRoleTarget[i.Member.User.ID] = targetMsgID + } + } + + // Build the modal components: one text input per role for its button label. modalComponents := []discordgo.MessageComponent{} - for idx := 1; idx <= count; idx++ { - // Input for Role ID. - roleInput := discordgo.TextInput{ - CustomID: fmt.Sprintf("role_id_%d", idx), - Label: fmt.Sprintf("Role ID for pair %d", idx), - Style: discordgo.TextInputShort, - Placeholder: "Enter Role ID", - Required: true, - } - // Input for Button Label. + for _, role := range roles { labelInput := discordgo.TextInput{ - CustomID: fmt.Sprintf("role_label_%d", idx), - Label: fmt.Sprintf("Button label for pair %d", idx), + CustomID: fmt.Sprintf("label_%s", role.ID), + Label: fmt.Sprintf("Button label for role %s", role.Name), Style: discordgo.TextInputShort, - Placeholder: "Button Text", + Placeholder: "Enter Button Label", Required: true, } - modalComponents = append(modalComponents, discordgo.ActionsRow{ - Components: []discordgo.MessageComponent{&roleInput}, - }) + modalComponents = append(modalComponents, discordgo.ActionsRow{ Components: []discordgo.MessageComponent{&labelInput}, }) @@ -295,26 +309,27 @@ func HandleReactionRoleModalSubmit(s *discordgo.Session, i *discordgo.Interactio } } - // For each pair, extract the Role ID and label. - for idx := 1; idx <= count; idx++ { - var roleID, label string + // FLAT + var rolearr [][]string + + for idx := range count { for _, comp := range data.Components { row, ok := comp.(*discordgo.ActionsRow) + if !ok { continue } - for _, innerComp := range row.Components { - textInput, ok := innerComp.(*discordgo.TextInput) - if !ok { - continue - } - if textInput.CustomID == fmt.Sprintf("role_id_%d", idx) { - roleID = textInput.Value - } else if textInput.CustomID == fmt.Sprintf("role_label_%d", idx) { - label = textInput.Value - } - } + + inp := row.Components[idx].(*discordgo.TextInput) + rolearr = append(rolearr, []string{inp.Value, strings.Split(inp.CustomID, "_")[1]}) } + } + + for idx := range len(rolearr) { + var roleID, label string + + label = rolearr[idx][0] + roleID = rolearr[idx][1] // Allow a cancellation action. if strings.ToLower(roleID) == "cancel" { @@ -391,7 +406,7 @@ func HandleReactionRoleModalSubmit(s *discordgo.Session, i *discordgo.Interactio ID: targetMsgID, Content: &originalMsg.Content, // Preserve original content. Components: &components, - }); + }) if err != nil { helpers.HandleError(s, i, fmt.Errorf("failed to edit target message: %w", err))