This commit is contained in:
2025-04-08 11:55:56 -04:00
parent e003afab6d
commit 14e5187535
+80 -65
View File
@@ -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))