commit dca41a348e
Author: quin lynch <lynchquin@gmail.com>
Date: Thu Sep 23 07:02:19 2021 -0300
Autocomplete commands
pull/1923/head
@@ -1,4 +1,4 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<Import Project="../../Discord.Net.targets" /> | |||
<Import Project="../../StyleAnalyzer.targets" /> | |||
<PropertyGroup> | |||
@@ -4508,37 +4508,42 @@ | |||
</member> | |||
<member name="P:Discord.ApplicationCommandOptionProperties.Name"> | |||
<summary> | |||
The name of this option. | |||
Gets or sets the name of this option. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.ApplicationCommandOptionProperties.Description"> | |||
<summary> | |||
The description of this option. | |||
Gets or sets the description of this option. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.ApplicationCommandOptionProperties.Type"> | |||
<summary> | |||
The type of this option. | |||
Gets or sets the type of this option. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.ApplicationCommandOptionProperties.Default"> | |||
<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> | |||
</member> | |||
<member name="P:Discord.ApplicationCommandOptionProperties.Required"> | |||
<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> | |||
</member> | |||
<member name="P:Discord.ApplicationCommandOptionProperties.Choices"> | |||
<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> | |||
</member> | |||
<member name="P:Discord.ApplicationCommandOptionProperties.Options"> | |||
<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> | |||
</member> | |||
<member name="T:Discord.ApplicationCommandOptionChoiceProperties"> | |||
@@ -4649,6 +4654,68 @@ | |||
ApplicationCommandType.Message is Context Menu Message command type | |||
</summary> | |||
</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"> | |||
<summary> | |||
A class used to build Message commands. | |||
@@ -5029,12 +5096,17 @@ | |||
</member> | |||
<member name="F:Discord.InteractionResponseType.DeferredUpdateMessage"> | |||
<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> | |||
</member> | |||
<member name="F:Discord.InteractionResponseType.UpdateMessage"> | |||
<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> | |||
</member> | |||
<member name="T:Discord.InteractionType"> | |||
@@ -5057,6 +5129,11 @@ | |||
A <see cref="T:Discord.IMessageComponent"/> sent from discord. | |||
</summary> | |||
</member> | |||
<member name="F:Discord.InteractionType.ApplicationCommandAutocomplete"> | |||
<summary> | |||
An autocomplete request sent from discord. | |||
</summary> | |||
</member> | |||
<member name="T:Discord.ActionRowComponent"> | |||
<summary> | |||
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> | |||
<returns>The current builder.</returns> | |||
</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> | |||
Adds an option to the current slash command. | |||
</summary> | |||
@@ -5987,37 +6064,42 @@ | |||
</member> | |||
<member name="P:Discord.SlashCommandOptionBuilder.Name"> | |||
<summary> | |||
The name of this option. | |||
Gets or sets the name of this option. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.SlashCommandOptionBuilder.Description"> | |||
<summary> | |||
The description of this option. | |||
Gets or sets the description of this option. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.SlashCommandOptionBuilder.Type"> | |||
<summary> | |||
The type of this option. | |||
Gets or sets the type of this option. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.SlashCommandOptionBuilder.Default"> | |||
<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> | |||
</member> | |||
<member name="P:Discord.SlashCommandOptionBuilder.Required"> | |||
<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> | |||
</member> | |||
<member name="P:Discord.SlashCommandOptionBuilder.Choices"> | |||
<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> | |||
</member> | |||
<member name="P:Discord.SlashCommandOptionBuilder.Options"> | |||
<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> | |||
</member> | |||
<member name="M:Discord.SlashCommandOptionBuilder.Build"> | |||
@@ -8876,14 +8958,24 @@ | |||
authentication when used on a guild that has server-wide 2FA enabled. | |||
</remarks> | |||
</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"> | |||
<summary> | |||
Allows for creating and participating in threads. | |||
Allows for creating public threads. | |||
</summary> | |||
</member> | |||
<member name="F:Discord.GuildPermission.UsePrivateThreads"> | |||
<summary> | |||
Allows for creating and participating in private threads. | |||
Allows for creating private threads. | |||
</summary> | |||
</member> | |||
<member name="F:Discord.GuildPermission.UseExternalStickers"> | |||
@@ -8891,6 +8983,16 @@ | |||
Allows the usage of custom stickers from other servers. | |||
</summary> | |||
</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"> | |||
<summary> Gets a blank <see cref="T:Discord.GuildPermissions"/> that grants no permissions. </summary> | |||
</member> | |||
@@ -9005,25 +9107,31 @@ | |||
<member name="P:Discord.GuildPermissions.ManageThreads"> | |||
<summary> If <c>true</c>, a user may manage threads in this guild. </summary> | |||
</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> | |||
</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> | |||
</member> | |||
<member name="P:Discord.GuildPermissions.UseExternalStickers"> | |||
<summary> If <c>true</c>, a user may use external stickers in this guild. </summary> | |||
</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)"> | |||
<summary> Creates a new <see cref="T:Discord.GuildPermissions"/> with the provided packed value. </summary> | |||
</member> | |||
<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> | |||
</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> | |||
</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> | |||
</member> | |||
<member name="M:Discord.GuildPermissions.Has(Discord.GuildPermission)"> | |||
@@ -16,7 +16,7 @@ namespace Discord | |||
private string _description; | |||
/// <summary> | |||
/// The name of this option. | |||
/// Gets or sets the name of this option. | |||
/// </summary> | |||
public string Name | |||
{ | |||
@@ -37,7 +37,7 @@ namespace Discord | |||
} | |||
/// <summary> | |||
/// The description of this option. | |||
/// Gets or sets the description of this option. | |||
/// </summary> | |||
public string Description | |||
{ | |||
@@ -53,27 +53,31 @@ namespace Discord | |||
} | |||
/// <summary> | |||
/// The type of this option. | |||
/// Gets or sets the type of this option. | |||
/// </summary> | |||
public ApplicationCommandOptionType Type { get; set; } | |||
/// <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> | |||
public bool? Default { get; set; } | |||
/// <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> | |||
public bool? Required { get; set; } | |||
/// <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> | |||
public List<ApplicationCommandOptionChoiceProperties> Choices { get; set; } | |||
/// <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> | |||
public List<ApplicationCommandOptionProperties> Options { get; set; } | |||
@@ -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; | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -45,13 +45,18 @@ namespace Discord | |||
DeferredChannelMessageWithSource = 5, | |||
/// <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> | |||
DeferredUpdateMessage = 6, | |||
/// <summary> | |||
/// for components: edit the message the component was attached to | |||
/// For components: edit the message the component was attached to | |||
/// </summary> | |||
UpdateMessage = 7 | |||
UpdateMessage = 7, | |||
/// <summary> | |||
/// Respond with a set of choices to a autocomplete interaction | |||
/// </summary> | |||
ApplicationCommandAutocompleteResult = 8 | |||
} | |||
} |
@@ -25,5 +25,10 @@ namespace Discord | |||
/// A <see cref="IMessageComponent"/> sent from discord. | |||
/// </summary> | |||
MessageComponent = 3, | |||
/// <summary> | |||
/// An autocomplete request sent from discord. | |||
/// </summary> | |||
ApplicationCommandAutocomplete = 4, | |||
} | |||
} |
@@ -165,7 +165,7 @@ namespace Discord | |||
/// <param name="choices">The choices of this option.</param> | |||
/// <returns>The current builder.</returns> | |||
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 | |||
Preconditions.NotNullOrEmpty(name, nameof(name)); | |||
@@ -197,6 +197,7 @@ namespace Discord | |||
option.Default = isDefault; | |||
option.Options = options; | |||
option.Type = type; | |||
option.Autocomplete = isAutocomplete; | |||
option.Choices = choices != null ? new List<ApplicationCommandOptionChoiceProperties>(choices) : null; | |||
return AddOption(option); | |||
@@ -288,7 +289,7 @@ namespace Discord | |||
private string _description; | |||
/// <summary> | |||
/// The name of this option. | |||
/// Gets or sets the name of this option. | |||
/// </summary> | |||
public string Name | |||
{ | |||
@@ -309,7 +310,7 @@ namespace Discord | |||
} | |||
/// <summary> | |||
/// The description of this option. | |||
/// Gets or sets the description of this option. | |||
/// </summary> | |||
public string Description | |||
{ | |||
@@ -326,27 +327,32 @@ namespace Discord | |||
} | |||
/// <summary> | |||
/// The type of this option. | |||
/// Gets or sets the type of this option. | |||
/// </summary> | |||
public ApplicationCommandOptionType Type { get; set; } | |||
/// <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> | |||
public bool? Default { get; set; } | |||
/// <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> | |||
public bool Required { get; set; } | |||
/// <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> | |||
public List<ApplicationCommandOptionChoiceProperties> Choices { get; set; } | |||
/// <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> | |||
public List<SlashCommandOptionBuilder> Options { get; set; } | |||
@@ -372,7 +378,8 @@ namespace Discord | |||
Required = this.Required, | |||
Type = this.Type, | |||
Options = this.Options?.Count > 0 ? new List<ApplicationCommandOptionProperties>(this.Options.Select(x => x.Build())) : null, | |||
Choices = this.Choices | |||
Choices = this.Choices, | |||
Autocomplete = this.Autocomplete | |||
}; | |||
} | |||
@@ -30,6 +30,9 @@ namespace Discord.API | |||
[JsonProperty("options")] | |||
public Optional<ApplicationCommandOption[]> Options { get; set; } | |||
[JsonProperty("autocomplete")] | |||
public Optional<bool> Autocomplete { get; set; } | |||
public ApplicationCommandOption() { } | |||
public ApplicationCommandOption(IApplicationCommandOption cmd) | |||
@@ -78,6 +81,7 @@ namespace Discord.API | |||
this.Name = option.Name; | |||
this.Type = option.Type; | |||
this.Description = option.Description; | |||
this.Autocomplete = option.Autocomplete; | |||
} | |||
} | |||
} |
@@ -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; } | |||
} | |||
} |
@@ -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; } | |||
} | |||
} |
@@ -21,5 +21,8 @@ namespace Discord.API | |||
[JsonProperty("components")] | |||
public Optional<API.ActionRowComponent[]> Components { get; set; } | |||
[JsonProperty("choices")] | |||
public Optional<API.ApplicationCommandOptionChoice[]> Choices { get; set; } | |||
} | |||
} |
@@ -418,6 +418,28 @@ namespace Discord.Rest | |||
public static async Task DeletedInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null) | |||
=> 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 | |||
#region Guild permissions | |||
@@ -53,6 +53,13 @@ namespace Discord.Net.Converters | |||
interaction.Data = messageComponent; | |||
} | |||
break; | |||
case InteractionType.ApplicationCommandAutocomplete: | |||
{ | |||
var autocompleteData = new API.AutocompleteInteractionData(); | |||
serializer.Populate(result.CreateReader(), autocompleteData); | |||
interaction.Data = autocompleteData; | |||
} | |||
break; | |||
} | |||
} | |||
else | |||
@@ -3961,6 +3961,98 @@ | |||
The value(s) of a <see cref="T:Discord.SelectMenuComponent"/> interaction response. | |||
</summary> | |||
</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"> | |||
<summary> | |||
Represents a Websocket-based slash command received over the gateway. | |||
@@ -4088,7 +4180,17 @@ | |||
</member> | |||
<member name="T:Discord.WebSocket.SocketCommandBase"> | |||
<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> | |||
</member> | |||
<member name="P:Discord.WebSocket.SocketCommandBase.Data"> | |||
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -12,10 +12,22 @@ using Model = Discord.API.Interaction; | |||
namespace Discord.WebSocket | |||
{ | |||
/// <summary> | |||
/// Base class for User, Message, and Slash command interactions | |||
/// Base class for User, Message, and Slash command interactions. | |||
/// </summary> | |||
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> | |||
/// The data associated with this interaction. | |||
/// </summary> | |||
@@ -65,23 +65,28 @@ namespace Discord.WebSocket | |||
{ | |||
if (model.Type == InteractionType.ApplicationCommand) | |||
{ | |||
if (model.ApplicationId != null) | |||
{ | |||
var dataModel = model.Data.IsSpecified ? | |||
var dataModel = model.Data.IsSpecified ? | |||
(DataModel)model.Data.Value | |||
: 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); | |||
else if (model.Type == InteractionType.ApplicationCommandAutocomplete) | |||
return SocketAutocompleteInteraction.Create(client, model, channel); | |||
else | |||
return null; | |||
} | |||