From 7d6224b558cbb364318b03d5a52c6db67116099a Mon Sep 17 00:00:00 2001 From: MrCakeSlayer <13650699+MrCakeSlayer@users.noreply.github.com> Date: Tue, 6 Jul 2021 08:51:05 -0400 Subject: [PATCH 1/2] Update examples --- README.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 981108982..f7671aca6 100644 --- a/README.md +++ b/README.md @@ -26,11 +26,7 @@ This branch is on pause and does not work currently, Once everything is stable w ### web/SlashCommandService webmilio's spin on the SlashCommandService branch, again the state of this is unknown. - -## Message Components -So, you want to use Message components? Well you're in luck! Below is a quick overview of how to use them - -#### Listening for button presses +## Listening for interactions ```cs // Subscribe to the InteractionCreated event client.InteractionCreated += Client_InteractionCreated; @@ -38,23 +34,80 @@ client.InteractionCreated += Client_InteractionCreated; ... private async Task Client_InteractionCreated(SocketInteraction arg) { - // If the type of the interaction is a message component - if(arg.Type == Discord.InteractionType.MessageComponent) + switch (arg.Type) // We want to check the type of this interaction { - // parse the args - var parsedArg = (SocketMessageComponent)arg; - // respond with the update message response type. This edits the original message if you have set AlwaysAcknowledgeInteractions to false. - await parsedArg.RespondAsync($"Clicked {parsedArg.Data.CustomId}!", type: InteractionResponseType.UpdateMessage); + //Slash commands + case InteractionType.ApplicationCommand: + await MySlashCommandHandler(arg); + break; + //Button clicks/selection dropdowns + case InteractionType.MessageComponent: + await MyMessageComponentHandler(arg); + break; + //Unused + case InteractionType.Ping: + break; + //Unknown/Unsupported + default: + Console.WriteLine("Unsupported interaction type: " + arg.Type); + break; } } ``` -#### Sending messages with buttons +### Handling button clicks and selection dropdowns +```cs +private async Task MyMessageComponentHandler(SocketInteraction arg) +{ + // Parse the arg + var parsedArg = (SocketMessageComponent) arg; + // Get the custom ID + var customId = parsedArg.Data.CustomId; + // Get the user + var user = (SocketGuildUser) arg.User; + // Get the guild + var guild = user.Guild; + + // Respond with the update message response type. This edits the original message if you have set AlwaysAcknowledgeInteractions to false. + // You can also use "ephemeral" so that only the original user of the interaction sees the message + await parsedArg.RespondAsync($"Clicked {parsedArg.Data.CustomId}!", type: InteractionResponseType.UpdateMessage, ephemeral: true); + + // You can also followup with a second message + await parsedArg.FollowupAsync($"Clicked {parsedArg.Data.CustomId}!", type: InteractionResponseType.ChannelMessageWithSource, ephemeral: true); +} +``` + +### Sending messages with buttons Theres a new field in all `SendMessageAsync` functions that takes in a `MessageComponent`, you can use it like so: ```cs -var builder = new ComponentBuilder().WithButton("Hello!", ButtonStyle.Primary, customId: "id_1"); +var builder = new ComponentBuilder().WithButton("Hello!", customId: "id_1", ButtonStyle.Primary, row: 0); await Context.Channel.SendMessageAsync("Test buttons!", component: builder.Build()); ``` +### Sending messages with selection dropdowns +Theres a new field in all `SendMessageAsync` functions that takes in a `MessageComponent`, you can use it like so: +```cs +var builder = new ComponentBuilder() + .WithSelectMenu(new SelectMenuBuilder() + .WithCustomId("id_2") + .WithLabel("Select menu!") + .WithPlaceholder("This is a placeholder") + .WithOptions(new List() + { + new SelectMenuOptionBuilder() + .WithLabel("Option A") + .WithEmote(Emote.Parse("<:evanpog:810017136814194698>")) + .WithDescription("Evan pog champ") + .WithValue("value1"), + new SelectMenuOptionBuilder() + .WithLabel("Option B") + .WithDescription("Option B is poggers") + .WithValue("value2") + })); +await Context.Channel.SendMessageAsync("Test selection!", component: builder.Build()); +``` + +> Note: You can only have 5 buttons per row and 5 rows per message. If a row contains a selection dropdown it cannot contain any buttons. + ## Slash commands Slash command example how to's can be found [here](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/Interactions/docs/guides/commands/application-commands.md). If you want to read some code using slash commands, you can do that [here](https://github.com/quinchs/SwissbotCore/blob/master/SwissbotCore/Handlers/AutoMod/Censor.cs) From 5e31eb12a693df53f6e40e98c6580257accf56b7 Mon Sep 17 00:00:00 2001 From: MrCakeSlayer <13650699+MrCakeSlayer@users.noreply.github.com> Date: Tue, 6 Jul 2021 09:00:17 -0400 Subject: [PATCH 2/2] Include addition vars for selection dropdowns --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index f7671aca6..f99f3ec4a 100644 --- a/README.md +++ b/README.md @@ -74,9 +74,15 @@ private async Task MyMessageComponentHandler(SocketInteraction arg) // You can also followup with a second message await parsedArg.FollowupAsync($"Clicked {parsedArg.Data.CustomId}!", type: InteractionResponseType.ChannelMessageWithSource, ephemeral: true); + + //If you are using selection dropdowns, you can get the selected label and values using these: + var selectedLabel = ((SelectMenu) parsedArg.Message.Components.First().Components.First()).Options.FirstOrDefault(x => x.Value == parsedArg.Data.Values.FirstOrDefault())?.Label; + var selectedValue = parsedArg.Data.Values.First(); } ``` +> Note: The example above assumes that the selection dropdown is expecting only 1 returned value, if you configured your dropdown for multiple values, you'll need to modify the code slightly. + ### Sending messages with buttons Theres a new field in all `SendMessageAsync` functions that takes in a `MessageComponent`, you can use it like so: ```cs