@@ -3967,11 +3967,6 @@ | |||
The base command model that belongs to an application. see <see href="https://discord.com/developers/docs/interactions/slash-commands#applicationcommand"/> | |||
</summary> | |||
</member> | |||
<member name="P:Discord.IApplicationCommand.Id"> | |||
<summary> | |||
Gets the unique id of the command. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.IApplicationCommand.ApplicationId"> | |||
<summary> | |||
Gets the unique id of the parent application. | |||
@@ -3987,6 +3982,11 @@ | |||
The description of the command. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.IApplicationCommand.DefaultPermission"> | |||
<summary> | |||
Whether the command is enabled by default when the app is added to a guild. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.IApplicationCommand.Options"> | |||
<summary> | |||
If the option is a subcommand or subcommand group type, this nested options will be the parameters. | |||
@@ -4886,6 +4886,11 @@ | |||
Gets or sets the options for this command. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.SlashCommandBuilder.DefaultPermission"> | |||
<summary> | |||
Whether the command is enabled by default when the app is added to a guild | |||
</summary> | |||
</member> | |||
<member name="M:Discord.SlashCommandBuilder.Build"> | |||
<summary> | |||
Build the current builder into a <see cref="T:Discord.SlashCommandCreationProperties"/> class. | |||
@@ -4908,6 +4913,13 @@ | |||
<param name="description">The description of this command.</param> | |||
<returns>The current builder.</returns> | |||
</member> | |||
<member name="M:Discord.SlashCommandBuilder.WithDefaultPermission(System.Boolean)"> | |||
<summary> | |||
Sets the default permission of the current command. | |||
</summary> | |||
<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[])"> | |||
<summary> | |||
Adds an option to the current slash command. | |||
@@ -7243,17 +7255,17 @@ | |||
Application command permissions allow you to enable or disable commands for specific users or roles within a guild. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.ApplicationCommandPermission.Id"> | |||
<member name="P:Discord.ApplicationCommandPermission.TargetId"> | |||
<summary> | |||
The id of the role or user. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.ApplicationCommandPermission.Type"> | |||
<member name="P:Discord.ApplicationCommandPermission.TargetType"> | |||
<summary> | |||
The target of this permission. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.ApplicationCommandPermission.Value"> | |||
<member name="P:Discord.ApplicationCommandPermission.Permission"> | |||
<summary> | |||
<see langword="true"/> to allow, otherwise <see langword="false"/>. | |||
</summary> | |||
@@ -7525,27 +7537,27 @@ | |||
<member name="M:Discord.ChannelPermissions.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})"> | |||
<summary> Creates a new <see cref="T:Discord.ChannelPermissions"/> from this one, changing the provided non-null permissions. </summary> | |||
</member> | |||
<member name="T:Discord.GuildApplicationCommandPermissions"> | |||
<member name="T:Discord.GuildApplicationCommandPermission"> | |||
<summary> | |||
Returned when fetching the permissions for a command in a guild. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.GuildApplicationCommandPermissions.Id"> | |||
<member name="P:Discord.GuildApplicationCommandPermission.CommandId"> | |||
<summary> | |||
The id of the command. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.GuildApplicationCommandPermissions.ApplicationId"> | |||
<member name="P:Discord.GuildApplicationCommandPermission.ApplicationId"> | |||
<summary> | |||
The id of the application the command belongs to. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.GuildApplicationCommandPermissions.GuildId"> | |||
<member name="P:Discord.GuildApplicationCommandPermission.GuildId"> | |||
<summary> | |||
The id of the guild. | |||
</summary> | |||
</member> | |||
<member name="P:Discord.GuildApplicationCommandPermissions.Permissions"> | |||
<member name="P:Discord.GuildApplicationCommandPermission.Permissions"> | |||
<summary> | |||
The permissions for the command in the guild. | |||
</summary> | |||
@@ -8,10 +8,10 @@ namespace Discord | |||
/// <summary> | |||
/// The target of the permission is a role. | |||
/// </summary> | |||
Role = 0, | |||
Role = 1, | |||
/// <summary> | |||
/// The target of the permission is a user. | |||
/// </summary> | |||
User = 1, | |||
User = 2, | |||
} | |||
} |
@@ -11,11 +11,6 @@ namespace Discord | |||
/// </summary> | |||
public interface IApplicationCommand : ISnowflakeEntity | |||
{ | |||
/// <summary> | |||
/// Gets the unique id of the command. | |||
/// </summary> | |||
ulong Id { get; } | |||
/// <summary> | |||
/// Gets the unique id of the parent application. | |||
/// </summary> | |||
@@ -31,6 +26,11 @@ namespace Discord | |||
/// </summary> | |||
string Description { get; } | |||
/// <summary> | |||
/// Whether the command is enabled by default when the app is added to a guild. | |||
/// </summary> | |||
bool DefaultPermission { get; } | |||
/// <summary> | |||
/// If the option is a subcommand or subcommand group type, this nested options will be the parameters. | |||
/// </summary> | |||
@@ -82,6 +82,12 @@ namespace Discord | |||
_options = value; | |||
} | |||
} | |||
/// <summary> | |||
/// Whether the command is enabled by default when the app is added to a guild | |||
/// </summary> | |||
public bool DefaultPermission { get; set; } = true; | |||
private string _name { get; set; } | |||
private string _description { get; set; } | |||
private List<SlashCommandOptionBuilder> _options { get; set; } | |||
@@ -96,6 +102,7 @@ namespace Discord | |||
{ | |||
Name = this.Name, | |||
Description = this.Description, | |||
DefaultPermission = this.DefaultPermission | |||
}; | |||
if (this.Options != null && this.Options.Any()) | |||
@@ -135,6 +142,17 @@ namespace Discord | |||
return this; | |||
} | |||
/// <summary> | |||
/// Sets the default permission of the current command. | |||
/// </summary> | |||
/// <param name="value">The default permission value to set.</param> | |||
/// <returns>The current builder.</returns> | |||
public SlashCommandBuilder WithDefaultPermission(bool value) | |||
{ | |||
this.DefaultPermission = value; | |||
return this; | |||
} | |||
/// <summary> | |||
/// Adds an option to the current slash command. | |||
/// </summary> | |||
@@ -8,17 +8,17 @@ namespace Discord | |||
/// <summary> | |||
/// The id of the role or user. | |||
/// </summary> | |||
public ulong Id { get; } | |||
public ulong TargetId { get; } | |||
/// <summary> | |||
/// The target of this permission. | |||
/// </summary> | |||
public PermissionTarget Type { get; } | |||
public PermissionTarget TargetType { get; } | |||
/// <summary> | |||
/// <see langword="true"/> to allow, otherwise <see langword="false"/>. | |||
/// </summary> | |||
public bool Value { get; } | |||
public bool Permission { get; } | |||
internal ApplicationCommandPermission() { } | |||
@@ -30,9 +30,9 @@ namespace Discord | |||
/// <param name="allow">The value of this permission.</param> | |||
public ApplicationCommandPermission(ulong targetId, PermissionTarget targetType, bool allow) | |||
{ | |||
this.Id = targetId; | |||
this.Type = targetType; | |||
this.Value = allow; | |||
this.TargetId = targetId; | |||
this.TargetType = targetType; | |||
this.Permission = allow; | |||
} | |||
/// <summary> | |||
@@ -42,9 +42,9 @@ namespace Discord | |||
/// <param name="allow">The value of this permission.</param> | |||
public ApplicationCommandPermission(IUser target, bool allow) | |||
{ | |||
this.Id = target.Id; | |||
this.Value = allow; | |||
this.Type = PermissionTarget.User; | |||
this.TargetId = target.Id; | |||
this.Permission = allow; | |||
this.TargetType = PermissionTarget.User; | |||
} | |||
/// <summary> | |||
@@ -54,9 +54,9 @@ namespace Discord | |||
/// <param name="allow">The value of this permission.</param> | |||
public ApplicationCommandPermission(IRole target, bool allow) | |||
{ | |||
this.Id = target.Id; | |||
this.Value = allow; | |||
this.Type = PermissionTarget.Role; | |||
this.TargetId = target.Id; | |||
this.Permission = allow; | |||
this.TargetType = PermissionTarget.Role; | |||
} | |||
} | |||
} |
@@ -9,12 +9,13 @@ namespace Discord | |||
/// <summary> | |||
/// Returned when fetching the permissions for a command in a guild. | |||
/// </summary> | |||
public class GuildApplicationCommandPermissions | |||
public class GuildApplicationCommandPermission | |||
{ | |||
/// <summary> | |||
/// The id of the command. | |||
/// </summary> | |||
public ulong Id { get; } | |||
public ulong CommandId { get; } | |||
/// <summary> | |||
/// The id of the application the command belongs to. | |||
@@ -31,12 +32,12 @@ namespace Discord | |||
/// </summary> | |||
public IReadOnlyCollection<ApplicationCommandPermission> Permissions { get; } | |||
internal GuildApplicationCommandPermissions(ulong id, ulong appId, ulong guildId, List<ApplicationCommandPermission> permissions) | |||
internal GuildApplicationCommandPermission(ulong commandId, ulong appId, ulong guildId, ApplicationCommandPermission[] permissions) | |||
{ | |||
this.Id = id; | |||
this.CommandId = commandId; | |||
this.ApplicationId = appId; | |||
this.GuildId = guildId; | |||
this.Permissions = permissions.ToReadOnlyCollection(); | |||
this.Permissions = permissions; | |||
} | |||
} | |||
} |
@@ -19,5 +19,7 @@ namespace Discord.API | |||
public string Description { get; set; } | |||
[JsonProperty("options")] | |||
public Optional<ApplicationCommandOption[]> Options { get; set; } | |||
[JsonProperty("default_permission")] | |||
public Optional<bool> DefaultPermissions { get; set; } | |||
} | |||
} |
@@ -7,7 +7,7 @@ using System.Threading.Tasks; | |||
namespace Discord.API | |||
{ | |||
public class ApplicationCommandPermissions | |||
internal class ApplicationCommandPermissions | |||
{ | |||
[JsonProperty("id")] | |||
public ulong Id { get; set; } | |||
@@ -7,16 +7,16 @@ using System.Threading.Tasks; | |||
namespace Discord.API | |||
{ | |||
public class GuildApplicationCommandPermission | |||
internal class GuildApplicationCommandPermission | |||
{ | |||
[JsonProperty("id")] | |||
public ulong Id { get; } | |||
public ulong Id { get; set; } | |||
[JsonProperty("application_id")] | |||
public ulong ApplicationId { get; } | |||
public ulong ApplicationId { get; set; } | |||
[JsonProperty("guild_id")] | |||
public ulong GuildId { get; } | |||
public ulong GuildId { get; set; } | |||
[JsonProperty("permissions")] | |||
public API.ApplicationCommandPermissions[] Permissions { get; set; } | |||
@@ -13,6 +13,6 @@ namespace Discord.API.Rest | |||
public ulong Id { get; set; } | |||
[JsonProperty("permissions")] | |||
public ApplicationCommandPermission[] Permissions { get; set; } | |||
public ApplicationCommandPermissions[] Permissions { get; set; } | |||
} | |||
} |
@@ -206,7 +206,7 @@ namespace Discord.Rest | |||
public static async Task<IReadOnlyCollection<RestGuildCommand>> GetGuildApplicationCommands(BaseDiscordClient client, ulong guildId, RequestOptions options) | |||
{ | |||
var response = await client.ApiClient.GetGuildApplicationCommandAsync(guildId, options).ConfigureAwait(false); | |||
var response = await client.ApiClient.GetGuildApplicationCommandsAsync(guildId, options).ConfigureAwait(false); | |||
if (!response.Any()) | |||
return new RestGuildCommand[0].ToImmutableArray(); | |||
@@ -214,6 +214,7 @@ namespace Discord.Rest | |||
return response.Select(x => RestGuildCommand.Create(client, x, guildId)).ToImmutableArray(); | |||
} | |||
public static Task AddRoleAsync(BaseDiscordClient client, ulong guildId, ulong userId, ulong roleId, RequestOptions options = null) | |||
=> client.ApiClient.AddRoleAsync(guildId, userId, roleId, options); | |||
@@ -9,7 +9,7 @@ | |||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard2.0;netstandard2.1</TargetFrameworks> | |||
<PackageIcon>Temporary.png</PackageIcon> | |||
<PackageProjectUrl>https://github.com/Discord-Net-Labs/Discord.Net-Labs</PackageProjectUrl> | |||
<Version>2.4.1</Version> | |||
<Version>2.4.2</Version> | |||
<PackageId>Discord.Net.Labs.Rest</PackageId> | |||
<RepositoryUrl>https://github.com/Discord-Net-Labs/Discord.Net-Labs</RepositoryUrl> | |||
<AssemblyVersion>2.3.4</AssemblyVersion> | |||
@@ -2740,6 +2740,27 @@ | |||
<member name="M:Discord.Rest.RestGuild.LeaveAsync(Discord.RequestOptions)"> | |||
<inheritdoc /> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.GetSlashCommandsAsync(Discord.RequestOptions)"> | |||
<summary> | |||
Gets a collection of slash commands created by the current user in this guild. | |||
</summary> | |||
<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 read-only collection of | |||
slash commands created by the current user. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.GetSlashCommandAsync(System.UInt64,Discord.RequestOptions)"> | |||
<summary> | |||
Gets a slash command in the current guild. | |||
</summary> | |||
<param name="id">The unique identifier of the slash command.</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 | |||
slash command created by the current user. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuild.GetBansAsync(Discord.RequestOptions)"> | |||
<summary> | |||
Gets a collection of all users banned in this guild. | |||
@@ -3378,6 +3399,9 @@ | |||
<member name="P:Discord.Rest.RestApplicationCommand.Description"> | |||
<inheritdoc/> | |||
</member> | |||
<member name="P:Discord.Rest.RestApplicationCommand.DefaultPermission"> | |||
<inheritdoc/> | |||
</member> | |||
<member name="P:Discord.Rest.RestApplicationCommand.Options"> | |||
<summary> | |||
The options of this command. | |||
@@ -3391,6 +3415,9 @@ | |||
<member name="P:Discord.Rest.RestApplicationCommand.CreatedAt"> | |||
<inheritdoc/> | |||
</member> | |||
<member name="M:Discord.Rest.RestApplicationCommand.DeleteAsync(Discord.RequestOptions)"> | |||
<inheritdoc/> | |||
</member> | |||
<member name="T:Discord.Rest.RestApplicationCommandChoice"> | |||
<summary> | |||
Represents a Rest-based implementation of <see cref="T:Discord.IApplicationCommandOptionChoice"/>. | |||
@@ -3488,6 +3515,38 @@ | |||
The modified command | |||
</returns> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuildCommand.GetCommandPermission(Discord.RequestOptions)"> | |||
<summary> | |||
Gets this commands permissions inside of the current guild. | |||
</summary> | |||
<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.GuildApplicationCommandPermission"/> object defining the permissions of the current slash command. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuildCommand.ModifyCommandPermissions(Discord.ApplicationCommandPermission[],Discord.RequestOptions)"> | |||
<summary> | |||
Modifies the current command permissions for this guild command. | |||
</summary> | |||
<param name="permissions">The permissions to overwrite.</param> | |||
<param name="options">The options to be used when sending the request.</param> | |||
<returns> | |||
A task that represents the asynchronous modification operation. The task result contains a | |||
<see cref="T:Discord.GuildApplicationCommandPermission"/> object containing the modified permissions. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.Rest.RestGuildCommand.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> | |||
@@ -827,54 +827,14 @@ namespace Discord.API | |||
options = RequestOptions.CreateOrClone(options); | |||
try | |||
{ | |||
return await SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/commands", command, new BucketIds(), 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; | |||
} | |||
return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/commands", command, new BucketIds(), options: options)).ConfigureAwait(false); | |||
} | |||
public async Task<ApplicationCommand> ModifyGlobalApplicationCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null) | |||
{ | |||
Preconditions.NotNull(command, nameof(command)); | |||
if (command.Name.IsSpecified) | |||
{ | |||
Preconditions.AtMost(command.Name.Value.Length, 32, nameof(command.Name)); | |||
Preconditions.AtLeast(command.Name.Value.Length, 3, nameof(command.Name)); | |||
} | |||
if (command.Description.IsSpecified) | |||
{ | |||
Preconditions.AtMost(command.Description.Value.Length, 100, nameof(command.Description)); | |||
Preconditions.AtLeast(command.Description.Value.Length, 1, nameof(command.Description)); | |||
} | |||
options = RequestOptions.CreateOrClone(options); | |||
try | |||
{ | |||
return await SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/commands/{commandId}", command, new BucketIds(), 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; | |||
} | |||
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) | |||
{ | |||
@@ -883,7 +843,14 @@ namespace Discord.API | |||
await SendAsync("DELETE", () => $"applications/{this.CurrentUserId}/commands/{commandId}", new BucketIds(), options: options).ConfigureAwait(false); | |||
} | |||
public async Task<ApplicationCommand[]> GetGuildApplicationCommandAsync(ulong guildId, RequestOptions options = null) | |||
public async Task<ApplicationCommand[]> BulkOverwriteGlobalApplicationCommands(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) | |||
{ | |||
options = RequestOptions.CreateOrClone(options); | |||
@@ -891,49 +858,27 @@ namespace Discord.API | |||
return await SendAsync<ApplicationCommand[]>("GET", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", bucket, options: options).ConfigureAwait(false); | |||
} | |||
public async Task<ApplicationCommand> CreateGuildApplicationCommandAsync(CreateApplicationCommandParams command, ulong guildId, RequestOptions options = null) | |||
public async Task<ApplicationCommand> GetGuildApplicationCommandAsync(ulong guildId, ulong commandId, 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.AtMost(command.Description.Length, 100, nameof(command.Description)); | |||
Preconditions.AtLeast(command.Description.Length, 1, nameof(command.Description)); | |||
options = RequestOptions.CreateOrClone(options); | |||
var bucket = new BucketIds(guildId: guildId); | |||
return await SendAsync<ApplicationCommand>("GET", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", bucket, options: options); | |||
} | |||
public async Task<ApplicationCommand> CreateGuildApplicationCommandAsync(CreateApplicationCommandParams command, ulong guildId, RequestOptions options = null) | |||
{ | |||
options = RequestOptions.CreateOrClone(options); | |||
var bucket = new BucketIds(guildId: guildId); | |||
try | |||
{ | |||
return await SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", 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); | |||
} | |||
return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", command, bucket, options: options)).ConfigureAwait(false); | |||
// Re-throw the http exception | |||
throw; | |||
} | |||
} | |||
public async Task<ApplicationCommand> ModifyGuildApplicationCommandAsync(ModifyApplicationCommandParams command, ulong guildId, ulong commandId, RequestOptions options = null) | |||
{ | |||
Preconditions.NotNull(command, nameof(command)); | |||
if (command.Name.IsSpecified) | |||
{ | |||
Preconditions.AtMost(command.Name.Value.Length, 32, nameof(command.Name)); | |||
Preconditions.AtLeast(command.Name.Value.Length, 3, nameof(command.Name)); | |||
} | |||
if (command.Description.IsSpecified) | |||
{ | |||
Preconditions.AtMost(command.Description.Value.Length, 100, nameof(command.Description)); | |||
Preconditions.AtLeast(command.Description.Value.Length, 1, nameof(command.Description)); | |||
} | |||
options = RequestOptions.CreateOrClone(options); | |||
var bucket = new BucketIds(guildId: guildId); | |||
@@ -963,6 +908,15 @@ namespace Discord.API | |||
await SendAsync<ApplicationCommand>("DELETE", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", bucket, options: options).ConfigureAwait(false); | |||
} | |||
public async Task<ApplicationCommand[]> BulkOverwriteGuildApplicationCommands(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) | |||
{ | |||
@@ -971,7 +925,7 @@ namespace Discord.API | |||
options = RequestOptions.CreateOrClone(options); | |||
await SendJsonAsync("POST", () => $"interactions/{interactionId}/{interactionToken}/callback", response, new BucketIds(), options: options); | |||
await SendJsonAsync<Message>("POST", () => $"interactions/{interactionId}/{interactionToken}/callback", response, new BucketIds(), options: options); | |||
} | |||
public async Task<Message> GetInteractionResponse(string interactionToken, RequestOptions options = null) | |||
{ | |||
@@ -1037,7 +991,7 @@ namespace Discord.API | |||
options = RequestOptions.CreateOrClone(options); | |||
return await SendAsync<GuildApplicationCommandPermission[]>("GET", () => $"/applications/{this.CurrentUserId}/guilds/{guildId}/commands/permissions", new BucketIds(), options: options).ConfigureAwait(false); | |||
return await SendAsync<GuildApplicationCommandPermission[]>("GET", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/permissions", new BucketIds(), options: options).ConfigureAwait(false); | |||
} | |||
public async Task<GuildApplicationCommandPermission> GetGuildApplicationCommandPermission(ulong guildId, ulong commandId, RequestOptions options = null) | |||
@@ -1047,37 +1001,27 @@ namespace Discord.API | |||
options = RequestOptions.CreateOrClone(options); | |||
return await SendAsync<GuildApplicationCommandPermission>("GET", () => $"/applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}/permissions", new BucketIds(), options: options).ConfigureAwait(false); | |||
return await SendAsync<GuildApplicationCommandPermission>("GET", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}/permissions", new BucketIds(), options: options).ConfigureAwait(false); | |||
} | |||
public async Task ModifyApplicationCommandPermissions(ApplicationCommandPermissions[] permissions, ulong guildId, ulong commandId, RequestOptions options = null) | |||
public async Task<GuildApplicationCommandPermission> ModifyApplicationCommandPermissions(ApplicationCommandPermissions[] permissions, ulong guildId, ulong commandId, RequestOptions options = null) | |||
{ | |||
Preconditions.NotEqual(guildId, 0, nameof(guildId)); | |||
Preconditions.NotEqual(commandId, 0, nameof(commandId)); | |||
options = RequestOptions.CreateOrClone(options); | |||
await SendJsonAsync("PUT", () => $"/applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}/permissions", permissions, new BucketIds(), options: options).ConfigureAwait(false); | |||
return await SendJsonAsync<GuildApplicationCommandPermission>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}/permissions", permissions, new BucketIds(), options: options).ConfigureAwait(false); | |||
} | |||
public async Task BatchModifyApplicationCommandPermissions(ModifyGuildApplicationCommandPermissions[] permissions, ulong guildId, RequestOptions options = null) | |||
public async Task<IReadOnlyCollection<GuildApplicationCommandPermission>> BatchModifyApplicationCommandPermissions(ModifyGuildApplicationCommandPermissions[] permissions, ulong guildId, RequestOptions options = null) | |||
{ | |||
Preconditions.NotEqual(guildId, 0, nameof(guildId)); | |||
Preconditions.NotNull(permissions, nameof(permissions)); | |||
options = RequestOptions.CreateOrClone(options); | |||
await SendJsonAsync("PUT", () => $"/applications/{this.CurrentUserId}/guilds/{guildId}/commands/premissions", permissions, new BucketIds(), options: options).ConfigureAwait(false); | |||
} | |||
public async Task BulkOverrideGuildApplicationCommand(API.ApplicationCommand[] commands, ulong guildId, RequestOptions options = null) | |||
{ | |||
Preconditions.NotEqual(guildId, 0, nameof(guildId)); | |||
Preconditions.NotNull(commands, nameof(commands)); | |||
options = RequestOptions.CreateOrClone(options); | |||
await SendJsonAsync("PUT", () => $"/applications/{this.CurrentUserId}/guilds/{guildId}/commands", commands, new BucketIds(), options: options).ConfigureAwait(false); | |||
return await SendJsonAsync<GuildApplicationCommandPermission[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/permissions", permissions, new BucketIds(), options: options).ConfigureAwait(false); | |||
} | |||
//Guilds | |||
@@ -1772,6 +1716,27 @@ namespace Discord.API | |||
return _serializer.Deserialize<T>(reader); | |||
} | |||
protected async Task<T> TrySendApplicationCommand<T>(Task<T> sendTask) | |||
{ | |||
var result = await sendTask.ConfigureAwait(false); | |||
if (sendTask.Exception != null) | |||
{ | |||
if (sendTask.Exception.InnerException is HttpException x) | |||
{ | |||
if (x.HttpCode == HttpStatusCode.BadRequest) | |||
{ | |||
var json = (x.Request as JsonRestRequest).Json; | |||
throw new ApplicationCommandException(json, x); | |||
} | |||
} | |||
throw sendTask.Exception; | |||
} | |||
else | |||
return result; | |||
} | |||
internal class BucketIds | |||
{ | |||
public ulong GuildId { get; internal set; } | |||
@@ -106,6 +106,7 @@ namespace Discord.Rest | |||
=> ClientHelper.GetVoiceRegionAsync(this, id, options); | |||
public Task<RestWebhook> GetWebhookAsync(ulong id, RequestOptions options = null) | |||
=> ClientHelper.GetWebhookAsync(this, id, options); | |||
public Task<RestGlobalCommand> CreateGlobalCommand(SlashCommandCreationProperties properties, RequestOptions options = null) | |||
=> InteractionHelper.CreateGlobalCommand(this, properties, options); | |||
public Task<RestGlobalCommand> CreateGlobalCommand(Action<SlashCommandCreationProperties> func, RequestOptions options = null) | |||
@@ -118,6 +119,14 @@ namespace Discord.Rest | |||
=> ClientHelper.GetGlobalApplicationCommands(this, options); | |||
public Task<IReadOnlyCollection<RestGuildCommand>> GetGuildApplicationCommands(ulong guildId, RequestOptions options = null) | |||
=> ClientHelper.GetGuildApplicationCommands(this, guildId, options); | |||
public Task<IReadOnlyCollection<RestGlobalCommand>> BulkOverwriteGlobalCommands(SlashCommandCreationProperties[] commandProperties, RequestOptions options = null) | |||
=> InteractionHelper.BulkOverwriteGlobalCommands(this, commandProperties, options); | |||
public Task<IReadOnlyCollection<RestGuildCommand>> BulkOverwriteGuildCommands(SlashCommandCreationProperties[] commandProperties, ulong guildId, RequestOptions options = null) | |||
=> InteractionHelper.BulkOverwriteGuildCommands(this, guildId, commandProperties, options); | |||
public Task<IReadOnlyCollection<GuildApplicationCommandPermission>> BatchEditGuildCommandPermissions(ulong guildId, IDictionary<ulong, ApplicationCommandPermission[]> permissions, RequestOptions options = null) | |||
=> InteractionHelper.BatchEditGuildCommandPermissionsAsync(this, guildId, permissions, options); | |||
public Task AddRoleAsync(ulong guildId, ulong userId, ulong roleId) | |||
=> ClientHelper.AddRoleAsync(this, guildId, userId, roleId); | |||
public Task RemoveRoleAsync(ulong guildId, ulong userId, ulong roleId) | |||
@@ -270,6 +270,20 @@ namespace Discord.Rest | |||
return RestGuildIntegration.Create(client, guild, model); | |||
} | |||
//Interactions | |||
public static async Task<IReadOnlyCollection<RestGuildCommand>> GetSlashCommandsAsync(IGuild guild, BaseDiscordClient client, | |||
RequestOptions options) | |||
{ | |||
var models = await client.ApiClient.GetGuildApplicationCommandsAsync(guild.Id, options); | |||
return models.Select(x => RestGuildCommand.Create(client, x, guild.Id)).ToImmutableArray(); | |||
} | |||
public static async Task<RestGuildCommand> GetSlashCommandAsync(IGuild guild, ulong id, BaseDiscordClient client, | |||
RequestOptions options) | |||
{ | |||
var model = await client.ApiClient.GetGuildApplicationCommandAsync(guild.Id, id, options); | |||
return RestGuildCommand.Create(client, model, guild.Id); | |||
} | |||
//Invites | |||
public static async Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(IGuild guild, BaseDiscordClient client, | |||
RequestOptions options) | |||
@@ -255,7 +255,30 @@ namespace Discord.Rest | |||
public Task LeaveAsync(RequestOptions options = null) | |||
=> GuildHelper.LeaveAsync(this, Discord, options); | |||
//Bans | |||
//Interactions | |||
/// <summary> | |||
/// Gets a collection of slash commands created by the current user in this guild. | |||
/// </summary> | |||
/// <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 read-only collection of | |||
/// slash commands created by the current user. | |||
/// </returns> | |||
public Task<IReadOnlyCollection<RestGuildCommand>> GetSlashCommandsAsync(RequestOptions options = null) | |||
=> GuildHelper.GetSlashCommandsAsync(this, Discord, options); | |||
/// <summary> | |||
/// Gets a slash command in the current guild. | |||
/// </summary> | |||
/// <param name="id">The unique identifier of the slash command.</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 | |||
/// slash command created by the current user. | |||
/// </returns> | |||
public Task<RestGuildCommand> GetSlashCommandAsync(ulong id, RequestOptions options = null) | |||
=> GuildHelper.GetSlashCommandAsync(this, id, Discord, options); | |||
//Bans | |||
/// <summary> | |||
/// Gets a collection of all users banned in this guild. | |||
@@ -10,20 +10,20 @@ namespace Discord.Rest | |||
{ | |||
internal static class InteractionHelper | |||
{ | |||
internal static Task SendInteractionResponse(BaseDiscordClient client, IMessageChannel channel, InteractionResponse response, | |||
public static Task SendInteractionResponse(BaseDiscordClient client, IMessageChannel channel, InteractionResponse response, | |||
ulong interactionId, string interactionToken, RequestOptions options = null) | |||
{ | |||
return client.ApiClient.CreateInteractionResponse(response, interactionId, interactionToken, options); | |||
} | |||
internal static async Task<RestInteractionMessage> GetOriginalResponseAsync(BaseDiscordClient client, IMessageChannel channel, | |||
public static async Task<RestInteractionMessage> GetOriginalResponseAsync(BaseDiscordClient client, IMessageChannel channel, | |||
IDiscordInteraction interaction, RequestOptions options = null) | |||
{ | |||
var model = await client.ApiClient.GetInteractionResponse(interaction.Token, options).ConfigureAwait(false); | |||
return RestInteractionMessage.Create(client, model, interaction.Token, channel); | |||
} | |||
internal static async Task<RestFollowupMessage> SendFollowupAsync(BaseDiscordClient client, CreateWebhookMessageParams args, | |||
public static async Task<RestFollowupMessage> SendFollowupAsync(BaseDiscordClient client, CreateWebhookMessageParams args, | |||
string token, IMessageChannel channel, RequestOptions options = null) | |||
{ | |||
var model = await client.ApiClient.CreateInteractionFollowupMessage(args, token, options).ConfigureAwait(false); | |||
@@ -31,47 +31,128 @@ namespace Discord.Rest | |||
RestFollowupMessage entity = RestFollowupMessage.Create(client, model, token, channel); | |||
return entity; | |||
} | |||
// Global commands | |||
internal static async Task<RestGlobalCommand> CreateGlobalCommand(BaseDiscordClient client, | |||
public static async Task<RestGlobalCommand> CreateGlobalCommand(BaseDiscordClient client, | |||
Action<SlashCommandCreationProperties> func, RequestOptions options = null) | |||
{ | |||
var args = new SlashCommandCreationProperties(); | |||
func(args); | |||
return await CreateGlobalCommand(client, args, options).ConfigureAwait(false); | |||
} | |||
internal static async Task<RestGlobalCommand> CreateGlobalCommand(BaseDiscordClient client, | |||
SlashCommandCreationProperties args, RequestOptions options = null) | |||
public static async Task<RestGlobalCommand> CreateGlobalCommand(BaseDiscordClient client, | |||
SlashCommandCreationProperties arg, RequestOptions options = null) | |||
{ | |||
if (args.Options.IsSpecified) | |||
{ | |||
if (args.Options.Value.Count > 10) | |||
throw new ArgumentException("Option count must be 10 or less"); | |||
} | |||
Preconditions.NotNullOrEmpty(arg.Name, nameof(arg.Name)); | |||
Preconditions.NotNullOrEmpty(arg.Description, nameof(arg.Description)); | |||
if (arg.Options.IsSpecified) | |||
Preconditions.AtMost(arg.Options.Value.Count, 25, nameof(arg.Options)); | |||
var model = new CreateApplicationCommandParams() | |||
{ | |||
Name = args.Name, | |||
Description = args.Description, | |||
Options = args.Options.IsSpecified | |||
? args.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() | |||
Name = arg.Name, | |||
Description = arg.Description, | |||
Options = arg.Options.IsSpecified | |||
? arg.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() | |||
: Optional<Discord.API.ApplicationCommandOption[]>.Unspecified, | |||
DefaultPermission = args.DefaultPermission.IsSpecified | |||
? args.DefaultPermission.Value | |||
DefaultPermission = arg.DefaultPermission.IsSpecified | |||
? arg.DefaultPermission.Value | |||
: Optional<bool>.Unspecified | |||
}; | |||
var cmd = await client.ApiClient.CreateGlobalApplicationCommandAsync(model, options).ConfigureAwait(false); | |||
return RestGlobalCommand.Create(client, cmd); | |||
} | |||
internal static async Task<RestGlobalCommand> ModifyGlobalCommand(BaseDiscordClient client, RestGlobalCommand command, | |||
public static async Task<IReadOnlyCollection<RestGlobalCommand>> BulkOverwriteGlobalCommands(BaseDiscordClient client, | |||
SlashCommandCreationProperties[] 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)); | |||
if (arg.Options.IsSpecified) | |||
Preconditions.AtMost(arg.Options.Value.Count, 25, nameof(arg.Options)); | |||
var model = new CreateApplicationCommandParams() | |||
{ | |||
Name = arg.Name, | |||
Description = arg.Description, | |||
Options = arg.Options.IsSpecified | |||
? arg.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() | |||
: Optional<Discord.API.ApplicationCommandOption[]>.Unspecified, | |||
DefaultPermission = arg.DefaultPermission.IsSpecified | |||
? arg.DefaultPermission.Value | |||
: Optional<bool>.Unspecified | |||
}; | |||
models.Add(model); | |||
} | |||
var apiModels = await client.ApiClient.BulkOverwriteGlobalApplicationCommands(models.ToArray(), options); | |||
return apiModels.Select(x => RestGlobalCommand.Create(client, x)).ToArray(); | |||
} | |||
public static async Task<IReadOnlyCollection<RestGuildCommand>> BulkOverwriteGuildCommands(BaseDiscordClient client, ulong guildId, | |||
SlashCommandCreationProperties[] 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)); | |||
if (arg.Options.IsSpecified) | |||
Preconditions.AtMost(arg.Options.Value.Count, 25, nameof(arg.Options)); | |||
var model = new CreateApplicationCommandParams() | |||
{ | |||
Name = arg.Name, | |||
Description = arg.Description, | |||
Options = arg.Options.IsSpecified | |||
? arg.Options.Value.Select(x => new Discord.API.ApplicationCommandOption(x)).ToArray() | |||
: Optional<Discord.API.ApplicationCommandOption[]>.Unspecified, | |||
DefaultPermission = arg.DefaultPermission.IsSpecified | |||
? arg.DefaultPermission.Value | |||
: Optional<bool>.Unspecified | |||
}; | |||
models.Add(model); | |||
} | |||
var apiModels = await client.ApiClient.BulkOverwriteGuildApplicationCommands(guildId, models.ToArray(), options); | |||
return apiModels.Select(x => RestGuildCommand.Create(client, x, guildId)).ToArray(); | |||
} | |||
public static async Task<RestGlobalCommand> ModifyGlobalCommand(BaseDiscordClient client, RestGlobalCommand 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.AtMost(args.Description.Value.Length, 100, nameof(args.Description)); | |||
Preconditions.AtLeast(args.Description.Value.Length, 1, nameof(args.Description)); | |||
} | |||
if (args.Options.IsSpecified) | |||
{ | |||
if (args.Options.Value.Count > 10) | |||
@@ -96,7 +177,7 @@ namespace Discord.Rest | |||
} | |||
internal static async Task DeleteGlobalCommand(BaseDiscordClient client, RestGlobalCommand command, RequestOptions options = null) | |||
public static async Task DeleteGlobalCommand(BaseDiscordClient client, RestGlobalCommand command, RequestOptions options = null) | |||
{ | |||
Preconditions.NotNull(command, nameof(command)); | |||
Preconditions.NotEqual(command.Id, 0, nameof(command.Id)); | |||
@@ -105,7 +186,7 @@ namespace Discord.Rest | |||
} | |||
// Guild Commands | |||
internal static async Task<RestGuildCommand> CreateGuildCommand(BaseDiscordClient client, ulong guildId, | |||
public static async Task<RestGuildCommand> CreateGuildCommand(BaseDiscordClient client, ulong guildId, | |||
Action<SlashCommandCreationProperties> func, RequestOptions options = null) | |||
{ | |||
var args = new SlashCommandCreationProperties(); | |||
@@ -113,19 +194,23 @@ namespace Discord.Rest | |||
return await CreateGuildCommand(client, guildId, args, options).ConfigureAwait(false); | |||
} | |||
internal static async Task<RestGuildCommand> CreateGuildCommand(BaseDiscordClient client, ulong guildId, | |||
public static async Task<RestGuildCommand> CreateGuildCommand(BaseDiscordClient client, ulong guildId, | |||
SlashCommandCreationProperties args, RequestOptions options = null) | |||
{ | |||
Preconditions.NotNullOrEmpty(args.Name, nameof(args.Name)); | |||
Preconditions.NotNullOrEmpty(args.Description, nameof(args.Description)); | |||
Preconditions.AtMost(args.Name.Length, 32, nameof(args.Name)); | |||
Preconditions.AtLeast(args.Name.Length, 3, nameof(args.Name)); | |||
Preconditions.AtMost(args.Description.Length, 100, nameof(args.Description)); | |||
Preconditions.AtLeast(args.Description.Length, 1, nameof(args.Description)); | |||
if (args.Options.IsSpecified) | |||
{ | |||
if (args.Options.Value.Count > 10) | |||
throw new ArgumentException("Option count must be 10 or less"); | |||
foreach(var item in args.Options.Value) | |||
foreach (var item in args.Options.Value) | |||
{ | |||
Preconditions.NotNullOrEmpty(item.Name, nameof(item.Name)); | |||
Preconditions.NotNullOrEmpty(item.Description, nameof(item.Description)); | |||
@@ -147,12 +232,23 @@ namespace Discord.Rest | |||
var cmd = await client.ApiClient.CreateGuildApplicationCommandAsync(model, guildId, options).ConfigureAwait(false); | |||
return RestGuildCommand.Create(client, cmd, guildId); | |||
} | |||
internal static async Task<RestGuildCommand> ModifyGuildCommand(BaseDiscordClient client, RestGuildCommand command, | |||
public static async Task<RestGuildCommand> ModifyGuildCommand(BaseDiscordClient client, RestGuildCommand 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.AtMost(args.Description.Value.Length, 100, nameof(args.Description)); | |||
Preconditions.AtLeast(args.Description.Value.Length, 1, nameof(args.Description)); | |||
} | |||
if (args.Options.IsSpecified) | |||
{ | |||
if (args.Options.Value.Count > 10) | |||
@@ -176,15 +272,15 @@ namespace Discord.Rest | |||
return command; | |||
} | |||
internal static async Task DeleteGuildCommand(BaseDiscordClient client, RestGuildCommand command, RequestOptions options = null) | |||
public static async Task DeleteGuildCommand(BaseDiscordClient client, ulong guildId, IApplicationCommand command, RequestOptions options = null) | |||
{ | |||
Preconditions.NotNull(command, nameof(command)); | |||
Preconditions.NotEqual(command.Id, 0, nameof(command.Id)); | |||
await client.ApiClient.DeleteGuildApplicationCommandAsync(command.GuildId, command.Id, options).ConfigureAwait(false); | |||
await client.ApiClient.DeleteGuildApplicationCommandAsync(guildId, command.Id, options).ConfigureAwait(false); | |||
} | |||
internal static async Task<Discord.API.Message> ModifyFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, Action<MessageProperties> func, | |||
public static async Task<Discord.API.Message> ModifyFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, Action<MessageProperties> func, | |||
RequestOptions options = null) | |||
{ | |||
var args = new MessageProperties(); | |||
@@ -204,10 +300,10 @@ namespace Discord.Rest | |||
return await client.ApiClient.ModifyInteractionFollowupMessage(apiArgs, message.Id, message.Token, options).ConfigureAwait(false); | |||
} | |||
internal static async Task DeleteFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, RequestOptions options = null) | |||
public static async Task DeleteFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, RequestOptions options = null) | |||
=> await client.ApiClient.DeleteInteractionFollowupMessage(message.Id, message.Token, options); | |||
internal static async Task<Discord.API.Message> ModifyInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, Action<MessageProperties> func, | |||
public static async Task<Discord.API.Message> ModifyInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, Action<MessageProperties> func, | |||
RequestOptions options = null) | |||
{ | |||
var args = new MessageProperties(); | |||
@@ -227,16 +323,87 @@ namespace Discord.Rest | |||
return await client.ApiClient.ModifyInteractionFollowupMessage(apiArgs, message.Id, message.Token, options).ConfigureAwait(false); | |||
} | |||
internal static async Task DeletedInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null) | |||
public static async Task DeletedInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null) | |||
=> await client.ApiClient.DeleteInteractionFollowupMessage(message.Id, message.Token, options); | |||
// Guild permissions | |||
internal static async Task<IReadOnlyCollection<Discord.GuildApplicationCommandPermissions>> GetCommandGuildPermissions(BaseDiscordClient client, | |||
RestGuildCommand command) | |||
public static async Task<IReadOnlyCollection<GuildApplicationCommandPermission>> GetGuildCommandPermissionsAsync(BaseDiscordClient client, | |||
ulong guildId, RequestOptions options) | |||
{ | |||
// TODO | |||
return null; | |||
var models = await client.ApiClient.GetGuildApplicationCommandPermissions(guildId, options); | |||
return models.Select(x => | |||
new GuildApplicationCommandPermission(x.Id, x.ApplicationId, guildId, x.Permissions.Select( | |||
y => new Discord.ApplicationCommandPermission(y.Id, y.Type, y.Permission)) | |||
.ToArray()) | |||
).ToArray(); | |||
} | |||
public static async Task<GuildApplicationCommandPermission> GetGuildCommandPermissionAsync(BaseDiscordClient client, | |||
ulong guildId, ulong commandId, RequestOptions options) | |||
{ | |||
var model = await client.ApiClient.GetGuildApplicationCommandPermission(guildId, commandId, options); | |||
return new GuildApplicationCommandPermission(model.Id, model.ApplicationId, guildId, model.Permissions.Select( | |||
y => new ApplicationCommandPermission(y.Id, y.Type, y.Permission)).ToArray()); | |||
} | |||
public static async Task<GuildApplicationCommandPermission> ModifyGuildCommandPermissionsAsync(BaseDiscordClient client, ulong guildId, ulong commandId, | |||
ApplicationCommandPermission[] args, RequestOptions options) | |||
{ | |||
Preconditions.NotNull(args, nameof(args)); | |||
Preconditions.AtMost(args.Length, 10, nameof(args)); | |||
Preconditions.GreaterThan(args.Length, 0, nameof(args)); | |||
List<ApplicationCommandPermissions> models = new List<ApplicationCommandPermissions>(); | |||
foreach(var arg in args) | |||
{ | |||
var model = new ApplicationCommandPermissions() | |||
{ | |||
Id = arg.TargetId, | |||
Permission = arg.Permission, | |||
Type = arg.TargetType | |||
}; | |||
models.Add(model); | |||
} | |||
var apiModel = await client.ApiClient.ModifyApplicationCommandPermissions(models.ToArray(), guildId, commandId, options); | |||
return new GuildApplicationCommandPermission(apiModel.Id, apiModel.ApplicationId, guildId, apiModel.Permissions.Select( | |||
x => new ApplicationCommandPermission(x.Id, x.Type, x.Permission)).ToArray()); | |||
} | |||
public static async Task<IReadOnlyCollection<GuildApplicationCommandPermission>> BatchEditGuildCommandPermissionsAsync(BaseDiscordClient client, ulong guildId, | |||
IDictionary<ulong, ApplicationCommandPermission[]> args, RequestOptions options) | |||
{ | |||
Preconditions.NotNull(args, nameof(args)); | |||
Preconditions.NotEqual(args.Count, 0, nameof(args)); | |||
List<ModifyGuildApplicationCommandPermissions> models = new List<ModifyGuildApplicationCommandPermissions>(); | |||
foreach(var arg in args) | |||
{ | |||
Preconditions.AtMost(arg.Value.Length, 10, nameof(args)); | |||
var model = new ModifyGuildApplicationCommandPermissions() | |||
{ | |||
Id = arg.Key, | |||
Permissions = arg.Value.Select(x => new ApplicationCommandPermissions() | |||
{ | |||
Id = x.TargetId, | |||
Permission = x.Permission, | |||
Type = x.TargetType | |||
}).ToArray() | |||
}; | |||
models.Add(model); | |||
} | |||
var apiModels = await client.ApiClient.BatchModifyApplicationCommandPermissions(models.ToArray(), guildId, options); | |||
return apiModels.Select( | |||
x => new GuildApplicationCommandPermission(x.Id, x.ApplicationId, x.GuildId, x.Permissions.Select( | |||
y => new ApplicationCommandPermission(y.Id, y.Type, y.Permission)).ToArray())).ToArray(); | |||
} | |||
} | |||
} |
@@ -22,6 +22,9 @@ namespace Discord.Rest | |||
/// <inheritdoc/> | |||
public string Description { get; private set; } | |||
/// <inheritdoc/> | |||
public bool DefaultPermission { get; private set; } | |||
/// <summary> | |||
/// The options of this command. | |||
/// </summary> | |||
@@ -58,14 +61,18 @@ namespace Discord.Rest | |||
this.ApplicationId = model.ApplicationId; | |||
this.Name = model.Name; | |||
this.Description = model.Description; | |||
this.DefaultPermission = model.DefaultPermissions.GetValueOrDefault(true); | |||
this.Options = model.Options.IsSpecified | |||
? model.Options.Value.Select(x => RestApplicationCommandOption.Create(x)).ToImmutableArray() | |||
: null; | |||
} | |||
/// <inheritdoc/> | |||
public abstract Task DeleteAsync(RequestOptions options = null); | |||
IReadOnlyCollection<IApplicationCommandOption> IApplicationCommand.Options => Options; | |||
public virtual Task DeleteAsync(RequestOptions options = null) => throw new NotImplementedException(); | |||
} | |||
} |
@@ -33,7 +33,7 @@ namespace Discord.Rest | |||
/// <inheritdoc/> | |||
public override async Task DeleteAsync(RequestOptions options = null) | |||
=> await InteractionHelper.DeleteGuildCommand(Discord, this).ConfigureAwait(false); | |||
=> await InteractionHelper.DeleteGuildCommand(Discord, GuildId, this).ConfigureAwait(false); | |||
/// <summary> | |||
/// Modifies this <see cref="RestApplicationCommand"/>. | |||
@@ -46,7 +46,39 @@ namespace Discord.Rest | |||
public async Task<RestGuildCommand> ModifyAsync(Action<ApplicationCommandProperties> func, RequestOptions options = null) | |||
=> await InteractionHelper.ModifyGuildCommand(Discord, this, func, options).ConfigureAwait(false); | |||
public async Task<IReadOnlyCollection<Discord.GuildApplicationCommandPermissions>> GetCommandPermissions() | |||
=> await InteractionHelper.GetCommandGuildPermissions(Discord, this); | |||
/// <summary> | |||
/// Gets this commands permissions inside of the current guild. | |||
/// </summary> | |||
/// <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="GuildApplicationCommandPermission"/> object defining the permissions of the current slash command. | |||
/// </returns> | |||
public Task<GuildApplicationCommandPermission> GetCommandPermission(RequestOptions options = null) | |||
=> InteractionHelper.GetGuildCommandPermissionAsync(Discord, this.GuildId, this.Id, options); | |||
/// <summary> | |||
/// Modifies the current command permissions for this guild command. | |||
/// </summary> | |||
/// <param name="permissions">The permissions to overwrite.</param> | |||
/// <param name="options">The options to be used when sending the request.</param> | |||
/// <returns> | |||
/// A task that represents the asynchronous modification operation. The task result contains a | |||
/// <see cref="GuildApplicationCommandPermission"/> object containing the modified permissions. | |||
/// </returns> | |||
public Task<GuildApplicationCommandPermission> ModifyCommandPermissions(ApplicationCommandPermission[] permissions, RequestOptions options = null) | |||
=> InteractionHelper.ModifyGuildCommandPermissionsAsync(Discord, this.GuildId, this.Id, permissions, options); | |||
/// <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); | |||
} | |||
} |
@@ -26,5 +26,8 @@ namespace Discord.API.Gateway | |||
[JsonProperty("options")] | |||
public Optional<List<Discord.API.ApplicationCommandOption>> Options { get; set; } | |||
[JsonProperty("default_permission")] | |||
public Optional<bool> DefaultPermission { get; set; } | |||
} | |||
} |
@@ -2843,6 +2843,27 @@ | |||
voice regions the guild can access. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.WebSocket.SocketGuild.GetSlashCommandsAsync(Discord.RequestOptions)"> | |||
<summary> | |||
Gets a collection of slash commands created by the current user in this guild. | |||
</summary> | |||
<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 read-only collection of | |||
slash commands created by the current user. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.WebSocket.SocketGuild.GetSlashCommandAsync(System.UInt64,Discord.RequestOptions)"> | |||
<summary> | |||
Gets a slash command in the current guild. | |||
</summary> | |||
<param name="id">The unique identifier of the slash command.</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 | |||
slash command created by the current user. | |||
</returns> | |||
</member> | |||
<member name="M:Discord.WebSocket.SocketGuild.GetInvitesAsync(Discord.RequestOptions)"> | |||
<summary> | |||
Gets a collection of all invites in this guild. | |||
@@ -3243,6 +3264,9 @@ | |||
<member name="P:Discord.WebSocket.SocketApplicationCommand.Description"> | |||
<inheritdoc/> | |||
</member> | |||
<member name="P:Discord.WebSocket.SocketApplicationCommand.DefaultPermission"> | |||
<inheritdoc/> | |||
</member> | |||
<member name="P:Discord.WebSocket.SocketApplicationCommand.Options"> | |||
<summary> | |||
A collection of <see cref="T:Discord.WebSocket.SocketApplicationCommandOption"/>'s recieved over the gateway. | |||
@@ -3256,6 +3280,9 @@ | |||
The <see cref="T:Discord.WebSocket.SocketGuild"/> where this application was created. | |||
</summary> | |||
</member> | |||
<member name="M:Discord.WebSocket.SocketApplicationCommand.DeleteAsync(Discord.RequestOptions)"> | |||
<inheritdoc/> | |||
</member> | |||
<member name="T:Discord.WebSocket.SocketApplicationCommandChoice"> | |||
<summary> | |||
Represents a choice for a <see cref="T:Discord.WebSocket.SocketApplicationCommandOption"/>. | |||
@@ -723,6 +723,30 @@ namespace Discord.WebSocket | |||
public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null) | |||
=> GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options); | |||
//Interactions | |||
/// <summary> | |||
/// Gets a collection of slash commands created by the current user in this guild. | |||
/// </summary> | |||
/// <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 read-only collection of | |||
/// slash commands created by the current user. | |||
/// </returns> | |||
public Task<IReadOnlyCollection<RestGuildCommand>> GetSlashCommandsAsync(RequestOptions options = null) | |||
=> GuildHelper.GetSlashCommandsAsync(this, Discord, options); | |||
/// <summary> | |||
/// Gets a slash command in the current guild. | |||
/// </summary> | |||
/// <param name="id">The unique identifier of the slash command.</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 | |||
/// slash command created by the current user. | |||
/// </returns> | |||
public Task<RestGuildCommand> GetSlashCommandAsync(ulong id, RequestOptions options = null) | |||
=> GuildHelper.GetSlashCommandAsync(this, id, Discord, options); | |||
//Invites | |||
/// <summary> | |||
/// Gets a collection of all invites in this guild. | |||
@@ -1,3 +1,4 @@ | |||
using Discord.Rest; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
@@ -22,6 +23,9 @@ namespace Discord.WebSocket | |||
/// <inheritdoc/> | |||
public string Description { get; private set; } | |||
/// <inheritdoc/> | |||
public bool DefaultPermission { get; private set; } | |||
/// <summary> | |||
/// A collection of <see cref="SocketApplicationCommandOption"/>'s recieved over the gateway. | |||
/// </summary> | |||
@@ -56,13 +60,18 @@ namespace Discord.WebSocket | |||
this.Description = model.Description; | |||
this.Name = model.Name; | |||
this.GuildId = model.GuildId; | |||
this.DefaultPermission = model.DefaultPermission.GetValueOrDefault(true); | |||
this.Options = model.Options.IsSpecified | |||
? model.Options.Value.Select(x => SocketApplicationCommandOption.Create(x)).ToImmutableArray() | |||
: new ImmutableArray<SocketApplicationCommandOption>(); | |||
} | |||
public Task DeleteAsync(RequestOptions options = null) => throw new NotImplementedException(); | |||
/// <inheritdoc/> | |||
public Task DeleteAsync(RequestOptions options = null) | |||
=> InteractionHelper.DeleteGuildCommand(Discord, this.GuildId, this, options); | |||
IReadOnlyCollection<IApplicationCommandOption> IApplicationCommand.Options => Options; | |||
} | |||
} |
@@ -54,9 +54,20 @@ namespace Discord.WebSocket | |||
{ | |||
foreach (var channel in resolved.Channels.Value) | |||
{ | |||
SocketChannel socketChannel = channel.Value.GuildId.IsSpecified | |||
? SocketGuildChannel.Create(Discord.GetGuild(channel.Value.GuildId.Value), Discord.State, channel.Value) | |||
: SocketDMChannel.Create(Discord, Discord.State, channel.Value); | |||
SocketChannel socketChannel = guild != null | |||
? guild.GetChannel(channel.Value.Id) | |||
: Discord.GetChannel(channel.Value.Id); | |||
if (socketChannel == null) | |||
{ | |||
var channelModel = guild != null | |||
? Discord.Rest.ApiClient.GetChannelAsync(guild.Id, channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult() | |||
: Discord.Rest.ApiClient.GetChannelAsync(channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult(); | |||
socketChannel = guild != null | |||
? SocketGuildChannel.Create(guild, Discord.State, channelModel) | |||
: (SocketChannel)SocketChannel.CreatePrivate(Discord, Discord.State, channelModel); | |||
} | |||
Discord.State.AddChannel(socketChannel); | |||
this.channels.Add(ulong.Parse(channel.Key), socketChannel); | |||
@@ -2,7 +2,7 @@ | |||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> | |||
<metadata> | |||
<id>Discord.Net.Labs</id> | |||
<version>2.4.2$suffix$</version> | |||
<version>2.4.3$suffix$</version> | |||
<title>Discord.Net Labs</title> | |||
<authors>Discord.Net Contributors</authors> | |||
<owners>quinchs</owners> | |||
@@ -15,22 +15,22 @@ | |||
<dependencies> | |||
<group targetFramework="net461"> | |||
<dependency id="Discord.Net.Labs.Core" version="2.4.1$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Rest" version="2.4.0$suffix$" /> | |||
<dependency id="Discord.Net.Labs.WebSocket" version="2.4.2$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Rest" version="2.4.2$suffix$" /> | |||
<dependency id="Discord.Net.Labs.WebSocket" version="2.4.3$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Commands" version="2.3.5$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Webhook" version="2.3.4$suffix$" /> | |||
</group> | |||
<group targetFramework="netstandard2.0"> | |||
<dependency id="Discord.Net.Labs.Core" version="2.4.1$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Rest" version="2.4.0$suffix$" /> | |||
<dependency id="Discord.Net.Labs.WebSocket" version="2.4.2$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Core" version="2.4.1$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Rest" version="2.4.2$suffix$" /> | |||
<dependency id="Discord.Net.Labs.WebSocket" version="2.4.3$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Commands" version="2.3.5$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Webhook" version="2.3.4$suffix$" /> | |||
</group> | |||
<group targetFramework="netstandard2.1"> | |||
<dependency id="Discord.Net.Labs.Core" version="2.4.1$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Rest" version="2.4.0$suffix$" /> | |||
<dependency id="Discord.Net.Labs.WebSocket" version="2.4.2$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Rest" version="2.4.2$suffix$" /> | |||
<dependency id="Discord.Net.Labs.WebSocket" version="2.4.3$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Commands" version="2.3.5$suffix$" /> | |||
<dependency id="Discord.Net.Labs.Webhook" version="2.3.4$suffix$" /> | |||
</group> | |||