forked from pothtonswer/discordmuffin
Slash commands example: parse options into a map (#1129)
* implement code resolutions removes parseMap from the API and requires user inclusion * optimize map initialization * add note for parseOptionsToMap capacity * feat(examples/slash_commands): removed parseOptionsToMap * feat(examples/slash_commands): cosmetic changes * fix(examples/slash_commands): typo * fix(examples/slash_commands): another typo Co-authored-by: nitroflap <fe.lap.prog@gmail.com>
This commit is contained in:
parent
7e3d187823
commit
0c27cedbcb
1 changed files with 65 additions and 41 deletions
|
@ -158,14 +158,14 @@ var (
|
||||||
// will cause the registration of the command to fail
|
// will cause the registration of the command to fail
|
||||||
|
|
||||||
{
|
{
|
||||||
Name: "scmd-grp",
|
Name: "subcommand-group",
|
||||||
Description: "Subcommands group",
|
Description: "Subcommands group",
|
||||||
Options: []*discordgo.ApplicationCommandOption{
|
Options: []*discordgo.ApplicationCommandOption{
|
||||||
// Also, subcommand groups aren't capable of
|
// Also, subcommand groups aren't capable of
|
||||||
// containing options, by the name of them, you can see
|
// containing options, by the name of them, you can see
|
||||||
// they can only contain subcommands
|
// they can only contain subcommands
|
||||||
{
|
{
|
||||||
Name: "nst-subcmd",
|
Name: "nested-subcommand",
|
||||||
Description: "Nested subcommand",
|
Description: "Nested subcommand",
|
||||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||||
},
|
},
|
||||||
|
@ -178,7 +178,7 @@ var (
|
||||||
// Read the intro of slash-commands docs on Discord dev portal
|
// Read the intro of slash-commands docs on Discord dev portal
|
||||||
// to get more information
|
// to get more information
|
||||||
{
|
{
|
||||||
Name: "subcmd",
|
Name: "subcommand",
|
||||||
Description: "Top-level subcommand",
|
Description: "Top-level subcommand",
|
||||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||||
},
|
},
|
||||||
|
@ -211,6 +211,7 @@ var (
|
||||||
Description: "Followup messages",
|
Description: "Followup messages",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
commandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
|
commandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
|
||||||
"basic-command": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
"basic-command": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||||
|
@ -254,37 +255,62 @@ var (
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"options": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
"options": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
margs := []interface{}{
|
// Access options in the order provided by the user.
|
||||||
// Here we need to convert raw interface{} value to wanted type.
|
options := i.ApplicationCommandData().Options
|
||||||
// Also, as you can see, here is used utility functions to convert the value
|
|
||||||
// to particular type. Yeah, you can use just switch type,
|
// Or convert the slice into a map
|
||||||
// but this is much simpler
|
optionMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(options))
|
||||||
i.ApplicationCommandData().Options[0].StringValue(),
|
for _, opt := range options {
|
||||||
i.ApplicationCommandData().Options[1].IntValue(),
|
optionMap[opt.Name] = opt
|
||||||
i.ApplicationCommandData().Options[2].FloatValue(),
|
|
||||||
i.ApplicationCommandData().Options[3].BoolValue(),
|
|
||||||
}
|
}
|
||||||
msgformat :=
|
|
||||||
` Now you just learned how to use command options. Take a look to the value of which you've just entered:
|
// This example stores the provided arguments in an []interface{}
|
||||||
> string_option: %s
|
// which will be used to format the bot's response
|
||||||
> integer_option: %d
|
margs := make([]interface{}, 0, len(options))
|
||||||
> number_option: %f
|
msgformat := "You learned how to use command options! " +
|
||||||
> bool_option: %v
|
"Take a look at the value(s) you entered:\n"
|
||||||
`
|
|
||||||
if len(i.ApplicationCommandData().Options) >= 5 {
|
// Get the value from the option map.
|
||||||
margs = append(margs, i.ApplicationCommandData().Options[4].ChannelValue(nil).ID)
|
// When the option exists, ok = true
|
||||||
|
if option, ok := optionMap["string-option"]; ok {
|
||||||
|
// Option values must be type asserted from interface{}.
|
||||||
|
// Discordgo provides utility functions to make this simple.
|
||||||
|
margs = append(margs, option.StringValue())
|
||||||
|
msgformat += "> string-option: %s\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt, ok := optionMap["integer-option"]; ok {
|
||||||
|
margs = append(margs, opt.IntValue())
|
||||||
|
msgformat += "> integer-option: %d\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt, ok := optionMap["number-option"]; ok {
|
||||||
|
margs = append(margs, opt.FloatValue())
|
||||||
|
msgformat += "> number-option: %f\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt, ok := optionMap["bool-option"]; ok {
|
||||||
|
margs = append(margs, opt.BoolValue())
|
||||||
|
msgformat += "> bool-option: %v\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt, ok := optionMap["channel-option"]; ok {
|
||||||
|
margs = append(margs, opt.ChannelValue(nil).ID)
|
||||||
msgformat += "> channel-option: <#%s>\n"
|
msgformat += "> channel-option: <#%s>\n"
|
||||||
}
|
}
|
||||||
if len(i.ApplicationCommandData().Options) >= 6 {
|
|
||||||
margs = append(margs, i.ApplicationCommandData().Options[5].UserValue(nil).ID)
|
if opt, ok := optionMap["user-option"]; ok {
|
||||||
|
margs = append(margs, opt.UserValue(nil).ID)
|
||||||
msgformat += "> user-option: <@%s>\n"
|
msgformat += "> user-option: <@%s>\n"
|
||||||
}
|
}
|
||||||
if len(i.ApplicationCommandData().Options) >= 7 {
|
|
||||||
margs = append(margs, i.ApplicationCommandData().Options[6].RoleValue(nil, "").ID)
|
if opt, ok := optionMap["role-option"]; ok {
|
||||||
|
margs = append(margs, opt.RoleValue(nil, "").ID)
|
||||||
msgformat += "> role-option: <@&%s>\n"
|
msgformat += "> role-option: <@&%s>\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||||
// Ignore type for now, we'll discuss them in "responses" part
|
// Ignore type for now, they will be discussed in "responses"
|
||||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||||
Data: &discordgo.InteractionResponseData{
|
Data: &discordgo.InteractionResponseData{
|
||||||
Content: fmt.Sprintf(
|
Content: fmt.Sprintf(
|
||||||
|
@ -295,27 +321,25 @@ var (
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
"subcommands": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
"subcommands": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
|
options := i.ApplicationCommandData().Options
|
||||||
content := ""
|
content := ""
|
||||||
|
|
||||||
// As you can see, the name of subcommand (nested, top-level) or subcommand group
|
// As you can see, names of subcommands (nested, top-level)
|
||||||
// is provided through arguments.
|
// and subcommand groups are provided through the arguments.
|
||||||
switch i.ApplicationCommandData().Options[0].Name {
|
switch options[0].Name {
|
||||||
case "subcmd":
|
case "subcommand":
|
||||||
content =
|
content = "The top-level subcommand is executed. Now try to execute the nested one."
|
||||||
"The top-level subcommand is executed. Now try to execute the nested one."
|
case "subcommand-group":
|
||||||
default:
|
options = options[0].Options
|
||||||
if i.ApplicationCommandData().Options[0].Name != "scmd-grp" {
|
switch options[0].Name {
|
||||||
return
|
case "nested-subcommand":
|
||||||
}
|
|
||||||
switch i.ApplicationCommandData().Options[0].Options[0].Name {
|
|
||||||
case "nst-subcmd":
|
|
||||||
content = "Nice, now you know how to execute nested commands too"
|
content = "Nice, now you know how to execute nested commands too"
|
||||||
default:
|
default:
|
||||||
// I added this in the case something might go wrong
|
content = "Oops, something went wrong.\n" +
|
||||||
content = "Oops, something gone wrong.\n" +
|
|
||||||
"Hol' up, you aren't supposed to see this message."
|
"Hol' up, you aren't supposed to see this message."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||||
Data: &discordgo.InteractionResponseData{
|
Data: &discordgo.InteractionResponseData{
|
||||||
|
@ -476,5 +500,5 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Gracefully shutdowning")
|
log.Println("Gracefully shutting down.")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue