There are two kinds of Slash Commands: global commands and guild commands.
@@ -35,7 +40,10 @@ The slash command builder will help you create slash commands. The builder has t
| AddOption | Function | Adds an option to the current slash command. |
| Build | Function | Builds the builder into a `SlashCommandCreationProperties` class used to make slash commands |
**Note**: Slash command names must be all lowercase!
> [!NOTE]
> Slash command names must be all lowercase!
## Creating a Slash Command
Let's use the slash command builder to make a global and guild command.
@@ -84,4 +92,5 @@ public async Task Client_Ready()
```
**Note**: Slash commands only need to be created once. They do _not_ have to be 'created' on every startup or connection. The example simple shows creating them in the ready event as it's simpler than creating normal bot commands to register slash commands.
> [!NOTE]
> Slash commands only need to be created once. They do _not_ have to be 'created' on every startup or connection. The example simple shows creating them in the ready event as it's simpler than creating normal bot commands to register slash commands.
Interactions are the base thing sent over by Discord. Slash commands are one of the interaction types. In order to receive a slash command we have to listen to the `InteractionCreated` event. Let's add this to our code.
@@ -45,6 +50,8 @@ Let's try this out!
Let's go over the response types quickly, as you would only change them for style points :P
> After receiving an interaction, you must respond to acknowledge it. You can choose to respond with a message immediately using `RespondAsync()` or you can choose to send a deferred response with `DeferAsync()`. If choosing a deferred response, the user will see a loading state for the interaction, and you'll have up to 15 minutes to edit the original deferred response using `ModifyOriginalResponseAsync()`. You can read more about response types [here](https://discord.com/developers/docs/interactions/slash-commands#interaction-response)
> [!NOTE]
> After receiving an interaction, you must respond to acknowledge it. You can choose to respond with a message immediately using `RespondAsync()` or you can choose to send a deferred response with `DeferAsync()`.
> If choosing a deferred response, the user will see a loading state for the interaction, and you'll have up to 15 minutes to edit the original deferred response using `ModifyOriginalResponseAsync()`. You can read more about response types [here](https://discord.com/developers/docs/interactions/slash-commands#interaction-response)
This seems to be working! Next, we will look at parameters for slash commands.
What is an ephemeral response? Basically, only the user who executed the command can see the result of it. In labs this is pretty simple to do.
First, we need to talk about `AlwaysAcknowledgeInteractions` in the discord config. `AlwaysAcknowledgeInteractions` will always acknowledge the message non-ephemerally, meaning any follow-up messages or responses will also be non-ephemeral. If you set `AlwaysAcknowledgeInteractions` to false, you can acknowledge interactions yourself with the ephemeral field set to your discretion.
---
uid: Guides.SlashCommands.Ephemeral
title: Ephemeral Responses
---
**Note**: You don't have to run arg.AcknowledgeAsync() to capture the interaction, you can use arg.RespondAsync with a message to capture it, this also follows the ephemeral rule.
# Responding ephemerally
Let's start by changing our client config.
What is an ephemeral response? Basically, only the user who executed the command can see the result of it, this is pretty simple to implement.
```cs
client = new DiscordSocketClient(new DiscordSocketConfig()
{
// Add this!
AlwaysAcknowledgeInteractions = false,
});
```
**Note**: You don't have to run arg.DeferAsync() to capture the interaction, you can use arg.RespondAsync() with a message to capture it, this also follows the ephemeral rule.
When responding with either `FollowupAsync` or `RespondAsync` you can pass in an `ephemeral` property. When setting it to true it will respond ephemerally, false and it will respond non-ephemerally.
Subcommands allow you to have multiple commands available in a single command. They can be useful for representing sub options for a command. For example: A settings command. Let's first look at some limitations with subcommands set by discord.
With slash command options you can add choices, making the user select between some set values. Lets create a command that asks how much they like our bot!
2. [Creating a slash command](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/Interactions/docs/guides/slash-commands/02-creating-slash-commands.md)
3. [Responding to slash commands](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/Interactions/docs/guides/slash-commands/03-responding-to-slash-commands.md)
4. [Parameters in slash commands](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/Interactions/docs/guides/slash-commands/04-parameters.md)
7. [Bulk overwrite of global slash commands](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/release/3.x/docs/guides/interactions/application-commands/slash-commands/08-bulk-overwrite-of-global-slash-commands.md)
1. [Creating a slash command](https://github.com/discord-net/Discord.Net/blob/dev/docs/guides/interactions/application-commands/slash-commands/02-creating-slash-commands.md)
2. [Responding to slash commands](https://github.com/discord-net/Discord.Net/blob/dev/docs/guides/interactions/application-commands/slash-commands/03-responding-to-slash-commands.md)
3. [Parameters in slash commands](https://github.com/discord-net/Discord.Net/blob/dev/docs/guides/interactions/application-commands/slash-commands/04-parameters.md)
7. [Bulk overwrite of global slash commands](https://github.com/discord-net/Discord.Net/blob/dev/docs/guides/interactions/application-commands/slash-commands/08-bulk-overwrite-of-global-slash-commands.md)
//If we get this far, at least one parse was successful. Execute the most likely overload.
var chosenOverload = successfulParses[0];
var result = await chosenOverload.Key.ExecuteAsync(context, chosenOverload.Value, services).ConfigureAwait(false);
if (!result.IsSuccess && !(result is RuntimeResult || result is ExecuteResult)) // succesful results raise the event in CommandInfo#ExecuteInternalAsync (have to raise it there b/c deffered execution)
if (!result.IsSuccess && !(result is RuntimeResult || result is ExecuteResult)) // successful results raise the event in CommandInfo#ExecuteInternalAsync (have to raise it there b/c deferred execution)
/// <returns>A guild user associated with the specified <paramref name="userId" />; <see langword="null" /> if the user is already in the guild.</returns>
/// <param name="options">The request options for this response.</param>
/// <param name="component">A <see cref="MessageComponent"/> to be sent with this response.</param>
/// <param name="embed">A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.</param>
/// After receiving an interaction, you must respond to acknowledge it. You can choose to respond with a message immediately using <see cref="ChannelMessageWithSource"/>
/// or you can choose to send a deferred response with <see cref="DeferredChannelMessageWithSource"/>. If choosing a deferred response, the user will see a loading state for the interaction,
/// and you'll have up to 15 minutes to edit the original deferred response using Edit Original Interaction Response.
/// You can read more about Response types <see href="https://discord.com/developers/docs/interactions/slash-commands#interaction-response">Here</see>
/// You can read more about Response types <see href="https://discord.com/developers/docs/interactions/slash-commands#interaction-response">Here</see>.
/// </remarks>
public enum InteractionResponseType : byte
{
@@ -22,18 +18,6 @@ namespace Discord
/// </summary>
Pong = 1,
/// <summary>
/// ACK a command without sending a message, eating the user's input.
/// </summary>
[Obsolete("This response type has been depricated by discord. Either use ChannelMessageWithSource or DeferredChannelMessageWithSource", true)]
Acknowledge = 2,
/// <summary>
/// Respond with a message, showing the user's input.
/// </summary>
[Obsolete("This response type has been depricated by discord. Either use ChannelMessageWithSource or DeferredChannelMessageWithSource", true)]
public ComponentType Type { get; } = ComponentType.Button;
public ComponentType Type => ComponentType.Button;
/// <summary>
/// Gets the <see cref="ButtonStyle"/> of this button, example buttons with each style can be found <see href="https://discord.com/assets/7bb017ce52cfd6575e21c058feb3883b.png">Here</see>.
/// A string that contains the body of the message stripped of mentions, markdown, emojis and pings; note that this field may be empty if there is an embed.
/// </returns>
string CleanContent { get; }
/// <summary>
/// Gets the time this message was sent.
/// </summary>
/// <returns>
@@ -187,7 +194,15 @@ namespace Discord
/// A message's flags, if any is associated.
/// </returns>
MessageFlags? Flags { get; }
/// <summary>
/// Gets the interaction this message is a response to.
/// </summary>
/// <returns>
/// A <see cref="IMessageInteraction"/> if the message is a response to an interaction; otherwise <see langword="null"/>.
throw new InvalidOperationException($"The url {url} must include a protocol (either {(allowAttachments ? "HTTP, HTTPS, or ATTACHMENT" : "HTTP or HTTPS")})");
return true;
}
/// <summary>
/// Not full URL validation right now. Just Ensures the protocol is either http, https, or discord
/// <see cref="Validate(string)"/> should be used everything other than url buttons.
/// </summary>
/// <param name="url">The URL to validate before sending to discord.</param>
/// <exception cref="InvalidOperationException">A URL must include a protocol (either http, https, or discord).</exception>
/// <returns>true if the URL is valid by our standard, false if null, throws an error upon invalid.</returns>
public static bool ValidateButton(string url)
{
if (string.IsNullOrEmpty(url))
return false;
if (!(url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
Thank you for your continuous support to the Openl Qizhi Community AI Collaboration Platform. In order to protect your usage rights and ensure network security, we updated the Openl Qizhi Community AI Collaboration Platform Usage Agreement in January 2024. The updated agreement specifies that users are prohibited from using intranet penetration tools. After you click "Agree and continue", you can continue to use our services. Thank you for your cooperation and understanding.