Browse Source

Squashed commit of the following:

commit dca41a348e
Author: quin lynch <lynchquin@gmail.com>
Date:   Thu Sep 23 07:02:19 2021 -0300

    Autocomplete commands
pull/1923/head
quin lynch 3 years ago
parent
commit
016c1dc80a
20 changed files with 681 additions and 57 deletions
  1. +1
    -1
      src/Discord.Net.Core/Discord.Net.Core.csproj
  2. +131
    -23
      src/Discord.Net.Core/Discord.Net.Core.xml
  3. +11
    -7
      src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs
  4. +42
    -0
      src/Discord.Net.Core/Entities/Interactions/AutocompleteOption.cs
  5. +90
    -0
      src/Discord.Net.Core/Entities/Interactions/AutocompleteResult.cs
  6. +8
    -3
      src/Discord.Net.Core/Entities/Interactions/InteractionResponseType.cs
  7. +5
    -0
      src/Discord.Net.Core/Entities/Interactions/InteractionType.cs
  8. +16
    -9
      src/Discord.Net.Core/Entities/Interactions/Slash Commands/SlashCommandBuilder.cs
  9. +0
    -0
      src/Discord.Net.Core/Entities/Interactions/Slash Commands/SlashCommandProperties.cs
  10. +4
    -0
      src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs
  11. +27
    -0
      src/Discord.Net.Rest/API/Common/AutocompleteInteractionData.cs
  12. +24
    -0
      src/Discord.Net.Rest/API/Common/AutocompleteInteractionDataOption.cs
  13. +3
    -0
      src/Discord.Net.Rest/API/Common/InteractionCallbackData.cs
  14. +22
    -0
      src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
  15. +7
    -0
      src/Discord.Net.Rest/Net/Converters/InteractionConverter.cs
  16. +103
    -1
      src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml
  17. +97
    -0
      src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketAutocompleteInteraction.cs
  18. +60
    -0
      src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketAutocompleteInteractionData.cs
  19. +13
    -1
      src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs
  20. +17
    -12
      src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs

+ 1
- 1
src/Discord.Net.Core/Discord.Net.Core.csproj View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../Discord.Net.targets" /> <Import Project="../../Discord.Net.targets" />
<Import Project="../../StyleAnalyzer.targets" /> <Import Project="../../StyleAnalyzer.targets" />
<PropertyGroup> <PropertyGroup>


+ 131
- 23
src/Discord.Net.Core/Discord.Net.Core.xml View File

@@ -4508,37 +4508,42 @@
</member> </member>
<member name="P:Discord.ApplicationCommandOptionProperties.Name"> <member name="P:Discord.ApplicationCommandOptionProperties.Name">
<summary> <summary>
The name of this option.
Gets or sets the name of this option.
</summary> </summary>
</member> </member>
<member name="P:Discord.ApplicationCommandOptionProperties.Description"> <member name="P:Discord.ApplicationCommandOptionProperties.Description">
<summary> <summary>
The description of this option.
Gets or sets the description of this option.
</summary> </summary>
</member> </member>
<member name="P:Discord.ApplicationCommandOptionProperties.Type"> <member name="P:Discord.ApplicationCommandOptionProperties.Type">
<summary> <summary>
The type of this option.
Gets or sets the type of this option.
</summary> </summary>
</member> </member>
<member name="P:Discord.ApplicationCommandOptionProperties.Default"> <member name="P:Discord.ApplicationCommandOptionProperties.Default">
<summary> <summary>
The first required option for the user to complete. only one option can be default.
Gets or sets whether or not this options is the first required option for the user to complete. only one option can be default.
</summary> </summary>
</member> </member>
<member name="P:Discord.ApplicationCommandOptionProperties.Required"> <member name="P:Discord.ApplicationCommandOptionProperties.Required">
<summary> <summary>
<see langword="true"/> if this option is required for this command, otherwise <see langword="false"/>.
Gets or sets if the option is required.
</summary>
</member>
<member name="P:Discord.ApplicationCommandOptionProperties.Autocomplete">
<summary>
Gets or sets whether or not this option supports autocomplete
</summary> </summary>
</member> </member>
<member name="P:Discord.ApplicationCommandOptionProperties.Choices"> <member name="P:Discord.ApplicationCommandOptionProperties.Choices">
<summary> <summary>
choices for string and int types for the user to pick from.
Gets or sets the choices for string and int types for the user to pick from.
</summary> </summary>
</member> </member>
<member name="P:Discord.ApplicationCommandOptionProperties.Options"> <member name="P:Discord.ApplicationCommandOptionProperties.Options">
<summary> <summary>
If the option is a subcommand or subcommand group type, this nested options will be the parameters.
Gets or sets if this option is a subcommand or subcommand group type, these nested options will be the parameters.
</summary> </summary>
</member> </member>
<member name="T:Discord.ApplicationCommandOptionChoiceProperties"> <member name="T:Discord.ApplicationCommandOptionChoiceProperties">
@@ -4649,6 +4654,68 @@
ApplicationCommandType.Message is Context Menu Message command type ApplicationCommandType.Message is Context Menu Message command type
</summary> </summary>
</member> </member>
<member name="T:Discord.AutocompleteOption">
<summary>
Represents an autocomplete option.
</summary>
</member>
<member name="P:Discord.AutocompleteOption.Type">
<summary>
Gets the type of this option
</summary>
</member>
<member name="P:Discord.AutocompleteOption.Name">
<summary>
Gets the name of the option.
</summary>
</member>
<member name="P:Discord.AutocompleteOption.Value">
<summary>
Gets the value of the option.
</summary>
</member>
<member name="P:Discord.AutocompleteOption.Focused">
<summary>
Gets whether or not this option is focused by the executing user.
</summary>
</member>
<member name="T:Discord.AutocompleteResult">
<summary>
Represents a result to an autocomplete interaction.
</summary>
</member>
<member name="P:Discord.AutocompleteResult.Name">
<summary>
Gets or sets the name of the result.
</summary>
<remarks>
Name cannot be null and has to be between 1-100 characters in length.
</remarks>
<exception cref="T:System.ArgumentNullException"/>
<exception cref="T:System.ArgumentException"/>
</member>
<member name="P:Discord.AutocompleteResult.Value">
<summary>
Gets or sets the value of the result.
</summary>
<remarks>
Only <see cref="T:System.String"/>, <see cref="T:System.Int32"/>, and <see cref="T:System.Double"/> are allowed for a value.
</remarks>
<exception cref="T:System.ArgumentNullException"/>
<exception cref="T:System.ArgumentException"/>
</member>
<member name="M:Discord.AutocompleteResult.#ctor">
<summary>
Creates a new <see cref="T:Discord.AutocompleteResult"/>.
</summary>
</member>
<member name="M:Discord.AutocompleteResult.#ctor(System.String,System.Object)">
<summary>
Creates a new <see cref="T:Discord.AutocompleteResult"/> with the passed in <paramref name="name"/> and <paramref name="value"/>.
</summary>
<exception cref="T:System.ArgumentNullException"/>
<exception cref="T:System.ArgumentException"/>
</member>
<member name="T:Discord.MessageCommandBuilder"> <member name="T:Discord.MessageCommandBuilder">
<summary> <summary>
A class used to build Message commands. A class used to build Message commands.
@@ -5029,12 +5096,17 @@
</member> </member>
<member name="F:Discord.InteractionResponseType.DeferredUpdateMessage"> <member name="F:Discord.InteractionResponseType.DeferredUpdateMessage">
<summary> <summary>
for components: ACK an interaction and edit the original message later; the user does not see a loading state
For components: ACK an interaction and edit the original message later; the user does not see a loading state
</summary> </summary>
</member> </member>
<member name="F:Discord.InteractionResponseType.UpdateMessage"> <member name="F:Discord.InteractionResponseType.UpdateMessage">
<summary> <summary>
for components: edit the message the component was attached to
For components: edit the message the component was attached to
</summary>
</member>
<member name="F:Discord.InteractionResponseType.ApplicationCommandAutocompleteResult">
<summary>
Respond with a set of choices to a autocomplete interaction
</summary> </summary>
</member> </member>
<member name="T:Discord.InteractionType"> <member name="T:Discord.InteractionType">
@@ -5057,6 +5129,11 @@
A <see cref="T:Discord.IMessageComponent"/> sent from discord. A <see cref="T:Discord.IMessageComponent"/> sent from discord.
</summary> </summary>
</member> </member>
<member name="F:Discord.InteractionType.ApplicationCommandAutocomplete">
<summary>
An autocomplete request sent from discord.
</summary>
</member>
<member name="T:Discord.ActionRowComponent"> <member name="T:Discord.ActionRowComponent">
<summary> <summary>
Represents a <see cref="T:Discord.IMessageComponent"/> Row for child components to live in. Represents a <see cref="T:Discord.IMessageComponent"/> Row for child components to live in.
@@ -5934,7 +6011,7 @@
<param name="value">The default permission value to set.</param> <param name="value">The default permission value to set.</param>
<returns>The current builder.</returns> <returns>The current builder.</returns>
</member> </member>
<member name="M:Discord.SlashCommandBuilder.AddOption(System.String,Discord.ApplicationCommandOptionType,System.String,System.Boolean,System.Boolean,System.Collections.Generic.List{Discord.SlashCommandOptionBuilder},Discord.ApplicationCommandOptionChoiceProperties[])">
<member name="M:Discord.SlashCommandBuilder.AddOption(System.String,Discord.ApplicationCommandOptionType,System.String,System.Boolean,System.Boolean,System.Boolean,System.Collections.Generic.List{Discord.SlashCommandOptionBuilder},Discord.ApplicationCommandOptionChoiceProperties[])">
<summary> <summary>
Adds an option to the current slash command. Adds an option to the current slash command.
</summary> </summary>
@@ -5987,37 +6064,42 @@
</member> </member>
<member name="P:Discord.SlashCommandOptionBuilder.Name"> <member name="P:Discord.SlashCommandOptionBuilder.Name">
<summary> <summary>
The name of this option.
Gets or sets the name of this option.
</summary> </summary>
</member> </member>
<member name="P:Discord.SlashCommandOptionBuilder.Description"> <member name="P:Discord.SlashCommandOptionBuilder.Description">
<summary> <summary>
The description of this option.
Gets or sets the description of this option.
</summary> </summary>
</member> </member>
<member name="P:Discord.SlashCommandOptionBuilder.Type"> <member name="P:Discord.SlashCommandOptionBuilder.Type">
<summary> <summary>
The type of this option.
Gets or sets the type of this option.
</summary> </summary>
</member> </member>
<member name="P:Discord.SlashCommandOptionBuilder.Default"> <member name="P:Discord.SlashCommandOptionBuilder.Default">
<summary> <summary>
The first required option for the user to complete. only one option can be default.
Gets or sets whether or not this options is the first required option for the user to complete. only one option can be default.
</summary> </summary>
</member> </member>
<member name="P:Discord.SlashCommandOptionBuilder.Required"> <member name="P:Discord.SlashCommandOptionBuilder.Required">
<summary> <summary>
<see langword="true"/> if this option is required for this command, otherwise <see langword="false"/>.
Gets or sets if the option is required.
</summary>
</member>
<member name="P:Discord.SlashCommandOptionBuilder.Autocomplete">
<summary>
Gets or sets whether or not this option supports autocomplete.
</summary> </summary>
</member> </member>
<member name="P:Discord.SlashCommandOptionBuilder.Choices"> <member name="P:Discord.SlashCommandOptionBuilder.Choices">
<summary> <summary>
choices for string and int types for the user to pick from.
Gets or sets the choices for string and int types for the user to pick from.
</summary> </summary>
</member> </member>
<member name="P:Discord.SlashCommandOptionBuilder.Options"> <member name="P:Discord.SlashCommandOptionBuilder.Options">
<summary> <summary>
If the option is a subcommand or subcommand group type, this nested options will be the parameters.
Gets or sets if this option is a subcommand or subcommand group type, these nested options will be the parameters.
</summary> </summary>
</member> </member>
<member name="M:Discord.SlashCommandOptionBuilder.Build"> <member name="M:Discord.SlashCommandOptionBuilder.Build">
@@ -8876,14 +8958,24 @@
authentication when used on a guild that has server-wide 2FA enabled. authentication when used on a guild that has server-wide 2FA enabled.
</remarks> </remarks>
</member> </member>
<member name="F:Discord.GuildPermission.CreatePublicThreads">
<summary>
Allows for creating public threads.
</summary>
</member>
<member name="F:Discord.GuildPermission.CreatePrivateThreads">
<summary>
Allows for creating private threads.
</summary>
</member>
<member name="F:Discord.GuildPermission.UsePublicThreads"> <member name="F:Discord.GuildPermission.UsePublicThreads">
<summary> <summary>
Allows for creating and participating in threads.
Allows for creating public threads.
</summary> </summary>
</member> </member>
<member name="F:Discord.GuildPermission.UsePrivateThreads"> <member name="F:Discord.GuildPermission.UsePrivateThreads">
<summary> <summary>
Allows for creating and participating in private threads.
Allows for creating private threads.
</summary> </summary>
</member> </member>
<member name="F:Discord.GuildPermission.UseExternalStickers"> <member name="F:Discord.GuildPermission.UseExternalStickers">
@@ -8891,6 +8983,16 @@
Allows the usage of custom stickers from other servers. Allows the usage of custom stickers from other servers.
</summary> </summary>
</member> </member>
<member name="F:Discord.GuildPermission.SendMessagesInThreads">
<summary>
Allows for sending messages in threads.
</summary>
</member>
<member name="F:Discord.GuildPermission.StartEmbeddedActivities">
<summary>
Allows for launching activities (applications with the EMBEDDED flag) in a voice channel.
</summary>
</member>
<member name="F:Discord.GuildPermissions.None"> <member name="F:Discord.GuildPermissions.None">
<summary> Gets a blank <see cref="T:Discord.GuildPermissions"/> that grants no permissions. </summary> <summary> Gets a blank <see cref="T:Discord.GuildPermissions"/> that grants no permissions. </summary>
</member> </member>
@@ -9005,25 +9107,31 @@
<member name="P:Discord.GuildPermissions.ManageThreads"> <member name="P:Discord.GuildPermissions.ManageThreads">
<summary> If <c>true</c>, a user may manage threads in this guild. </summary> <summary> If <c>true</c>, a user may manage threads in this guild. </summary>
</member> </member>
<member name="P:Discord.GuildPermissions.UsePublicThreads">
<member name="P:Discord.GuildPermissions.CreatePublicThreads">
<summary> If <c>true</c>, a user may create public threads in this guild. </summary> <summary> If <c>true</c>, a user may create public threads in this guild. </summary>
</member> </member>
<member name="P:Discord.GuildPermissions.UsePrivateThreads">
<member name="P:Discord.GuildPermissions.CreatePrivateThreads">
<summary> If <c>true</c>, a user may create private threads in this guild. </summary> <summary> If <c>true</c>, a user may create private threads in this guild. </summary>
</member> </member>
<member name="P:Discord.GuildPermissions.UseExternalStickers"> <member name="P:Discord.GuildPermissions.UseExternalStickers">
<summary> If <c>true</c>, a user may use external stickers in this guild. </summary> <summary> If <c>true</c>, a user may use external stickers in this guild. </summary>
</member> </member>
<member name="P:Discord.GuildPermissions.SendMessagesInThreads">
<summary> If <c>true</c>, a user may send messages in threads in this guild. </summary>
</member>
<member name="P:Discord.GuildPermissions.StartEmbeddedActivities">
<summary> If <c>true</c>, a user launch application activites in voice channels in this guild. </summary>
</member>
<member name="M:Discord.GuildPermissions.#ctor(System.UInt64)"> <member name="M:Discord.GuildPermissions.#ctor(System.UInt64)">
<summary> Creates a new <see cref="T:Discord.GuildPermissions"/> with the provided packed value. </summary> <summary> Creates a new <see cref="T:Discord.GuildPermissions"/> with the provided packed value. </summary>
</member> </member>
<member name="M:Discord.GuildPermissions.#ctor(System.String)"> <member name="M:Discord.GuildPermissions.#ctor(System.String)">
<summary> Creates a new <see cref="T:Discord.GuildPermissions"/> with the provided packed value after converting to ulong. </summary> <summary> Creates a new <see cref="T:Discord.GuildPermissions"/> with the provided packed value after converting to ulong. </summary>
</member> </member>
<member name="M:Discord.GuildPermissions.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
<member name="M:Discord.GuildPermissions.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
<summary> Creates a new <see cref="T:Discord.GuildPermissions"/> structure with the provided permissions. </summary> <summary> Creates a new <see cref="T:Discord.GuildPermissions"/> structure with the provided permissions. </summary>
</member> </member>
<member name="M:Discord.GuildPermissions.Modify(System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean})">
<member name="M:Discord.GuildPermissions.Modify(System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean})">
<summary> Creates a new <see cref="T:Discord.GuildPermissions"/> from this one, changing the provided non-null permissions. </summary> <summary> Creates a new <see cref="T:Discord.GuildPermissions"/> from this one, changing the provided non-null permissions. </summary>
</member> </member>
<member name="M:Discord.GuildPermissions.Has(Discord.GuildPermission)"> <member name="M:Discord.GuildPermissions.Has(Discord.GuildPermission)">


+ 11
- 7
src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs View File

@@ -16,7 +16,7 @@ namespace Discord
private string _description; private string _description;


/// <summary> /// <summary>
/// The name of this option.
/// Gets or sets the name of this option.
/// </summary> /// </summary>
public string Name public string Name
{ {
@@ -37,7 +37,7 @@ namespace Discord
} }


/// <summary> /// <summary>
/// The description of this option.
/// Gets or sets the description of this option.
/// </summary> /// </summary>
public string Description public string Description
{ {
@@ -53,27 +53,31 @@ namespace Discord
} }


/// <summary> /// <summary>
/// The type of this option.
/// Gets or sets the type of this option.
/// </summary> /// </summary>
public ApplicationCommandOptionType Type { get; set; } public ApplicationCommandOptionType Type { get; set; }


/// <summary> /// <summary>
/// The first required option for the user to complete. only one option can be default.
/// Gets or sets whether or not this options is the first required option for the user to complete. only one option can be default.
/// </summary> /// </summary>
public bool? Default { get; set; } public bool? Default { get; set; }


/// <summary> /// <summary>
/// <see langword="true"/> if this option is required for this command, otherwise <see langword="false"/>.
/// Gets or sets if the option is required.
/// </summary> /// </summary>
public bool? Required { get; set; } public bool? Required { get; set; }


/// <summary> /// <summary>
/// choices for string and int types for the user to pick from.
/// Gets or sets whether or not this option supports autocomplete.
/// </summary>
public bool Autocomplete { get; set; }
/// <summary>
/// Gets or sets the choices for string and int types for the user to pick from.
/// </summary> /// </summary>
public List<ApplicationCommandOptionChoiceProperties> Choices { get; set; } public List<ApplicationCommandOptionChoiceProperties> Choices { get; set; }


/// <summary> /// <summary>
/// If the option is a subcommand or subcommand group type, this nested options will be the parameters.
/// Gets or sets if this option is a subcommand or subcommand group type, these nested options will be the parameters.
/// </summary> /// </summary>
public List<ApplicationCommandOptionProperties> Options { get; set; } public List<ApplicationCommandOptionProperties> Options { get; set; }




+ 42
- 0
src/Discord.Net.Core/Entities/Interactions/AutocompleteOption.cs View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord
{
/// <summary>
/// Represents an autocomplete option.
/// </summary>
public class AutocompleteOption
{
/// <summary>
/// Gets the type of this option
/// </summary>
public ApplicationCommandOptionType Type { get; }

/// <summary>
/// Gets the name of the option.
/// </summary>
public string Name { get; }

/// <summary>
/// Gets the value of the option.
/// </summary>
public object Value { get; }

/// <summary>
/// Gets whether or not this option is focused by the executing user.
/// </summary>
public bool Focused { get; }

internal AutocompleteOption(ApplicationCommandOptionType type, string name, object value, bool focused)
{
this.Type = type;
this.Name = name;
this.Value = value;
this.Focused = focused;
}
}
}

+ 90
- 0
src/Discord.Net.Core/Entities/Interactions/AutocompleteResult.cs View File

@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord
{
/// <summary>
/// Represents a result to an autocomplete interaction.
/// </summary>
public class AutocompleteResult
{
private object _value { get; set; }
private string _name { get; set; }

/// <summary>
/// Gets or sets the name of the result.
/// </summary>
/// <remarks>
/// Name cannot be null and has to be between 1-100 characters in length.
/// </remarks>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="ArgumentException"/>
public string Name
{
get => _name;
set
{
if (value == null)
throw new ArgumentException("Name cannot be null!");
if (value.Length > 100)
throw new ArgumentException("Name length must be less than or equal to 100 characters in length!");
if (value.Length < 1)
throw new ArgumentException("Name length must at least 1 character in length!");
_name = value;
}
}

/// <summary>
/// Gets or sets the value of the result.
/// </summary>
/// <remarks>
/// Only <see cref="string"/>, <see cref="int"/>, and <see cref="double"/> are allowed for a value.
/// </remarks>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="ArgumentException"/>
public object Value
{
get => _value;
set
{
if (value == null)
throw new ArgumentNullException("Value cannot be null");

switch (value)
{
case string str:
_value = str;
break;
case int integer:
_value = integer;
break;
case double number:
_value = number;
break;

default:
throw new ArgumentException($"Type {value.GetType().Name} cannot be set as a value! Only string, int, and double allowed!");
}
}
}

/// <summary>
/// Creates a new <see cref="AutocompleteResult"/>.
/// </summary>
public AutocompleteResult() { }

/// <summary>
/// Creates a new <see cref="AutocompleteResult"/> with the passed in <paramref name="name"/> and <paramref name="value"/>.
/// </summary>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="ArgumentException"/>
public AutocompleteResult(string name, object value)
{
this.Name = name;
this.Value = value;
}
}
}

+ 8
- 3
src/Discord.Net.Core/Entities/Interactions/InteractionResponseType.cs View File

@@ -45,13 +45,18 @@ namespace Discord
DeferredChannelMessageWithSource = 5, DeferredChannelMessageWithSource = 5,


/// <summary> /// <summary>
/// for components: ACK an interaction and edit the original message later; the user does not see a loading state
/// For components: ACK an interaction and edit the original message later; the user does not see a loading state
/// </summary> /// </summary>
DeferredUpdateMessage = 6, DeferredUpdateMessage = 6,


/// <summary> /// <summary>
/// for components: edit the message the component was attached to
/// For components: edit the message the component was attached to
/// </summary> /// </summary>
UpdateMessage = 7
UpdateMessage = 7,

/// <summary>
/// Respond with a set of choices to a autocomplete interaction
/// </summary>
ApplicationCommandAutocompleteResult = 8
} }
} }

+ 5
- 0
src/Discord.Net.Core/Entities/Interactions/InteractionType.cs View File

@@ -25,5 +25,10 @@ namespace Discord
/// A <see cref="IMessageComponent"/> sent from discord. /// A <see cref="IMessageComponent"/> sent from discord.
/// </summary> /// </summary>
MessageComponent = 3, MessageComponent = 3,

/// <summary>
/// An autocomplete request sent from discord.
/// </summary>
ApplicationCommandAutocomplete = 4,
} }
} }

src/Discord.Net.Core/Entities/Interactions/SlashCommandBuilder.cs → src/Discord.Net.Core/Entities/Interactions/Slash Commands/SlashCommandBuilder.cs View File

@@ -165,7 +165,7 @@ namespace Discord
/// <param name="choices">The choices of this option.</param> /// <param name="choices">The choices of this option.</param>
/// <returns>The current builder.</returns> /// <returns>The current builder.</returns>
public SlashCommandBuilder AddOption(string name, ApplicationCommandOptionType type, public SlashCommandBuilder AddOption(string name, ApplicationCommandOptionType type,
string description, bool required = true, bool isDefault = false, List<SlashCommandOptionBuilder> options = null, params ApplicationCommandOptionChoiceProperties[] choices)
string description, bool required = true, bool isDefault = false, bool isAutocomplete = false, List<SlashCommandOptionBuilder> options = null, params ApplicationCommandOptionChoiceProperties[] choices)
{ {
// Make sure the name matches the requirements from discord // Make sure the name matches the requirements from discord
Preconditions.NotNullOrEmpty(name, nameof(name)); Preconditions.NotNullOrEmpty(name, nameof(name));
@@ -197,6 +197,7 @@ namespace Discord
option.Default = isDefault; option.Default = isDefault;
option.Options = options; option.Options = options;
option.Type = type; option.Type = type;
option.Autocomplete = isAutocomplete;
option.Choices = choices != null ? new List<ApplicationCommandOptionChoiceProperties>(choices) : null; option.Choices = choices != null ? new List<ApplicationCommandOptionChoiceProperties>(choices) : null;


return AddOption(option); return AddOption(option);
@@ -288,7 +289,7 @@ namespace Discord
private string _description; private string _description;


/// <summary> /// <summary>
/// The name of this option.
/// Gets or sets the name of this option.
/// </summary> /// </summary>
public string Name public string Name
{ {
@@ -309,7 +310,7 @@ namespace Discord
} }


/// <summary> /// <summary>
/// The description of this option.
/// Gets or sets the description of this option.
/// </summary> /// </summary>
public string Description public string Description
{ {
@@ -326,27 +327,32 @@ namespace Discord
} }


/// <summary> /// <summary>
/// The type of this option.
/// Gets or sets the type of this option.
/// </summary> /// </summary>
public ApplicationCommandOptionType Type { get; set; } public ApplicationCommandOptionType Type { get; set; }


/// <summary> /// <summary>
/// The first required option for the user to complete. only one option can be default.
/// Gets or sets whether or not this options is the first required option for the user to complete. only one option can be default.
/// </summary> /// </summary>
public bool? Default { get; set; } public bool? Default { get; set; }


/// <summary> /// <summary>
/// <see langword="true"/> if this option is required for this command, otherwise <see langword="false"/>.
/// Gets or sets if the option is required.
/// </summary> /// </summary>
public bool Required { get; set; } public bool Required { get; set; }


/// <summary> /// <summary>
/// choices for string and int types for the user to pick from.
/// Gets or sets whether or not this option supports autocomplete.
/// </summary>
public bool Autocomplete { get; set; }

/// <summary>
/// Gets or sets the choices for string and int types for the user to pick from.
/// </summary> /// </summary>
public List<ApplicationCommandOptionChoiceProperties> Choices { get; set; } public List<ApplicationCommandOptionChoiceProperties> Choices { get; set; }


/// <summary> /// <summary>
/// If the option is a subcommand or subcommand group type, this nested options will be the parameters.
/// Gets or sets if this option is a subcommand or subcommand group type, these nested options will be the parameters.
/// </summary> /// </summary>
public List<SlashCommandOptionBuilder> Options { get; set; } public List<SlashCommandOptionBuilder> Options { get; set; }


@@ -372,7 +378,8 @@ namespace Discord
Required = this.Required, Required = this.Required,
Type = this.Type, Type = this.Type,
Options = this.Options?.Count > 0 ? new List<ApplicationCommandOptionProperties>(this.Options.Select(x => x.Build())) : null, Options = this.Options?.Count > 0 ? new List<ApplicationCommandOptionProperties>(this.Options.Select(x => x.Build())) : null,
Choices = this.Choices
Choices = this.Choices,
Autocomplete = this.Autocomplete
}; };
} }



src/Discord.Net.Core/Entities/Interactions/SlashCommandProperties.cs → src/Discord.Net.Core/Entities/Interactions/Slash Commands/SlashCommandProperties.cs View File


+ 4
- 0
src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs View File

@@ -30,6 +30,9 @@ namespace Discord.API
[JsonProperty("options")] [JsonProperty("options")]
public Optional<ApplicationCommandOption[]> Options { get; set; } public Optional<ApplicationCommandOption[]> Options { get; set; }


[JsonProperty("autocomplete")]
public Optional<bool> Autocomplete { get; set; }

public ApplicationCommandOption() { } public ApplicationCommandOption() { }


public ApplicationCommandOption(IApplicationCommandOption cmd) public ApplicationCommandOption(IApplicationCommandOption cmd)
@@ -78,6 +81,7 @@ namespace Discord.API
this.Name = option.Name; this.Name = option.Name;
this.Type = option.Type; this.Type = option.Type;
this.Description = option.Description; this.Description = option.Description;
this.Autocomplete = option.Autocomplete;
} }
} }
} }

+ 27
- 0
src/Discord.Net.Rest/API/Common/AutocompleteInteractionData.cs View File

@@ -0,0 +1,27 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord.API
{
internal class AutocompleteInteractionData : IDiscordInteractionData
{
[JsonProperty("id")]
public ulong Id { get; set; }

[JsonProperty("name")]
public string Name { get; set; }

[JsonProperty("type")]
public ApplicationCommandType Type { get; set; }

[JsonProperty("version")]
public ulong Version { get; set; }

[JsonProperty("options")]
public AutocompleteInteractionDataOption[] Options { get; set; }
}
}

+ 24
- 0
src/Discord.Net.Rest/API/Common/AutocompleteInteractionDataOption.cs View File

@@ -0,0 +1,24 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord.API
{
internal class AutocompleteInteractionDataOption
{
[JsonProperty("type")]
public ApplicationCommandOptionType Type { get; set; }

[JsonProperty("name")]
public string Name { get; set; }

[JsonProperty("value")]
public object Value { get; set; }

[JsonProperty("focused")]
public bool Focused { get; set; }
}
}

+ 3
- 0
src/Discord.Net.Rest/API/Common/InteractionCallbackData.cs View File

@@ -21,5 +21,8 @@ namespace Discord.API


[JsonProperty("components")] [JsonProperty("components")]
public Optional<API.ActionRowComponent[]> Components { get; set; } public Optional<API.ActionRowComponent[]> Components { get; set; }

[JsonProperty("choices")]
public Optional<API.ApplicationCommandOptionChoice[]> Choices { get; set; }
} }
} }

+ 22
- 0
src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs View File

@@ -418,6 +418,28 @@ namespace Discord.Rest


public static async Task DeletedInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null) public static async Task DeletedInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null)
=> await client.ApiClient.DeleteInteractionFollowupMessageAsync(message.Id, message.Token, options); => await client.ApiClient.DeleteInteractionFollowupMessageAsync(message.Id, message.Token, options);

public static Task SendAutocompleteResult(BaseDiscordClient client, IEnumerable<AutocompleteResult> result, ulong interactionId,
string interactionToken, RequestOptions options)
{
if (result == null)
result = new AutocompleteResult[0];

Preconditions.AtMost(result.Count(), 20, nameof(result), "A maximum of 20 choices are allowed!");

var apiArgs = new InteractionResponse()
{
Type = InteractionResponseType.ApplicationCommandAutocompleteResult,
Data = new InteractionCallbackData()
{
Choices = result.Any()
? result.Select(x => new API.ApplicationCommandOptionChoice() { Name = x.Name, Value = x.Value }).ToArray()
: new ApplicationCommandOptionChoice[0]
}
};

return client.ApiClient.CreateInteractionResponseAsync(apiArgs, interactionId, interactionToken, options);
}
#endregion #endregion


#region Guild permissions #region Guild permissions


+ 7
- 0
src/Discord.Net.Rest/Net/Converters/InteractionConverter.cs View File

@@ -53,6 +53,13 @@ namespace Discord.Net.Converters
interaction.Data = messageComponent; interaction.Data = messageComponent;
} }
break; break;
case InteractionType.ApplicationCommandAutocomplete:
{
var autocompleteData = new API.AutocompleteInteractionData();
serializer.Populate(result.CreateReader(), autocompleteData);
interaction.Data = autocompleteData;
}
break;
} }
} }
else else


+ 103
- 1
src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml View File

@@ -3961,6 +3961,98 @@
The value(s) of a <see cref="T:Discord.SelectMenuComponent"/> interaction response. The value(s) of a <see cref="T:Discord.SelectMenuComponent"/> interaction response.
</summary> </summary>
</member> </member>
<member name="T:Discord.WebSocket.SocketAutocompleteInteraction">
<summary>
Represents a <see cref="F:Discord.InteractionType.ApplicationCommandAutocomplete"/> received over the gateway.
</summary>
</member>
<member name="P:Discord.WebSocket.SocketAutocompleteInteraction.Data">
<summary>
The autocomplete data of this interaction.
</summary>
</member>
<member name="M:Discord.WebSocket.SocketAutocompleteInteraction.RespondAsync(System.Collections.Generic.IEnumerable{Discord.AutocompleteResult},Discord.RequestOptions)">
<summary>
Responds to this interaction with a set of choices.
</summary>
<param name="result">
The set of choices for the user to pick from.
<remarks>
A max of 20 choices are allowed. Passing <see langword="null"/> for this argument will show the executing user that
there is no choices for their autocompleted input.
</remarks>
</param>
<param name="options">The request options for this response.</param>
<returns>
A task that represents the asynchronous operation of responding to this interaction.
</returns>
</member>
<member name="M:Discord.WebSocket.SocketAutocompleteInteraction.RespondAsync(Discord.RequestOptions,Discord.AutocompleteResult[])">
<summary>
Responds to this interaction with a set of choices.
</summary>
<param name="options">The request options for this response.</param>
<param name="result">
The set of choices for the user to pick from.
<remarks>
A max of 20 choices are allowed. Passing <see langword="null"/> for this argument will show the executing user that
there is no choices for their autocompleted input.
</remarks>
</param>
<returns>
A task that represents the asynchronous operation of responding to this interaction.
</returns>
</member>
<member name="M:Discord.WebSocket.SocketAutocompleteInteraction.DeferAsync(System.Boolean,Discord.RequestOptions)">
<inheritdoc/>
</member>
<member name="M:Discord.WebSocket.SocketAutocompleteInteraction.FollowupAsync(System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent,Discord.Embed)">
<inheritdoc/>
</member>
<member name="M:Discord.WebSocket.SocketAutocompleteInteraction.FollowupWithFileAsync(System.String,System.IO.Stream,System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent,Discord.Embed)">
<inheritdoc/>
</member>
<member name="M:Discord.WebSocket.SocketAutocompleteInteraction.FollowupWithFileAsync(System.String,System.String,System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent,Discord.Embed)">
<inheritdoc/>
</member>
<member name="M:Discord.WebSocket.SocketAutocompleteInteraction.RespondAsync(System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent,Discord.Embed)">
<inheritdoc/>
</member>
<member name="T:Discord.WebSocket.SocketAutocompleteInteractionData">
<summary>
Represents data for a slash commands autocomplete interaction.
</summary>
</member>
<member name="P:Discord.WebSocket.SocketAutocompleteInteractionData.CommandName">
<summary>
Gets the name of the invoked command.
</summary>
</member>
<member name="P:Discord.WebSocket.SocketAutocompleteInteractionData.CommandId">
<summary>
Gets the id of the invoked command.
</summary>
</member>
<member name="P:Discord.WebSocket.SocketAutocompleteInteractionData.Type">
<summary>
Gets the type of the invoked command.
</summary>
</member>
<member name="P:Discord.WebSocket.SocketAutocompleteInteractionData.Version">
<summary>
Gets the version of the invoked command.
</summary>
</member>
<member name="P:Discord.WebSocket.SocketAutocompleteInteractionData.Current">
<summary>
Gets the current autocomplete option that is activly being filled out.
</summary>
</member>
<member name="P:Discord.WebSocket.SocketAutocompleteInteractionData.Options">
<summary>
Gets a collection of all the other options the executing users has filled out.
</summary>
</member>
<member name="T:Discord.WebSocket.SocketSlashCommand"> <member name="T:Discord.WebSocket.SocketSlashCommand">
<summary> <summary>
Represents a Websocket-based slash command received over the gateway. Represents a Websocket-based slash command received over the gateway.
@@ -4088,7 +4180,17 @@
</member> </member>
<member name="T:Discord.WebSocket.SocketCommandBase"> <member name="T:Discord.WebSocket.SocketCommandBase">
<summary> <summary>
Base class for User, Message, and Slash command interactions
Base class for User, Message, and Slash command interactions.
</summary>
</member>
<member name="P:Discord.WebSocket.SocketCommandBase.CommandName">
<summary>
Gets the name of the invoked command.
</summary>
</member>
<member name="P:Discord.WebSocket.SocketCommandBase.CommandId">
<summary>
Gets the id of the invoked command.
</summary> </summary>
</member> </member>
<member name="P:Discord.WebSocket.SocketCommandBase.Data"> <member name="P:Discord.WebSocket.SocketCommandBase.Data">


+ 97
- 0
src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketAutocompleteInteraction.cs View File

@@ -0,0 +1,97 @@
using Discord.Rest;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model = Discord.API.Interaction;
using DataModel = Discord.API.AutocompleteInteractionData;


namespace Discord.WebSocket
{
/// <summary>
/// Represents a <see cref="InteractionType.ApplicationCommandAutocomplete"/> received over the gateway.
/// </summary>
public class SocketAutocompleteInteraction : SocketInteraction
{
/// <summary>
/// The autocomplete data of this interaction.
/// </summary>
public new SocketAutocompleteInteractionData Data { get; }

internal SocketAutocompleteInteraction(DiscordSocketClient client, Model model, ISocketMessageChannel channel)
: base(client, model.Id, channel)
{
var dataModel = model.Data.IsSpecified
? (DataModel)model.Data.Value
: null;

if (dataModel != null)
Data = new SocketAutocompleteInteractionData(dataModel);
}

internal new static SocketAutocompleteInteraction Create(DiscordSocketClient client, Model model, ISocketMessageChannel channel)
{
var entity = new SocketAutocompleteInteraction(client, model, channel);
entity.Update(model);
return entity;
}

/// <summary>
/// Responds to this interaction with a set of choices.
/// </summary>
/// <param name="result">
/// The set of choices for the user to pick from.
/// <remarks>
/// A max of 20 choices are allowed. Passing <see langword="null"/> for this argument will show the executing user that
/// there is no choices for their autocompleted input.
/// </remarks>
/// </param>
/// <param name="options">The request options for this response.</param>
/// <returns>
/// A task that represents the asynchronous operation of responding to this interaction.
/// </returns>
public Task RespondAsync(IEnumerable<AutocompleteResult> result, RequestOptions options = null)
=> InteractionHelper.SendAutocompleteResult(Discord, result, this.Id, this.Token, options);

/// <summary>
/// Responds to this interaction with a set of choices.
/// </summary>
/// <param name="options">The request options for this response.</param>
/// <param name="result">
/// The set of choices for the user to pick from.
/// <remarks>
/// A max of 20 choices are allowed. Passing <see langword="null"/> for this argument will show the executing user that
/// there is no choices for their autocompleted input.
/// </remarks>
/// </param>
/// <returns>
/// A task that represents the asynchronous operation of responding to this interaction.
/// </returns>
public Task RespondAsync(RequestOptions options = null, params AutocompleteResult[] result)
=> InteractionHelper.SendAutocompleteResult(Discord, result, this.Id, this.Token, options);


/// <inheritdoc/>
[Obsolete("Autocomplete interactions cannot be defered!", true)]
public override Task DeferAsync(bool ephemeral = false, RequestOptions options = null) => throw new NotSupportedException();

/// <inheritdoc/>
[Obsolete("Autocomplete interactions cannot have followups!", true)]
public override Task<RestFollowupMessage> FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null) => throw new NotSupportedException();

/// <inheritdoc/>
[Obsolete("Autocomplete interactions cannot have followups!", true)]
public override Task<RestFollowupMessage> FollowupWithFileAsync(string text = null, Stream fileStream = null, string fileName = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null) => throw new NotSupportedException();

/// <inheritdoc/>
[Obsolete("Autocomplete interactions cannot have followups!", true)]
public override Task<RestFollowupMessage> FollowupWithFileAsync(string text = null, string filePath = null, string fileName = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null) => throw new NotSupportedException();

/// <inheritdoc/>
[Obsolete("Autocomplete interactions cannot have normal responses!", true)]
public override Task RespondAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null) => throw new NotSupportedException();
}
}

+ 60
- 0
src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketAutocompleteInteractionData.cs View File

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataModel = Discord.API.AutocompleteInteractionData;


namespace Discord.WebSocket
{
/// <summary>
/// Represents data for a slash commands autocomplete interaction.
/// </summary>
public class SocketAutocompleteInteractionData
{
/// <summary>
/// Gets the name of the invoked command.
/// </summary>
public string CommandName { get; }

/// <summary>
/// Gets the id of the invoked command.
/// </summary>
public ulong CommandId { get; }

/// <summary>
/// Gets the type of the invoked command.
/// </summary>
public ApplicationCommandType Type { get; }

/// <summary>
/// Gets the version of the invoked command.
/// </summary>
public ulong Version { get; }

/// <summary>
/// Gets the current autocomplete option that is activly being filled out.
/// </summary>
public AutocompleteOption Current { get; }

/// <summary>
/// Gets a collection of all the other options the executing users has filled out.
/// </summary>
public IReadOnlyCollection<AutocompleteOption> Options { get; }

internal SocketAutocompleteInteractionData(DataModel model)
{
var options = model.Options.Select(x => new AutocompleteOption(x.Type, x.Name, x.Value, x.Focused));

this.Current = options.FirstOrDefault(x => x.Focused);
this.Options = options.ToImmutableArray();

this.CommandName = model.Name;
this.CommandId = model.Id;
this.Type = model.Type;
this.Version = model.Version;
}
}
}

+ 13
- 1
src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs View File

@@ -12,10 +12,22 @@ using Model = Discord.API.Interaction;
namespace Discord.WebSocket namespace Discord.WebSocket
{ {
/// <summary> /// <summary>
/// Base class for User, Message, and Slash command interactions
/// Base class for User, Message, and Slash command interactions.
/// </summary> /// </summary>
public class SocketCommandBase : SocketInteraction public class SocketCommandBase : SocketInteraction
{ {
/// <summary>
/// Gets the name of the invoked command.
/// </summary>
public string CommandName
=> Data.Name;

/// <summary>
/// Gets the id of the invoked command.
/// </summary>
public ulong CommandId
=> Data.Id;

/// <summary> /// <summary>
/// The data associated with this interaction. /// The data associated with this interaction.
/// </summary> /// </summary>


+ 17
- 12
src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs View File

@@ -65,23 +65,28 @@ namespace Discord.WebSocket
{ {
if (model.Type == InteractionType.ApplicationCommand) if (model.Type == InteractionType.ApplicationCommand)
{ {
if (model.ApplicationId != null)
{
var dataModel = model.Data.IsSpecified ?
var dataModel = model.Data.IsSpecified ?
(DataModel)model.Data.Value (DataModel)model.Data.Value
: null; : null;
if (dataModel != null)
{
if (dataModel.Type.Equals(ApplicationCommandType.User))
return SocketUserCommand.Create(client, model, channel);
if (dataModel.Type.Equals(ApplicationCommandType.Message))
return SocketMessageCommand.Create(client, model, channel);
}

if (dataModel == null)
return null;

switch (dataModel.Type)
{
case ApplicationCommandType.Slash:
return SocketSlashCommand.Create(client, model, channel);
case ApplicationCommandType.Message:
return SocketMessageCommand.Create(client, model, channel);
case ApplicationCommandType.User:
return SocketUserCommand.Create(client, model, channel);
default: return null;
} }
return SocketSlashCommand.Create(client, model, channel);
} }
if (model.Type == InteractionType.MessageComponent)
else if (model.Type == InteractionType.MessageComponent)
return SocketMessageComponent.Create(client, model, channel); return SocketMessageComponent.Create(client, model, channel);
else if (model.Type == InteractionType.ApplicationCommandAutocomplete)
return SocketAutocompleteInteraction.Create(client, model, channel);
else else
return null; return null;
} }


Loading…
Cancel
Save