Browse Source

Implemented Context Menus

Added ApplicationCommand types:
Slash : 1
User: 2
Message: 3

And the appropriate CRUD methods.
pull/1923/head
drobbins329 3 years ago
parent
commit
afa480a8e6
26 changed files with 1320 additions and 15 deletions
  1. +17
    -3
      Discord.Net.sln
  2. +1
    -1
      src/Discord.Net.Core/Discord.Net.Core.csproj
  3. +149
    -0
      src/Discord.Net.Core/Discord.Net.Core.xml
  4. +5
    -1
      src/Discord.Net.Core/Entities/Interactions/ApplicationCommandProperties.cs
  5. +15
    -0
      src/Discord.Net.Core/Entities/Interactions/ApplicationCommandTypes.cs
  6. +5
    -0
      src/Discord.Net.Core/Entities/Interactions/IApplicationCommand.cs
  7. +109
    -0
      src/Discord.Net.Core/Entities/Interactions/MessageCommandBuilder.cs
  8. +30
    -0
      src/Discord.Net.Core/Entities/Interactions/MessageCommandCreationProperties.cs
  9. +2
    -1
      src/Discord.Net.Core/Entities/Interactions/SlashCommandBuilder.cs
  10. +4
    -0
      src/Discord.Net.Core/Entities/Interactions/SlashCommandCreationProperties.cs
  11. +109
    -0
      src/Discord.Net.Core/Entities/Interactions/UserCommandBuilder.cs
  12. +30
    -0
      src/Discord.Net.Core/Entities/Interactions/UserCommandCreationProperties.cs
  13. +5
    -1
      src/Discord.Net.Rest/API/Rest/CreateApplicationCommandParams.cs
  14. +3
    -0
      src/Discord.Net.Rest/API/Rest/ModifyApplicationCommandParams.cs
  15. +97
    -0
      src/Discord.Net.Rest/Discord.Net.Rest.xml
  16. +134
    -0
      src/Discord.Net.Rest/DiscordRestApiClient.cs
  17. +17
    -0
      src/Discord.Net.Rest/DiscordRestClient.cs
  18. +346
    -0
      src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
  19. +27
    -7
      src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommand.cs
  20. +5
    -1
      src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandType.cs
  21. +41
    -0
      src/Discord.Net.Rest/Entities/Interactions/RestGlobalMessageCommand.cs
  22. +41
    -0
      src/Discord.Net.Rest/Entities/Interactions/RestGlobalUserCommand.cs
  23. +61
    -0
      src/Discord.Net.Rest/Entities/Interactions/RestGuildMessageCommand.cs
  24. +61
    -0
      src/Discord.Net.Rest/Entities/Interactions/RestGuildUserCommand.cs
  25. +3
    -0
      src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml
  26. +3
    -0
      src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketApplicationCommand.cs

+ 17
- 3
Discord.Net.sln View File

@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28407.52
# Visual Studio Version 17
VisualStudioVersion = 17.0.31521.260
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Core", "src\Discord.Net.Core\Discord.Net.Core.csproj", "{91E9E7BD-75C9-4E98-84AA-2C271922E5C2}"
EndProject
@@ -40,7 +40,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Analyzers.Tests
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Examples", "src\Discord.Net.Examples\Discord.Net.Examples.csproj", "{47820065-3CFB-401C-ACEA-862BD564A404}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "idn", "samples\idn\idn.csproj", "{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "idn", "samples\idn\idn.csproj", "{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FeatureTesting", "..\FeatureTesting\FeatureTesting\FeatureTesting.csproj", "{0CC57A32-3AC7-489D-8DF5-C431925E4675}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -232,6 +234,18 @@ Global
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Release|x64.Build.0 = Release|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Release|x86.ActiveCfg = Release|Any CPU
{4A03840B-9EBE-47E3-89AB-E0914DF21AFB}.Release|x86.Build.0 = Release|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Debug|x64.ActiveCfg = Debug|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Debug|x64.Build.0 = Debug|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Debug|x86.ActiveCfg = Debug|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Debug|x86.Build.0 = Debug|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Release|Any CPU.Build.0 = Release|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Release|x64.ActiveCfg = Release|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Release|x64.Build.0 = Release|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Release|x86.ActiveCfg = Release|Any CPU
{0CC57A32-3AC7-489D-8DF5-C431925E4675}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE


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

@@ -8,7 +8,7 @@
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net461;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard2.0;netstandard2.1</TargetFrameworks>
<PackageId>Discord.Net.Labs.Core</PackageId>
<Version>3.0.0-pre</Version>
<Version>3.3.1.0</Version>
<Product>Discord.Net.Labs.Core</Product>
<RepositoryUrl>https://github.com/Discord-Net-Labs/Discord.Net-Labs</RepositoryUrl>
<PackageIcon>Temporary.png</PackageIcon>


+ 149
- 0
src/Discord.Net.Core/Discord.Net.Core.xml View File

@@ -4452,6 +4452,11 @@
Gets or sets the discription of this command.
</summary>
</member>
<member name="P:Discord.ApplicationCommandProperties.Type">
<summary>
Gets or sets the type for this command.
</summary>
</member>
<member name="P:Discord.ApplicationCommandProperties.Options">
<summary>
Gets or sets the options for this command.
@@ -4472,6 +4477,11 @@
Gets the unique id of the parent application.
</summary>
</member>
<member name="P:Discord.IApplicationCommand.Type">
<summary>
The type of the command
</summary>
</member>
<member name="P:Discord.IApplicationCommand.Name">
<summary>
The name of the command.
@@ -5444,6 +5454,73 @@
Will render this option as selected by default.
</summary>
</member>
<member name="T:Discord.MessageCommandBuilder">
<summary>
A class used to build slash commands.
</summary>
</member>
<member name="F:Discord.MessageCommandBuilder.MaxNameLength">
<summary>
Returns the maximun length a commands name allowed by Discord
</summary>
</member>
<member name="F:Discord.MessageCommandBuilder.MaxDescriptionLength">
<summary>
Returns the maximum length of a commands description allowed by Discord.
</summary>
</member>
<member name="P:Discord.MessageCommandBuilder.Name">
<summary>
The name of this slash command.
</summary>
</member>
<member name="P:Discord.MessageCommandBuilder.Description">
<summary>
A 1-100 length description of this slash command
</summary>
</member>
<member name="M:Discord.MessageCommandBuilder.Build">
<summary>
Build the current builder into a <see cref="T:Discord.MessageCommandCreationProperties"/> class.
</summary>
<returns>A <see cref="T:Discord.MessageCommandCreationProperties"/> that can be used to create user commands over rest.</returns>
</member>
<member name="M:Discord.MessageCommandBuilder.WithName(System.String)">
<summary>
Sets the field name.
</summary>
<param name="name">The value to set the field name to.</param>
<returns>
The current builder.
</returns>
</member>
<member name="M:Discord.MessageCommandBuilder.WithDescription(System.String)">
<summary>
Sets the description of the current command.
</summary>
<param name="description">The description of this command.</param>
<returns>The current builder.</returns>
</member>
<member name="T:Discord.MessageCommandCreationProperties">
<summary>
A class used to create Message commands.
</summary>
</member>
<member name="P:Discord.MessageCommandCreationProperties.Name">
<summary>
The name of this command.
</summary>
</member>
<member name="P:Discord.MessageCommandCreationProperties.Description">
<summary>
The discription of this command.
</summary>
</member>
<member name="P:Discord.MessageCommandCreationProperties.Type">
<summary>
Gets or sets the type for this command.
</summary>
</member>
<member name="T:Discord.SlashCommandBuilder">
<summary>
A class used to build slash commands.
@@ -5691,6 +5768,11 @@
The discription of this command.
</summary>
</member>
<member name="P:Discord.SlashCommandCreationProperties.Type">
<summary>
Gets or sets the type for this command.
</summary>
</member>
<member name="P:Discord.SlashCommandCreationProperties.Options">
<summary>
Gets or sets the options for this command.
@@ -5701,6 +5783,73 @@
Whether the command is enabled by default when the app is added to a guild. Default is <see langword="true"/>
</summary>
</member>
<member name="T:Discord.UserCommandBuilder">
<summary>
A class used to build slash commands.
</summary>
</member>
<member name="F:Discord.UserCommandBuilder.MaxNameLength">
<summary>
Returns the maximun length a commands name allowed by Discord
</summary>
</member>
<member name="F:Discord.UserCommandBuilder.MaxDescriptionLength">
<summary>
Returns the maximum length of a commands description allowed by Discord.
</summary>
</member>
<member name="P:Discord.UserCommandBuilder.Name">
<summary>
The name of this slash command.
</summary>
</member>
<member name="P:Discord.UserCommandBuilder.Description">
<summary>
A 1-100 length description of this slash command
</summary>
</member>
<member name="M:Discord.UserCommandBuilder.Build">
<summary>
Build the current builder into a <see cref="T:Discord.UserCommandCreationProperties"/> class.
</summary>
<returns>A <see cref="T:Discord.UserCommandCreationProperties"/> that can be used to create user commands over rest.</returns>
</member>
<member name="M:Discord.UserCommandBuilder.WithName(System.String)">
<summary>
Sets the field name.
</summary>
<param name="name">The value to set the field name to.</param>
<returns>
The current builder.
</returns>
</member>
<member name="M:Discord.UserCommandBuilder.WithDescription(System.String)">
<summary>
Sets the description of the current command.
</summary>
<param name="description">The description of this command.</param>
<returns>The current builder.</returns>
</member>
<member name="T:Discord.UserCommandCreationProperties">
<summary>
A class used to create User commands.
</summary>
</member>
<member name="P:Discord.UserCommandCreationProperties.Name">
<summary>
The name of this command.
</summary>
</member>
<member name="P:Discord.UserCommandCreationProperties.Description">
<summary>
The discription of this command.
</summary>
</member>
<member name="P:Discord.UserCommandCreationProperties.Type">
<summary>
Gets or sets the type for this command.
</summary>
</member>
<member name="T:Discord.IInvite">
<summary>
Represents a generic invite object.


+ 5
- 1
src/Discord.Net.Core/Entities/Interactions/ApplicationCommandProperties.cs View File

@@ -20,7 +20,11 @@ namespace Discord
/// Gets or sets the discription of this command.
/// </summary>
public Optional<string> Description { get; set; }

/// <summary>
/// Gets or sets the type for this command.
/// </summary>
public Optional<ApplicationCommandType> Type { get; set; }

/// <summary>
/// Gets or sets the options for this command.


+ 15
- 0
src/Discord.Net.Core/Entities/Interactions/ApplicationCommandTypes.cs View File

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

namespace Discord
{
public enum ApplicationCommandType : byte
{
Slash = 1,
User = 2,
Message = 3
}
}

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

@@ -16,6 +16,11 @@ namespace Discord
/// </summary>
ulong ApplicationId { get; }

/// <summary>
/// The type of the command
/// </summary>
ApplicationCommandType Type { get; }

/// <summary>
/// The name of the command.
/// </summary>


+ 109
- 0
src/Discord.Net.Core/Entities/Interactions/MessageCommandBuilder.cs View File

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

namespace Discord
{
/// <summary>
/// A class used to build slash commands.
/// </summary>
public class MessageCommandBuilder
{
/// <summary>
/// Returns the maximun length a commands name allowed by Discord
/// </summary>
public const int MaxNameLength = 32;
/// <summary>
/// Returns the maximum length of a commands description allowed by Discord.
/// </summary>
public const int MaxDescriptionLength = 0;

/// <summary>
/// The name of this slash command.
/// </summary>
public string Name
{
get
{
return _name;
}
set
{
Preconditions.NotNullOrEmpty(value, nameof(Name));
Preconditions.AtLeast(value.Length, 3, nameof(Name));
Preconditions.AtMost(value.Length, MaxNameLength, nameof(Name));

// Discord updated the docs, this regex prevents special characters like @!$%(... etc,
// https://discord.com/developers/docs/interactions/slash-commands#applicationcommand
if (!Regex.IsMatch(value, @"^[\w -]{3,32}$"))
throw new ArgumentException("Command name cannot contain any special characters or whitespaces!");

_name = value;
}
}

/// <summary>
/// A 1-100 length description of this slash command
/// </summary>
public string Description
{
get
{
return _description;
}
set
{
Preconditions.Equals(value, "");

_description = value;
}
}

private string _name { get; set; }
private string _description { get; set; }

/// <summary>
/// Build the current builder into a <see cref="MessageCommandCreationProperties"/> class.
/// </summary>
/// <returns>A <see cref="MessageCommandCreationProperties"/> that can be used to create user commands over rest.</returns>
public MessageCommandCreationProperties Build()
{
MessageCommandCreationProperties props = new MessageCommandCreationProperties()
{
Name = this.Name,
Description = this.Description,
Type=ApplicationCommandType.Message
};

return props;

}

/// <summary>
/// Sets the field name.
/// </summary>
/// <param name="name">The value to set the field name to.</param>
/// <returns>
/// The current builder.
/// </returns>
public MessageCommandBuilder WithName(string name)
{
this.Name = name;
return this;
}

/// <summary>
/// Sets the description of the current command.
/// </summary>
/// <param name="description">The description of this command.</param>
/// <returns>The current builder.</returns>
public MessageCommandBuilder WithDescription(string description)
{
this.Description = description;
return this;
}
}
}

+ 30
- 0
src/Discord.Net.Core/Entities/Interactions/MessageCommandCreationProperties.cs View File

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

namespace Discord
{
/// <summary>
/// A class used to create Message commands.
/// </summary>
public class MessageCommandCreationProperties
{
/// <summary>
/// The name of this command.
/// </summary>
public string Name { get; set; }

/// <summary>
/// The discription of this command.
/// </summary>
public string Description { get; set; }


/// <summary>
/// Gets or sets the type for this command.
/// </summary>
public ApplicationCommandType Type { get; set; }
}
}

+ 2
- 1
src/Discord.Net.Core/Entities/Interactions/SlashCommandBuilder.cs View File

@@ -102,7 +102,8 @@ namespace Discord
{
Name = this.Name,
Description = this.Description,
DefaultPermission = this.DefaultPermission
DefaultPermission = this.DefaultPermission,
Type = ApplicationCommandType.Slash
};

if (this.Options != null && this.Options.Any())


+ 4
- 0
src/Discord.Net.Core/Entities/Interactions/SlashCommandCreationProperties.cs View File

@@ -21,6 +21,10 @@ namespace Discord
/// </summary>
public string Description { get; set; }

/// <summary>
/// Gets or sets the type for this command.
/// </summary>
public ApplicationCommandType Type { get; set; }

/// <summary>
/// Gets or sets the options for this command.


+ 109
- 0
src/Discord.Net.Core/Entities/Interactions/UserCommandBuilder.cs View File

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

namespace Discord
{
/// <summary>
/// A class used to build slash commands.
/// </summary>
public class UserCommandBuilder
{
/// <summary>
/// Returns the maximun length a commands name allowed by Discord
/// </summary>
public const int MaxNameLength = 32;
/// <summary>
/// Returns the maximum length of a commands description allowed by Discord.
/// </summary>
public const int MaxDescriptionLength = 0;

/// <summary>
/// The name of this slash command.
/// </summary>
public string Name
{
get
{
return _name;
}
set
{
Preconditions.NotNullOrEmpty(value, nameof(Name));
Preconditions.AtLeast(value.Length, 3, nameof(Name));
Preconditions.AtMost(value.Length, MaxNameLength, nameof(Name));

// Discord updated the docs, this regex prevents special characters like @!$%(... etc,
// https://discord.com/developers/docs/interactions/slash-commands#applicationcommand
if (!Regex.IsMatch(value, @"^[\w -]{3,32}$"))
throw new ArgumentException("Command name cannot contain any special characters or whitespaces!");

_name = value;
}
}

/// <summary>
/// A 1-100 length description of this slash command
/// </summary>
public string Description
{
get
{
return _description;
}
set
{
Preconditions.Equals(value, "");

_description = value;
}
}

private string _name { get; set; }
private string _description { get; set; }

/// <summary>
/// Build the current builder into a <see cref="UserCommandCreationProperties"/> class.
/// </summary>
/// <returns>A <see cref="UserCommandCreationProperties"/> that can be used to create user commands over rest.</returns>
public UserCommandCreationProperties Build()
{
UserCommandCreationProperties props = new UserCommandCreationProperties()
{
Name = this.Name,
Description = this.Description,
Type=ApplicationCommandType.User
};

return props;

}

/// <summary>
/// Sets the field name.
/// </summary>
/// <param name="name">The value to set the field name to.</param>
/// <returns>
/// The current builder.
/// </returns>
public UserCommandBuilder WithName(string name)
{
this.Name = name;
return this;
}

/// <summary>
/// Sets the description of the current command.
/// </summary>
/// <param name="description">The description of this command.</param>
/// <returns>The current builder.</returns>
public UserCommandBuilder WithDescription(string description)
{
this.Description = description;
return this;
}
}
}

+ 30
- 0
src/Discord.Net.Core/Entities/Interactions/UserCommandCreationProperties.cs View File

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

namespace Discord
{
/// <summary>
/// A class used to create User commands.
/// </summary>
public class UserCommandCreationProperties
{
/// <summary>
/// The name of this command.
/// </summary>
public string Name { get; set; }

/// <summary>
/// The discription of this command.
/// </summary>
public string Description { get; set; }


/// <summary>
/// Gets or sets the type for this command.
/// </summary>
public ApplicationCommandType Type { get; set; }
}
}

+ 5
- 1
src/Discord.Net.Rest/API/Rest/CreateApplicationCommandParams.cs View File

@@ -13,6 +13,9 @@ namespace Discord.API.Rest
[JsonProperty("name")]
public string Name { get; set; }

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

[JsonProperty("description")]
public string Description { get; set; }

@@ -23,11 +26,12 @@ namespace Discord.API.Rest
public Optional<bool> DefaultPermission { get; set; }

public CreateApplicationCommandParams() { }
public CreateApplicationCommandParams(string name, string description, ApplicationCommandOption[] options = null)
public CreateApplicationCommandParams(string name, string description, ApplicationCommandType type, ApplicationCommandOption[] options = null)
{
this.Name = name;
this.Description = description;
this.Options = Optional.Create<ApplicationCommandOption[]>(options);
this.Type = type;
}
}
}

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

@@ -15,6 +15,9 @@ namespace Discord.API.Rest
[JsonProperty("description")]
public Optional<string> Description { get; set; }

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

[JsonProperty("options")]
public Optional<ApplicationCommandOption[]> Options { get; set; }



+ 97
- 0
src/Discord.Net.Rest/Discord.Net.Rest.xml View File

@@ -3732,6 +3732,9 @@
<member name="P:Discord.Rest.RestApplicationCommand.ApplicationId">
<inheritdoc/>
</member>
<member name="P:Discord.Rest.RestApplicationCommand.Type">
<inheritdoc/>
</member>
<member name="P:Discord.Rest.RestApplicationCommand.Name">
<inheritdoc/>
</member>
@@ -3831,6 +3834,32 @@
The modified command.
</returns>
</member>
<member name="M:Discord.Rest.RestGlobalMessageCommand.DeleteAsync(Discord.RequestOptions)">
<inheritdoc/>
</member>
<member name="M:Discord.Rest.RestGlobalMessageCommand.ModifyAsync(System.Action{Discord.ApplicationCommandProperties},Discord.RequestOptions)">
<summary>
Modifies this <see cref="T:Discord.Rest.RestApplicationCommand"/>.
</summary>
<param name="func">The delegate containing the properties to modify the command with.</param>
<param name="options">The options to be used when sending the request.</param>
<returns>
The modified command.
</returns>
</member>
<member name="M:Discord.Rest.RestGlobalUserCommand.DeleteAsync(Discord.RequestOptions)">
<inheritdoc/>
</member>
<member name="M:Discord.Rest.RestGlobalUserCommand.ModifyAsync(System.Action{Discord.ApplicationCommandProperties},Discord.RequestOptions)">
<summary>
Modifies this <see cref="T:Discord.Rest.RestApplicationCommand"/>.
</summary>
<param name="func">The delegate containing the properties to modify the command with.</param>
<param name="options">The options to be used when sending the request.</param>
<returns>
The modified command.
</returns>
</member>
<member name="T:Discord.Rest.RestGuildCommand">
<summary>
Represents a Rest-based guild command.
@@ -3886,6 +3915,74 @@
<see cref="T:Discord.Rest.RestGuild"/>.
</returns>
</member>
<member name="T:Discord.Rest.RestGuildMessageCommand">
<summary>
Represents a Rest-based guild command.
</summary>
</member>
<member name="P:Discord.Rest.RestGuildMessageCommand.GuildId">
<summary>
The guild Id where this command originates.
</summary>
</member>
<member name="M:Discord.Rest.RestGuildMessageCommand.DeleteAsync(Discord.RequestOptions)">
<inheritdoc/>
</member>
<member name="M:Discord.Rest.RestGuildMessageCommand.ModifyAsync(System.Action{Discord.ApplicationCommandProperties},Discord.RequestOptions)">
<summary>
Modifies this <see cref="T:Discord.Rest.RestApplicationCommand"/>.
</summary>
<param name="func">The delegate containing the properties to modify the command with.</param>
<param name="options">The options to be used when sending the request.</param>
<returns>
The modified command
</returns>
</member>
<member name="M:Discord.Rest.RestGuildMessageCommand.GetGuild(System.Boolean,Discord.RequestOptions)">
<summary>
Gets the guild that this slash command resides in.
</summary>
<param name="withCounts"><see langword="true"/> if you want the approximate member and presence counts for the guild, otherwise <see langword="false"/>.</param>
<param name="options">The options to be used when sending the request.</param>
<returns>
A task that represents the asynchronous get operation. The task result contains a
<see cref="T:Discord.Rest.RestGuild"/>.
</returns>
</member>
<member name="T:Discord.Rest.RestGuildUserCommand">
<summary>
Represents a Rest-based guild command.
</summary>
</member>
<member name="P:Discord.Rest.RestGuildUserCommand.GuildId">
<summary>
The guild Id where this command originates.
</summary>
</member>
<member name="M:Discord.Rest.RestGuildUserCommand.DeleteAsync(Discord.RequestOptions)">
<inheritdoc/>
</member>
<member name="M:Discord.Rest.RestGuildUserCommand.ModifyAsync(System.Action{Discord.ApplicationCommandProperties},Discord.RequestOptions)">
<summary>
Modifies this <see cref="T:Discord.Rest.RestApplicationCommand"/>.
</summary>
<param name="func">The delegate containing the properties to modify the command with.</param>
<param name="options">The options to be used when sending the request.</param>
<returns>
The modified command
</returns>
</member>
<member name="M:Discord.Rest.RestGuildUserCommand.GetGuild(System.Boolean,Discord.RequestOptions)">
<summary>
Gets the guild that this slash command resides in.
</summary>
<param name="withCounts"><see langword="true"/> if you want the approximate member and presence counts for the guild, otherwise <see langword="false"/>.</param>
<param name="options">The options to be used when sending the request.</param>
<returns>
A task that represents the asynchronous get operation. The task result contains a
<see cref="T:Discord.Rest.RestGuild"/>.
</returns>
</member>
<member name="P:Discord.Rest.RestInvite.ChannelName">
<inheritdoc />
</member>


+ 134
- 0
src/Discord.Net.Rest/DiscordRestApiClient.cs View File

@@ -235,6 +235,7 @@ namespace Discord.API
options.BucketId = bucketId;

string json = payload != null ? SerializeJson(payload) : null;
Console.WriteLine($"Sending JSON....\n{json}");
var request = new JsonRestRequest(RestClient, method, endpoint, json, options);
return DeserializeJson<TResponse>(await SendInternalAsync(method, endpoint, request).ConfigureAwait(false));
}
@@ -1082,6 +1083,18 @@ namespace Discord.API

return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
}
public async Task<ApplicationCommand> ModifyGlobalApplicationUserCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);

return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
}
public async Task<ApplicationCommand> ModifyGlobalApplicationMessageCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);

return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
}
public async Task DeleteGlobalApplicationCommandAsync(ulong commandId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
@@ -1095,6 +1108,46 @@ namespace Discord.API

return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/commands", commands, new BucketIds(), options: options)).ConfigureAwait(false);
}
public async Task<ApplicationCommand> CreateGlobalApplicationUserCommandAsync(CreateApplicationCommandParams command, RequestOptions options = null)
{
Preconditions.NotNull(command, nameof(command));
Preconditions.AtMost(command.Name.Length, 32, nameof(command.Name));
Preconditions.AtLeast(command.Name.Length, 3, nameof(command.Name));
Preconditions.Equals(command.Description, "");

options = RequestOptions.CreateOrClone(options);


return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/commands", command, new BucketIds(), options: options)).ConfigureAwait(false);
}
public async Task<ApplicationCommand> CreateGlobalApplicationMessageCommandAsync(CreateApplicationCommandParams command, RequestOptions options = null)
{
Preconditions.NotNull(command, nameof(command));
Preconditions.AtMost(command.Name.Length, 32, nameof(command.Name));
Preconditions.AtLeast(command.Name.Length, 3, nameof(command.Name));
Preconditions.Equals(command.Description, "");

options = RequestOptions.CreateOrClone(options);



return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/commands", command, new BucketIds(), options: options)).ConfigureAwait(false);
}

public async Task<ApplicationCommand[]> BulkOverwriteGlobalApplicationUserCommands(CreateApplicationCommandParams[] commands, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);

return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/commands", commands, new BucketIds(), options: options)).ConfigureAwait(false);
}

public async Task<ApplicationCommand[]> BulkOverwriteGlobalApplicationMessageCommands(CreateApplicationCommandParams[] commands, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);

return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/commands", commands, new BucketIds(), options: options)).ConfigureAwait(false);
}

public async Task<ApplicationCommand[]> GetGuildApplicationCommandsAsync(ulong guildId, RequestOptions options = null)
{
@@ -1163,6 +1216,87 @@ namespace Discord.API
return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", commands, bucket, options: options)).ConfigureAwait(false);
}

public async Task<ApplicationCommand> CreateGuildApplicationUserCommandAsync(CreateApplicationCommandParams command, ulong guildId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);

var bucket = new BucketIds(guildId: guildId);

return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", command, bucket, options: options)).ConfigureAwait(false);

}
public async Task<ApplicationCommand> ModifyGuildApplicationUserCommandAsync(ModifyApplicationCommandParams command, ulong guildId, ulong commandId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);

var bucket = new BucketIds(guildId: guildId);

try
{
return await SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", command, bucket, options: options).ConfigureAwait(false);
}
catch (HttpException x)
{
if (x.HttpCode == HttpStatusCode.BadRequest)
{
var json = (x.Request as JsonRestRequest).Json;
throw new ApplicationCommandException(json, x);
}

// Re-throw the http exception
throw;
}
}
public async Task<ApplicationCommand[]> BulkOverwriteGuildApplicationUserCommands(ulong guildId, CreateApplicationCommandParams[] commands, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);

var bucket = new BucketIds(guildId: guildId);

return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", commands, bucket, options: options)).ConfigureAwait(false);
}

public async Task<ApplicationCommand> CreateGuildApplicationMessageCommandAsync(CreateApplicationCommandParams command, ulong guildId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);

var bucket = new BucketIds(guildId: guildId);

return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", command, bucket, options: options)).ConfigureAwait(false);

}
public async Task<ApplicationCommand> ModifyGuildApplicationMessageCommandAsync(ModifyApplicationCommandParams command, ulong guildId, ulong commandId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);

var bucket = new BucketIds(guildId: guildId);

try
{
return await SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", command, bucket, options: options).ConfigureAwait(false);
}
catch (HttpException x)
{
if (x.HttpCode == HttpStatusCode.BadRequest)
{
var json = (x.Request as JsonRestRequest).Json;
throw new ApplicationCommandException(json, x);
}

// Re-throw the http exception
throw;
}
}

public async Task<ApplicationCommand[]> BulkOverwriteGuildApplicationMessageCommands(ulong guildId, CreateApplicationCommandParams[] commands, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);

var bucket = new BucketIds(guildId: guildId);

return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", commands, bucket, options: options)).ConfigureAwait(false);
}

//Interaction Responses
public async Task CreateInteractionResponse(InteractionResponse response, ulong interactionId, string interactionToken, RequestOptions options = null)
{


+ 17
- 0
src/Discord.Net.Rest/DiscordRestClient.cs View File

@@ -1,3 +1,4 @@
//using Discord.Rest.Entities.Interactions;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
@@ -111,10 +112,26 @@ namespace Discord.Rest
=> InteractionHelper.CreateGlobalCommand(this, properties, options);
public Task<RestGlobalCommand> CreateGlobalCommand(Action<SlashCommandCreationProperties> func, RequestOptions options = null)
=> InteractionHelper.CreateGlobalCommand(this, func, options);
public Task<RestGlobalUserCommand> CreateGlobalUserCommand(UserCommandCreationProperties properties, RequestOptions options = null)
=> InteractionHelper.CreateGlobalUserCommand(this, properties, options);
public Task<RestGlobalUserCommand> CreateGlobalUserCommand(Action<UserCommandCreationProperties> func, RequestOptions options = null)
=> InteractionHelper.CreateGlobalUserCommand(this, func, options);
public Task<RestGlobalMessageCommand> CreateGlobalMessageCommand(MessageCommandCreationProperties properties, RequestOptions options = null)
=> InteractionHelper.CreateGlobalMessageCommand(this, properties, options);
public Task<RestGlobalMessageCommand> CreateGlobalMessageCommand(Action<MessageCommandCreationProperties> func, RequestOptions options = null)
=> InteractionHelper.CreateGlobalMessageCommand(this, func, options);
public Task<RestGuildCommand> CreateGuildCommand(SlashCommandCreationProperties properties, ulong guildId, RequestOptions options = null)
=> InteractionHelper.CreateGuildCommand(this, guildId, properties, options);
public Task<RestGuildCommand> CreateGuildCommand(Action<SlashCommandCreationProperties> func, ulong guildId, RequestOptions options = null)
=> InteractionHelper.CreateGuildCommand(this, guildId, func, options);
public Task<RestGuildUserCommand> CreateGuildUserCommand(UserCommandCreationProperties properties, ulong guildId, RequestOptions options = null)
=> InteractionHelper.CreateGuildUserCommand(this, guildId, properties, options);
public Task<RestGuildUserCommand> CreateGuildUserCommand(Action<UserCommandCreationProperties> func, ulong guildId, RequestOptions options = null)
=> InteractionHelper.CreateGuildUserCommand(this, guildId, func, options);
public Task<RestGuildMessageCommand> CreateGuildMessageCommand(MessageCommandCreationProperties properties, ulong guildId, RequestOptions options = null)
=> InteractionHelper.CreateGuildMessageCommand(this, guildId, properties, options);
public Task<RestGuildMessageCommand> CreateGuildMessageCommand(Action<MessageCommandCreationProperties> func, ulong guildId, RequestOptions options = null)
=> InteractionHelper.CreateGuildMessageCommand(this, guildId, func, options);
public Task<IReadOnlyCollection<RestGlobalCommand>> GetGlobalApplicationCommands(RequestOptions options = null)
=> ClientHelper.GetGlobalApplicationCommands(this, options);
public Task<IReadOnlyCollection<RestGuildCommand>> GetGuildApplicationCommands(ulong guildId, RequestOptions options = null)


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

@@ -1,6 +1,7 @@
using Discord.API;
using Discord.API.Rest;
using Discord.Net;
//using Discord.Rest.Entities.Interactions;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -63,6 +64,7 @@ namespace Discord.Rest
{
Name = arg.Name,
Description = arg.Description,
Type= arg.Type,
Options = arg.Options.IsSpecified
? arg.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray()
: Optional<Discord.API.ApplicationCommandOption[]>.Unspecified,
@@ -94,6 +96,7 @@ namespace Discord.Rest
{
Name = arg.Name,
Description = arg.Description,
Type = arg.Type,
Options = arg.Options.IsSpecified
? arg.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray()
: Optional<Discord.API.ApplicationCommandOption[]>.Unspecified,
@@ -129,6 +132,7 @@ namespace Discord.Rest
{
Name = arg.Name,
Description = arg.Description,
Type = arg.Type,
Options = arg.Options.IsSpecified
? arg.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray()
: Optional<Discord.API.ApplicationCommandOption[]>.Unspecified,
@@ -173,6 +177,7 @@ namespace Discord.Rest
{
Name = args.Name,
Description = args.Description,
Type = args.Type,
Options = args.Options.IsSpecified
? args.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray()
: Optional<Discord.API.ApplicationCommandOption[]>.Unspecified,
@@ -195,6 +200,174 @@ namespace Discord.Rest
await client.ApiClient.DeleteGlobalApplicationCommandAsync(command.Id, options).ConfigureAwait(false);
}

public static async Task<RestGlobalUserCommand> CreateGlobalUserCommand(BaseDiscordClient client, Action<UserCommandCreationProperties> func, RequestOptions options = null)
{
var args = new UserCommandCreationProperties();
func(args);
return await CreateGlobalUserCommand(client, args, options).ConfigureAwait(false);
}

public static async Task<RestGlobalUserCommand> CreateGlobalUserCommand(BaseDiscordClient client, UserCommandCreationProperties arg, RequestOptions options = null)
{
Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name));
Preconditions.Equals(arg.Description, "");

var model = new CreateApplicationCommandParams()
{
Name = arg.Name,
Description = arg.Description,
Type = arg.Type
};

var cmd = await client.ApiClient.CreateGlobalApplicationUserCommandAsync(model, options).ConfigureAwait(false);
return RestGlobalUserCommand.Create(client, cmd);
}

public static async Task<RestGlobalMessageCommand> CreateGlobalMessageCommand(BaseDiscordClient client, Action<MessageCommandCreationProperties> func, RequestOptions options = null)
{
var args = new MessageCommandCreationProperties();
func(args);
return await CreateGlobalMessageCommand(client, args, options).ConfigureAwait(false);
}

public static async Task<RestGlobalMessageCommand> CreateGlobalMessageCommand(BaseDiscordClient client, MessageCommandCreationProperties arg, RequestOptions options = null)
{
Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name));
Preconditions.Equals(arg.Description, "");

var model = new CreateApplicationCommandParams()
{
Name = arg.Name,
Description = arg.Description,
Type = arg.Type
};

var cmd = await client.ApiClient.CreateGlobalApplicationMessageCommandAsync(model, options).ConfigureAwait(false);
return RestGlobalMessageCommand.Create(client, cmd);
}

public static async Task<IReadOnlyCollection<RestGlobalUserCommand>> BulkOverwriteGlobalUserCommands(BaseDiscordClient client, UserCommandCreationProperties[] args, RequestOptions options = null)
{
Preconditions.NotNull(args, nameof(args));

List<CreateApplicationCommandParams> models = new List<CreateApplicationCommandParams>();

foreach (var arg in args)
{
Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name));
Preconditions.NotNullOrEmpty(arg.Description, nameof(arg.Description));
Preconditions.Equals(arg.Type, ApplicationCommandType.User);

var model = new CreateApplicationCommandParams()
{
Name = arg.Name,
Description = arg.Description,
Type = arg.Type
};

models.Add(model);
}

var apiModels = await client.ApiClient.BulkOverwriteGlobalApplicationUserCommands(models.ToArray(), options);

return apiModels.Select(x => RestGlobalUserCommand.Create(client, x)).ToArray();
}
public static async Task<RestGlobalUserCommand> ModifyGlobalUserCommand(BaseDiscordClient client, RestGlobalUserCommand command,
Action<ApplicationCommandProperties> func, RequestOptions options = null)
{
ApplicationCommandProperties args = new ApplicationCommandProperties();
func(args);

if (args.Name.IsSpecified)
{
Preconditions.AtMost(args.Name.Value.Length, 32, nameof(args.Name));
Preconditions.AtLeast(args.Name.Value.Length, 3, nameof(args.Name));
}
if (args.Description.IsSpecified)
{
Preconditions.Equals(args.Description.Value, "");
}

var model = new Discord.API.Rest.ModifyApplicationCommandParams()
{
Name = args.Name,
Description = args.Description
};

var msg = await client.ApiClient.ModifyGlobalApplicationUserCommandAsync(model, command.Id, options).ConfigureAwait(false);
command.Update(msg);
return command;
}

public static async Task DeleteGlobalUserCommand(BaseDiscordClient client, RestGlobalUserCommand command, RequestOptions options = null)
{
Preconditions.NotNull(command, nameof(command));
Preconditions.NotEqual(command.Id, 0, nameof(command.Id));

await client.ApiClient.DeleteGlobalApplicationCommandAsync(command.Id, options).ConfigureAwait(false);
}

public static async Task<IReadOnlyCollection<RestGlobalMessageCommand>> BulkOverwriteGlobalMessageCommands(BaseDiscordClient client, MessageCommandCreationProperties[] args, RequestOptions options = null)
{
Preconditions.NotNull(args, nameof(args));

List<CreateApplicationCommandParams> models = new List<CreateApplicationCommandParams>();

foreach (var arg in args)
{
Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name));
Preconditions.NotNullOrEmpty(arg.Description, nameof(arg.Description));
Preconditions.Equals(arg.Type, ApplicationCommandType.Message);

var model = new CreateApplicationCommandParams()
{
Name = arg.Name,
Description = arg.Description,
Type = arg.Type
};

models.Add(model);
}

var apiModels = await client.ApiClient.BulkOverwriteGlobalApplicationMessageCommands(models.ToArray(), options);

return apiModels.Select(x => RestGlobalMessageCommand.Create(client, x)).ToArray();
}
public static async Task<RestGlobalMessageCommand> ModifyGlobalMessageCommand(BaseDiscordClient client, RestGlobalMessageCommand command,
Action<ApplicationCommandProperties> func, RequestOptions options = null)
{
ApplicationCommandProperties args = new ApplicationCommandProperties();
func(args);

if (args.Name.IsSpecified)
{
Preconditions.AtMost(args.Name.Value.Length, 32, nameof(args.Name));
Preconditions.AtLeast(args.Name.Value.Length, 3, nameof(args.Name));
}
if (args.Description.IsSpecified)
{
Preconditions.Equals(args.Description.Value, "");
}

var model = new Discord.API.Rest.ModifyApplicationCommandParams()
{
Name = args.Name,
Description = args.Description
};

var msg = await client.ApiClient.ModifyGlobalApplicationMessageCommandAsync(model, command.Id, options).ConfigureAwait(false);
command.Update(msg);
return command;
}

public static async Task DeleteGlobalMessageCommand(BaseDiscordClient client, RestGlobalMessageCommand command, RequestOptions options = null)
{
Preconditions.NotNull(command, nameof(command));
Preconditions.NotEqual(command.Id, 0, nameof(command.Id));

await client.ApiClient.DeleteGlobalApplicationCommandAsync(command.Id, options).ConfigureAwait(false);
}

// Guild Commands
public static async Task<RestGuildCommand> CreateGuildCommand(BaseDiscordClient client, ulong guildId,
Action<SlashCommandCreationProperties> func, RequestOptions options = null)
@@ -231,6 +404,7 @@ namespace Discord.Rest
{
Name = args.Name,
Description = args.Description,
Type = args.Type,
Options = args.Options.IsSpecified
? args.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray()
: Optional<Discord.API.ApplicationCommandOption[]>.Unspecified,
@@ -269,6 +443,7 @@ namespace Discord.Rest
{
Name = args.Name,
Description = args.Description,
Type = args.Type,
Options = args.Options.IsSpecified
? args.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray()
: Optional<Discord.API.ApplicationCommandOption[]>.Unspecified,
@@ -290,6 +465,177 @@ namespace Discord.Rest
await client.ApiClient.DeleteGuildApplicationCommandAsync(guildId, command.Id, options).ConfigureAwait(false);
}

public static async Task<RestGuildUserCommand> CreateGuildUserCommand(BaseDiscordClient client, ulong guildId, Action<UserCommandCreationProperties> func, RequestOptions options = null)
{
var args = new UserCommandCreationProperties();
func(args);
return await CreateGuildUserCommand(client, guildId, args, options).ConfigureAwait(false);
}

public static async Task<RestGuildUserCommand> CreateGuildUserCommand(BaseDiscordClient client, ulong guildId, UserCommandCreationProperties arg, RequestOptions options = null)
{
Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name));
Preconditions.Equals(arg.Description, "");

var model = new CreateApplicationCommandParams()
{
Name = arg.Name,
Description = arg.Description,
Type = arg.Type
};

var cmd = await client.ApiClient.CreateGuildApplicationUserCommandAsync(model, guildId, options).ConfigureAwait(false);
return RestGuildUserCommand.Create(client, cmd, guildId);
}

public static async Task<RestGuildMessageCommand> CreateGuildMessageCommand(BaseDiscordClient client, ulong guildId, Action<MessageCommandCreationProperties> func, RequestOptions options = null)
{
var args = new MessageCommandCreationProperties();
func(args);
return await CreateGuildMessageCommand(client, guildId, args, options).ConfigureAwait(false);
}

public static async Task<RestGuildMessageCommand> CreateGuildMessageCommand(BaseDiscordClient client, ulong guildId, MessageCommandCreationProperties arg, RequestOptions options = null)
{
Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name));
Preconditions.Equals(arg.Description, "");

var model = new CreateApplicationCommandParams()
{
Name = arg.Name,
Description = arg.Description,
Type = arg.Type
};

var cmd = await client.ApiClient.CreateGuildApplicationMessageCommandAsync(model, guildId, options).ConfigureAwait(false);
return RestGuildMessageCommand.Create(client, cmd, guildId);
}

public static async Task<IReadOnlyCollection<RestGuildUserCommand>> BulkOverwriteGuildUserCommands(BaseDiscordClient client, ulong guildId, UserCommandCreationProperties[] args, RequestOptions options = null)
{
Preconditions.NotNull(args, nameof(args));

List<CreateApplicationCommandParams> models = new List<CreateApplicationCommandParams>();

foreach (var arg in args)
{
Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name));
Preconditions.NotNullOrEmpty(arg.Description, nameof(arg.Description));
Preconditions.Equals(arg.Type, ApplicationCommandType.User);

var model = new CreateApplicationCommandParams()
{
Name = arg.Name,
Description = arg.Description,
Type = arg.Type
};

models.Add(model);
}

var apiModels = await client.ApiClient.BulkOverwriteGuildApplicationUserCommands(guildId, models.ToArray(), options);

return apiModels.Select(x => RestGuildUserCommand.Create(client, x, guildId)).ToArray();
}
public static async Task<RestGuildUserCommand> ModifyGuildUserCommand(BaseDiscordClient client, RestGuildUserCommand command,
Action<ApplicationCommandProperties> func, RequestOptions options = null)
{
ApplicationCommandProperties args = new ApplicationCommandProperties();
func(args);

if (args.Name.IsSpecified)
{
Preconditions.AtMost(args.Name.Value.Length, 32, nameof(args.Name));
Preconditions.AtLeast(args.Name.Value.Length, 3, nameof(args.Name));
}
if (args.Description.IsSpecified)
{
Preconditions.Equals(args.Description.Value, "");
}

var model = new Discord.API.Rest.ModifyApplicationCommandParams()
{
Name = args.Name,
Description = args.Description,
Type=args.Type
};

var msg = await client.ApiClient.ModifyGuildApplicationUserCommandAsync(model, command.GuildId, command.Id, options).ConfigureAwait(false);
command.Update(msg);
return command;
}

public static async Task DeleteGuildUserCommand(BaseDiscordClient client, ulong guildId, RestGuildUserCommand command, RequestOptions options = null)
{
Preconditions.NotNull(command, nameof(command));
Preconditions.NotEqual(command.Id, 0, nameof(command.Id));

await client.ApiClient.DeleteGuildApplicationCommandAsync(guildId, command.Id, options).ConfigureAwait(false);
}

public static async Task<IReadOnlyCollection<RestGuildMessageCommand>> BulkOverwriteGuildMessageCommands(BaseDiscordClient client, ulong guildId, MessageCommandCreationProperties[] args, RequestOptions options = null)
{
Preconditions.NotNull(args, nameof(args));

List<CreateApplicationCommandParams> models = new List<CreateApplicationCommandParams>();

foreach (var arg in args)
{
Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name));
Preconditions.NotNullOrEmpty(arg.Description, nameof(arg.Description));
Preconditions.Equals(arg.Type, ApplicationCommandType.Message);

var model = new CreateApplicationCommandParams()
{
Name = arg.Name,
Description = arg.Description,
Type = arg.Type
};

models.Add(model);
}

var apiModels = await client.ApiClient.BulkOverwriteGuildApplicationMessageCommands(guildId, models.ToArray(), options);

return apiModels.Select(x => RestGuildMessageCommand.Create(client, x, guildId)).ToArray();
}
public static async Task<RestGuildMessageCommand> ModifyGuildMessageCommand(BaseDiscordClient client, RestGuildMessageCommand command,
Action<ApplicationCommandProperties> func, RequestOptions options = null)
{
ApplicationCommandProperties args = new ApplicationCommandProperties();
func(args);

if (args.Name.IsSpecified)
{
Preconditions.AtMost(args.Name.Value.Length, 32, nameof(args.Name));
Preconditions.AtLeast(args.Name.Value.Length, 3, nameof(args.Name));
}
if (args.Description.IsSpecified)
{
Preconditions.Equals(args.Description.Value, "");
}

var model = new Discord.API.Rest.ModifyApplicationCommandParams()
{
Name = args.Name,
Description = args.Description,
Type = args.Type
};

var msg = await client.ApiClient.ModifyGuildApplicationMessageCommandAsync(model, command.GuildId, command.Id, options).ConfigureAwait(false);
command.Update(msg);
return command;
}

public static async Task DeleteGuildMessageCommand(BaseDiscordClient client, ulong guildId, RestGuildMessageCommand command, RequestOptions options = null)
{
Preconditions.NotNull(command, nameof(command));
Preconditions.NotEqual(command.Id, 0, nameof(command.Id));

await client.ApiClient.DeleteGuildApplicationCommandAsync(guildId, command.Id, options).ConfigureAwait(false);
}


public static async Task<Discord.API.Message> ModifyFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, Action<MessageProperties> func,
RequestOptions options = null)
{


+ 27
- 7
src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommand.cs View File

@@ -16,6 +16,9 @@ namespace Discord.Rest
/// <inheritdoc/>
public ulong ApplicationId { get; private set; }

/// <inheritdoc/>
public ApplicationCommandType Type { get; private set; }

/// <inheritdoc/>
public string Name { get; private set; }

@@ -47,13 +50,30 @@ namespace Discord.Rest

internal static RestApplicationCommand Create(BaseDiscordClient client, Model model, RestApplicationCommandType type, ulong guildId = 0)
{
if (type == RestApplicationCommandType.GlobalCommand)
return RestGlobalCommand.Create(client, model);

if (type == RestApplicationCommandType.GuildCommand)
return RestGuildCommand.Create(client, model, guildId);

return null;
switch (type)
{
case RestApplicationCommandType.GlobalCommand:
return RestGlobalCommand.Create(client, model);
break;
case RestApplicationCommandType.GlobalUserCommand:
return RestGlobalUserCommand.Create(client, model);
break;
case RestApplicationCommandType.GlobalMessageCommand:
return RestGlobalMessageCommand.Create(client, model);
break;
case RestApplicationCommandType.GuildCommand:
return RestGuildCommand.Create(client, model, guildId);
break;
case RestApplicationCommandType.GuildUserCommand:
return RestGuildUserCommand.Create(client, model, guildId);
break;
case RestApplicationCommandType.GuildMessageCommand:
return RestGuildMessageCommand.Create(client, model, guildId);
break;
default:
return null;
break;
}
}

internal virtual void Update(Model model)


+ 5
- 1
src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandType.cs View File

@@ -15,10 +15,14 @@ namespace Discord.Rest
/// Specifies that this command is a Global command.
/// </summary>
GlobalCommand,
GlobalUserCommand,
GlobalMessageCommand,

/// <summary>
/// Specifies that this command is a Guild specific command.
/// </summary>
GuildCommand
GuildCommand,
GuildUserCommand,
GuildMessageCommand
}
}

+ 41
- 0
src/Discord.Net.Rest/Entities/Interactions/RestGlobalMessageCommand.cs View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Model = Discord.API.ApplicationCommand;

namespace Discord.Rest
{
public class RestGlobalMessageCommand : RestApplicationCommand
{
internal RestGlobalMessageCommand(BaseDiscordClient client, ulong id)
: base(client, id)
{
this.CommandType = RestApplicationCommandType.GlobalMessageCommand;
}

internal static RestGlobalMessageCommand Create(BaseDiscordClient client, Model model)
{
var entity = new RestGlobalMessageCommand(client, model.Id);
entity.Update(model);
return entity;
}

/// <inheritdoc/>
public override async Task DeleteAsync(RequestOptions options = null)
=> await InteractionHelper.DeleteGlobalMessageCommand(Discord, this).ConfigureAwait(false);

/// <summary>
/// Modifies this <see cref="RestApplicationCommand"/>.
/// </summary>
/// <param name="func">The delegate containing the properties to modify the command with.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// The modified command.
/// </returns>
public async Task<RestGlobalMessageCommand> ModifyAsync(Action<ApplicationCommandProperties> func, RequestOptions options = null)
=> await InteractionHelper.ModifyGlobalMessageCommand(Discord, this, func, options).ConfigureAwait(false);
}
}

+ 41
- 0
src/Discord.Net.Rest/Entities/Interactions/RestGlobalUserCommand.cs View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Model = Discord.API.ApplicationCommand;

namespace Discord.Rest
{
public class RestGlobalUserCommand : RestApplicationCommand
{
internal RestGlobalUserCommand(BaseDiscordClient client, ulong id)
: base(client, id)
{
this.CommandType = RestApplicationCommandType.GlobalUserCommand;
}

internal static RestGlobalUserCommand Create(BaseDiscordClient client, Model model)
{
var entity = new RestGlobalUserCommand(client, model.Id);
entity.Update(model);
return entity;
}

/// <inheritdoc/>
public override async Task DeleteAsync(RequestOptions options = null)
=> await InteractionHelper.DeleteGlobalUserCommand(Discord, this).ConfigureAwait(false);

/// <summary>
/// Modifies this <see cref="RestApplicationCommand"/>.
/// </summary>
/// <param name="func">The delegate containing the properties to modify the command with.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// The modified command.
/// </returns>
public async Task<RestGlobalUserCommand> ModifyAsync(Action<ApplicationCommandProperties> func, RequestOptions options = null)
=> await InteractionHelper.ModifyGlobalUserCommand(Discord, this, func, options).ConfigureAwait(false);
}
}

+ 61
- 0
src/Discord.Net.Rest/Entities/Interactions/RestGuildMessageCommand.cs View File

@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model = Discord.API.ApplicationCommand;

namespace Discord.Rest
{
/// <summary>
/// Represents a Rest-based guild command.
/// </summary>
public class RestGuildMessageCommand : RestApplicationCommand
{
/// <summary>
/// The guild Id where this command originates.
/// </summary>
public ulong GuildId { get; private set; }

internal RestGuildMessageCommand(BaseDiscordClient client, ulong id, ulong guildId)
: base(client, id)
{
this.CommandType = RestApplicationCommandType.GuildMessageCommand;
this.GuildId = guildId;
}

internal static RestGuildMessageCommand Create(BaseDiscordClient client, Model model, ulong guildId)
{
var entity = new RestGuildMessageCommand(client, model.Id, guildId);
entity.Update(model);
return entity;
}

/// <inheritdoc/>
public override async Task DeleteAsync(RequestOptions options = null)
=> await InteractionHelper.DeleteGuildMessageCommand(Discord, GuildId, this).ConfigureAwait(false);

/// <summary>
/// Modifies this <see cref="RestApplicationCommand"/>.
/// </summary>
/// <param name="func">The delegate containing the properties to modify the command with.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// The modified command
/// </returns>
public async Task<RestGuildMessageCommand> ModifyAsync(Action<ApplicationCommandProperties> func, RequestOptions options = null)
=> await InteractionHelper.ModifyGuildMessageCommand(Discord, this, func, options).ConfigureAwait(false);

/// <summary>
/// Gets the guild that this slash command resides in.
/// </summary>
/// <param name="withCounts"><see langword="true"/> if you want the approximate member and presence counts for the guild, otherwise <see langword="false"/>.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous get operation. The task result contains a
/// <see cref="RestGuild"/>.
/// </returns>
public Task<RestGuild> GetGuild(bool withCounts = false, RequestOptions options = null)
=> ClientHelper.GetGuildAsync(this.Discord, this.GuildId, withCounts, options);
}
}

+ 61
- 0
src/Discord.Net.Rest/Entities/Interactions/RestGuildUserCommand.cs View File

@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model = Discord.API.ApplicationCommand;

namespace Discord.Rest
{
/// <summary>
/// Represents a Rest-based guild command.
/// </summary>
public class RestGuildUserCommand : RestApplicationCommand
{
/// <summary>
/// The guild Id where this command originates.
/// </summary>
public ulong GuildId { get; private set; }

internal RestGuildUserCommand(BaseDiscordClient client, ulong id, ulong guildId)
: base(client, id)
{
this.CommandType = RestApplicationCommandType.GuildUserCommand;
this.GuildId = guildId;
}

internal static RestGuildUserCommand Create(BaseDiscordClient client, Model model, ulong guildId)
{
var entity = new RestGuildUserCommand(client, model.Id, guildId);
entity.Update(model);
return entity;
}

/// <inheritdoc/>
public override async Task DeleteAsync(RequestOptions options = null)
=> await InteractionHelper.DeleteGuildUserCommand(Discord, GuildId, this).ConfigureAwait(false);

/// <summary>
/// Modifies this <see cref="RestApplicationCommand"/>.
/// </summary>
/// <param name="func">The delegate containing the properties to modify the command with.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// The modified command
/// </returns>
public async Task<RestGuildUserCommand> ModifyAsync(Action<ApplicationCommandProperties> func, RequestOptions options = null)
=> await InteractionHelper.ModifyGuildUserCommand(Discord, this, func, options).ConfigureAwait(false);

/// <summary>
/// Gets the guild that this slash command resides in.
/// </summary>
/// <param name="withCounts"><see langword="true"/> if you want the approximate member and presence counts for the guild, otherwise <see langword="false"/>.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous get operation. The task result contains a
/// <see cref="RestGuild"/>.
/// </returns>
public Task<RestGuild> GetGuild(bool withCounts = false, RequestOptions options = null)
=> ClientHelper.GetGuildAsync(this.Discord, this.GuildId, withCounts, options);
}
}

+ 3
- 0
src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml View File

@@ -3668,6 +3668,9 @@
<member name="P:Discord.WebSocket.SocketApplicationCommand.Name">
<inheritdoc/>
</member>
<member name="P:Discord.WebSocket.SocketApplicationCommand.Type">
<inheritdoc/>
</member>
<member name="P:Discord.WebSocket.SocketApplicationCommand.Description">
<inheritdoc/>
</member>


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

@@ -20,6 +20,9 @@ namespace Discord.WebSocket
/// <inheritdoc/>
public string Name { get; private set; }

/// <inheritdoc/>
public ApplicationCommandType Type { get; private set; }

/// <inheritdoc/>
public string Description { get; private set; }



Loading…
Cancel
Save