diff --git a/src/Discord.Net.Core/Discord.Net.Core.xml b/src/Discord.Net.Core/Discord.Net.Core.xml
index 187461b93..879e5613d 100644
--- a/src/Discord.Net.Core/Discord.Net.Core.xml
+++ b/src/Discord.Net.Core/Discord.Net.Core.xml
@@ -3916,7 +3916,7 @@
- Gets this guilds slash commands commands
+ Gets this guilds application commands.
The options to be used when sending the request.
@@ -3924,6 +3924,18 @@
of application commands found within the guild.
+
+
+ Gets an application command within this guild with the specified id.
+
+ The id of the application command to get.
+ The that determines whether the object should be fetched from cache.
+ The options to be used when sending the request.
+
+ A ValueTask that represents the asynchronous get operation. The task result contains a
+ if found, otherwise .
+
+
Holds information for a guild integration feature.
@@ -10971,6 +10983,27 @@
A task that represents the asynchronous get operation. The task result contains a read-only collection of connections.
+
+
+ Gets a global application command.
+
+ The id of the command.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous get operation. The task result contains the application command if found, otherwise
+ .
+
+
+
+
+ Gets a collection of all global commands.
+
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous get operation. The task result contains a read-only collection of global
+ application commands.
+
+
Gets a guild.
diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
index 414b6fe73..a94c1ed33 100644
--- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
@@ -943,7 +943,7 @@ namespace Discord
Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null);
///
- /// Gets this guilds slash commands commands
+ /// Gets this guilds application commands.
///
/// The options to be used when sending the request.
///
@@ -951,5 +951,18 @@ namespace Discord
/// of application commands found within the guild.
///
Task> GetApplicationCommandsAsync (RequestOptions options = null);
+
+ ///
+ /// Gets an application command within this guild with the specified id.
+ ///
+ /// The id of the application command to get.
+ /// The that determines whether the object should be fetched from cache.
+ /// The options to be used when sending the request.
+ ///
+ /// A ValueTask that represents the asynchronous get operation. The task result contains a
+ /// if found, otherwise .
+ ///
+ Task GetApplicationCommandAsync(ulong id, CacheMode mode = CacheMode.AllowDownload,
+ RequestOptions options = null);
}
}
diff --git a/src/Discord.Net.Core/IDiscordClient.cs b/src/Discord.Net.Core/IDiscordClient.cs
index d7d6d2856..a728e6096 100644
--- a/src/Discord.Net.Core/IDiscordClient.cs
+++ b/src/Discord.Net.Core/IDiscordClient.cs
@@ -141,6 +141,27 @@ namespace Discord
///
Task> GetConnectionsAsync(RequestOptions options = null);
+ ///
+ /// Gets a global application command.
+ ///
+ /// The id of the command.
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents the asynchronous get operation. The task result contains the application command if found, otherwise
+ /// .
+ ///
+ Task GetGlobalApplicationCommandAsync(ulong id, RequestOptions options = null);
+
+ ///
+ /// Gets a collection of all global commands.
+ ///
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents the asynchronous get operation. The task result contains a read-only collection of global
+ /// application commands.
+ ///
+ Task> GetGlobalApplicationCommandsAsync(RequestOptions options = null);
+
///
/// Gets a guild.
///
diff --git a/src/Discord.Net.Rest/BaseDiscordClient.cs b/src/Discord.Net.Rest/BaseDiscordClient.cs
index 68589a4f1..c94723281 100644
--- a/src/Discord.Net.Rest/BaseDiscordClient.cs
+++ b/src/Discord.Net.Rest/BaseDiscordClient.cs
@@ -216,6 +216,14 @@ namespace Discord.Rest
Task IDiscordClient.GetWebhookAsync(ulong id, RequestOptions options)
=> Task.FromResult(null);
+ ///
+ Task IDiscordClient.GetGlobalApplicationCommandAsync(ulong id, RequestOptions options)
+ => Task.FromResult(null);
+
+ ///
+ Task> IDiscordClient.GetGlobalApplicationCommandsAsync(RequestOptions options)
+ => Task.FromResult>(ImmutableArray.Create());
+
///
Task IDiscordClient.StartAsync()
=> Task.Delay(0);
diff --git a/src/Discord.Net.Rest/ClientHelper.cs b/src/Discord.Net.Rest/ClientHelper.cs
index 0161483c9..19c3b1325 100644
--- a/src/Discord.Net.Rest/ClientHelper.cs
+++ b/src/Discord.Net.Rest/ClientHelper.cs
@@ -194,7 +194,8 @@ namespace Discord.Rest
};
}
- public static async Task> GetGlobalApplicationCommands(BaseDiscordClient client, RequestOptions options)
+ public static async Task> GetGlobalApplicationCommands(BaseDiscordClient client,
+ RequestOptions options = null)
{
var response = await client.ApiClient.GetGlobalApplicationCommandsAsync(options).ConfigureAwait(false);
@@ -203,8 +204,16 @@ namespace Discord.Rest
return response.Select(x => RestGlobalCommand.Create(client, x)).ToArray();
}
+ public static async Task GetGlobalApplicationCommand(BaseDiscordClient client, ulong id,
+ RequestOptions options = null)
+ {
+ var model = await client.ApiClient.GetGlobalApplicationCommandAsync(id, options);
+
+ return model != null ? RestGlobalCommand.Create(client, model) : null;
+ }
- public static async Task> GetGuildApplicationCommands(BaseDiscordClient client, ulong guildId, RequestOptions options)
+ public static async Task> GetGuildApplicationCommands(BaseDiscordClient client, ulong guildId,
+ RequestOptions options = null)
{
var response = await client.ApiClient.GetGuildApplicationCommandsAsync(guildId, options).ConfigureAwait(false);
@@ -213,6 +222,13 @@ namespace Discord.Rest
return response.Select(x => RestGuildCommand.Create(client, x, guildId)).ToImmutableArray();
}
+ public static async Task GetGuildApplicationCommand(BaseDiscordClient client, ulong id, ulong guildId,
+ RequestOptions options = null)
+ {
+ var model = await client.ApiClient.GetGuildApplicationCommandAsync(guildId, id, options);
+
+ return model != null ? RestGuildCommand.Create(client, model, guildId) : null;
+ }
public static Task AddRoleAsync(BaseDiscordClient client, ulong guildId, ulong userId, ulong roleId, RequestOptions options = null)
diff --git a/src/Discord.Net.Rest/Discord.Net.Rest.xml b/src/Discord.Net.Rest/Discord.Net.Rest.xml
index 0378df092..2167ad1c5 100644
--- a/src/Discord.Net.Rest/Discord.Net.Rest.xml
+++ b/src/Discord.Net.Rest/Discord.Net.Rest.xml
@@ -226,6 +226,12 @@
+
+
+
+
+
+
@@ -299,6 +305,12 @@
+
+
+
+
+
+
Represents a configuration class for .
@@ -3503,6 +3515,17 @@
of application commands found within the guild.
+
+
+ Gets an application command within this guild with the specified id.
+
+ The id of the application command to get.
+ The options to be used when sending the request.
+
+ A ValueTask that represents the asynchronous get operation. The task result contains a
+ if found, otherwise .
+
+
Returns the name of the guild.
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index 8bf7f6e43..f73799943 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -1063,6 +1063,18 @@ namespace Discord.API
return await SendAsync("GET", () => $"applications/{this.CurrentUserId}/commands", new BucketIds(), options: options).ConfigureAwait(false);
}
+ public async Task GetGlobalApplicationCommandAsync(ulong id, RequestOptions options = null)
+ {
+ Preconditions.NotEqual(id, 0, nameof(id));
+
+ options = RequestOptions.CreateOrClone(options);
+
+ try
+ {
+ return await SendAsync("GET", () => $"applications/{this.CurrentUserId}/commands/{id}", new BucketIds(), options: options).ConfigureAwait(false);
+ }
+ catch(HttpException x) when (x.HttpCode == HttpStatusCode.NotFound) { return null; }
+ }
public async Task CreateGlobalApplicationCommandAsync(CreateApplicationCommandParams command, RequestOptions options = null)
{
@@ -1074,7 +1086,6 @@ namespace Discord.API
options = RequestOptions.CreateOrClone(options);
-
return await TrySendApplicationCommand(SendJsonAsync("POST", () => $"applications/{this.CurrentUserId}/commands", command, new BucketIds(), options: options)).ConfigureAwait(false);
}
public async Task ModifyGlobalApplicationCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null)
@@ -1158,7 +1169,11 @@ namespace Discord.API
var bucket = new BucketIds(guildId: guildId);
- return await SendAsync("GET", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", bucket, options: options);
+ try
+ {
+ return await SendAsync("GET", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", bucket, options: options);
+ }
+ catch(HttpException x) when (x.HttpCode == HttpStatusCode.NotFound) { return null; }
}
public async Task CreateGuildApplicationCommandAsync(CreateApplicationCommandParams command, ulong guildId, RequestOptions options = null)
@@ -1195,58 +1210,6 @@ namespace Discord.API
return await TrySendApplicationCommand(SendJsonAsync("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", commands, bucket, options: options)).ConfigureAwait(false);
}
- public async Task CreateGuildApplicationUserCommandAsync(CreateApplicationCommandParams command, ulong guildId, RequestOptions options = null)
- {
- options = RequestOptions.CreateOrClone(options);
-
- var bucket = new BucketIds(guildId: guildId);
-
- return await TrySendApplicationCommand(SendJsonAsync("POST", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", command, bucket, options: options)).ConfigureAwait(false);
- }
-
- public async Task ModifyGuildApplicationUserCommandAsync(ModifyApplicationCommandParams command, ulong guildId, ulong commandId, RequestOptions options = null)
- {
- options = RequestOptions.CreateOrClone(options);
-
- var bucket = new BucketIds(guildId: guildId);
-
- return await TrySendApplicationCommand(SendJsonAsync("PATCH", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", command, bucket, options: options)).ConfigureAwait(false);
- }
- public async Task BulkOverwriteGuildApplicationUserCommands(ulong guildId, CreateApplicationCommandParams[] commands, RequestOptions options = null)
- {
- options = RequestOptions.CreateOrClone(options);
-
- var bucket = new BucketIds(guildId: guildId);
-
- return await TrySendApplicationCommand(SendJsonAsync("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", commands, bucket, options: options)).ConfigureAwait(false);
- }
-
- public async Task CreateGuildApplicationMessageCommandAsync(CreateApplicationCommandParams command, ulong guildId, RequestOptions options = null)
- {
- options = RequestOptions.CreateOrClone(options);
-
- var bucket = new BucketIds(guildId: guildId);
-
- return await TrySendApplicationCommand(SendJsonAsync("POST", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", command, bucket, options: options)).ConfigureAwait(false);
- }
- public async Task ModifyGuildApplicationMessageCommandAsync(ModifyApplicationCommandParams command, ulong guildId, ulong commandId, RequestOptions options = null)
- {
- options = RequestOptions.CreateOrClone(options);
-
- var bucket = new BucketIds(guildId: guildId);
-
- return await TrySendApplicationCommand(SendJsonAsync("PATCH", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", command, bucket, options: options)).ConfigureAwait(false);
- }
-
- public async Task BulkOverwriteGuildApplicationMessageCommands(ulong guildId, CreateApplicationCommandParams[] commands, RequestOptions options = null)
- {
- options = RequestOptions.CreateOrClone(options);
-
- var bucket = new BucketIds(guildId: guildId);
-
- return await TrySendApplicationCommand(SendJsonAsync("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)
{
diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs
index 32dbaf40e..feef4c12a 100644
--- a/src/Discord.Net.Rest/DiscordRestClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestClient.cs
@@ -226,5 +226,12 @@ namespace Discord.Rest
///
async Task IDiscordClient.GetWebhookAsync(ulong id, RequestOptions options)
=> await GetWebhookAsync(id, options).ConfigureAwait(false);
+
+ ///
+ async Task> IDiscordClient.GetGlobalApplicationCommandsAsync(RequestOptions options)
+ => await GetGlobalApplicationCommands(options).ConfigureAwait(false);
+ ///
+ async Task IDiscordClient.GetGlobalApplicationCommandAsync(ulong id, RequestOptions options)
+ => await ClientHelper.GetGlobalApplicationCommand(this, id, options).ConfigureAwait(false);
}
}
diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
index 126a211c8..bf4365a5f 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
@@ -878,8 +878,19 @@ namespace Discord.Rest
/// A task that represents the asynchronous get operation. The task result contains a read-only collection
/// of application commands found within the guild.
///
- public async Task> GetApplicationCommandsAsync (RequestOptions options = null)
+ public async Task> GetApplicationCommandsAsync (RequestOptions options = null)
=> await ClientHelper.GetGuildApplicationCommands(Discord, Id, options).ConfigureAwait(false);
+ ///
+ /// Gets an application command within this guild with the specified id.
+ ///
+ /// The id of the application command to get.
+ /// The options to be used when sending the request.
+ ///
+ /// A ValueTask that represents the asynchronous get operation. The task result contains a
+ /// if found, otherwise .
+ ///
+ public async Task GetApplicationCommandAsync(ulong id, RequestOptions options = null)
+ => await ClientHelper.GetGuildApplicationCommand(Discord, id, this.Id, options);
///
/// Returns the name of the guild.
@@ -1169,5 +1180,14 @@ namespace Discord.Rest
///
async Task> IGuild.GetApplicationCommandsAsync (RequestOptions options)
=> await GetApplicationCommandsAsync(options).ConfigureAwait(false);
+ async Task IGuild.GetApplicationCommandAsync(ulong id, CacheMode mode, RequestOptions options)
+ {
+ if (mode == CacheMode.AllowDownload)
+ {
+ return await GetApplicationCommandAsync(id, options);
+ }
+ else
+ return null;
+ }
}
}
diff --git a/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs b/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
index fbbce4f4b..adf6226e2 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
@@ -44,12 +44,20 @@ namespace Discord.Rest
}
// Global commands
- public static async Task CreateGlobalCommand(BaseDiscordClient client,
- Action func, RequestOptions options) where TArg : ApplicationCommandProperties
+ public static async Task GetGlobalCommandAsync(BaseDiscordClient client, ulong id,
+ RequestOptions options = null)
+ {
+ var model = await client.ApiClient.GetGlobalApplicationCommandAsync(id, options).ConfigureAwait(false);
+
+
+ return RestGlobalCommand.Create(client, model);
+ }
+ public static Task CreateGlobalCommand(BaseDiscordClient client,
+ Action func, RequestOptions options = null) where TArg : ApplicationCommandProperties
{
var args = Activator.CreateInstance(typeof(TArg));
func((TArg)args);
- return await CreateGlobalCommand(client, (TArg)args, options);
+ return CreateGlobalCommand(client, (TArg)args, options);
}
public static async Task CreateGlobalCommand(BaseDiscordClient client,
ApplicationCommandProperties arg, RequestOptions options = null)
@@ -116,7 +124,7 @@ namespace Discord.Rest
models.Add(model);
}
- var apiModels = await client.ApiClient.BulkOverwriteGlobalApplicationCommands(models.ToArray(), options);
+ var apiModels = await client.ApiClient.BulkOverwriteGlobalApplicationCommands(models.ToArray(), options).ConfigureAwait(false);
return apiModels.Select(x => RestGlobalCommand.Create(client, x)).ToArray();
}
@@ -156,7 +164,7 @@ namespace Discord.Rest
models.Add(model);
}
- var apiModels = await client.ApiClient.BulkOverwriteGuildApplicationCommands(guildId, models.ToArray(), options);
+ var apiModels = await client.ApiClient.BulkOverwriteGuildApplicationCommands(guildId, models.ToArray(), options).ConfigureAwait(false);
return apiModels.Select(x => RestGuildCommand.Create(client, x, guildId)).ToArray();
}
@@ -221,12 +229,12 @@ namespace Discord.Rest
}
// Guild Commands
- public static async Task CreateGuildCommand(BaseDiscordClient client, ulong guildId,
+ public static Task CreateGuildCommand(BaseDiscordClient client, ulong guildId,
Action func, RequestOptions options) where TArg : ApplicationCommandProperties
{
var args = Activator.CreateInstance(typeof(TArg));
func((TArg)args);
- return await CreateGuildCommand(client, guildId, (TArg)args, options);
+ return CreateGuildCommand(client, guildId, (TArg)args, options);
}
public static async Task CreateGuildCommand(BaseDiscordClient client, ulong guildId,
diff --git a/src/Discord.Net.WebSocket/ClientState.cs b/src/Discord.Net.WebSocket/ClientState.cs
index f2e370d02..653eec4c8 100644
--- a/src/Discord.Net.WebSocket/ClientState.cs
+++ b/src/Discord.Net.WebSocket/ClientState.cs
@@ -16,12 +16,14 @@ namespace Discord.WebSocket
private readonly ConcurrentDictionary _guilds;
private readonly ConcurrentDictionary _users;
private readonly ConcurrentHashSet _groupChannels;
+ private readonly ConcurrentDictionary _commands;
internal IReadOnlyCollection Channels => _channels.ToReadOnlyCollection();
internal IReadOnlyCollection DMChannels => _dmChannels.ToReadOnlyCollection();
internal IReadOnlyCollection GroupChannels => _groupChannels.Select(x => GetChannel(x) as SocketGroupChannel).ToReadOnlyCollection(_groupChannels);
internal IReadOnlyCollection Guilds => _guilds.ToReadOnlyCollection();
internal IReadOnlyCollection Users => _users.ToReadOnlyCollection();
+ internal IReadOnlyCollection Commands => _commands.ToReadOnlyCollection();
internal IReadOnlyCollection PrivateChannels =>
_dmChannels.Select(x => x.Value as ISocketPrivateChannel).Concat(
@@ -139,5 +141,22 @@ namespace Discord.WebSocket
foreach (var guild in _guilds.Values)
guild.PurgeGuildUserCache();
}
+
+ internal SocketApplicationCommand GetCommand(ulong id)
+ {
+ if (_commands.TryGetValue(id, out SocketApplicationCommand command))
+ return command;
+ return null;
+ }
+ internal void AddCommand(SocketApplicationCommand command)
+ {
+ _commands[command.Id] = command;
+ }
+ internal SocketApplicationCommand RemoveCommand(ulong id)
+ {
+ if (_commands.TryRemove(id, out SocketApplicationCommand command))
+ return command;
+ return null;
+ }
}
}
diff --git a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml
index b2a823741..faacf90ab 100644
--- a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml
+++ b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml
@@ -1078,6 +1078,27 @@
+
+
+ Gets a global application command.
+
+ The id of the command.
+ The options to be used when sending the request.
+
+ A ValueTask that represents the asynchronous get operation. The task result contains the application command if found, otherwise
+ .
+
+
+
+
+ Gets a collection of all global commands.
+
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous get operation. The task result contains a read-only collection of global
+ application commands.
+
+
Clears cached users from the client.
@@ -1166,6 +1187,12 @@
+
+
+
+
+
+
diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
index 0da71faf2..53d712dbf 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
@@ -343,6 +343,54 @@ namespace Discord.WebSocket
///
public override SocketUser GetUser(string username, string discriminator)
=> State.Users.FirstOrDefault(x => x.Discriminator == discriminator && x.Username == username);
+
+ ///
+ /// Gets a global application command.
+ ///
+ /// The id of the command.
+ /// The options to be used when sending the request.
+ ///
+ /// A ValueTask that represents the asynchronous get operation. The task result contains the application command if found, otherwise
+ /// .
+ ///
+ public async ValueTask GetGlobalApplicationCommandAsync(ulong id, RequestOptions options = null)
+ {
+ var command = State.GetCommand(id);
+
+ if (command != null)
+ return command;
+
+ var model = await ApiClient.GetGlobalApplicationCommandAsync(id, options);
+
+ if (model == null)
+ return null;
+
+ command = SocketApplicationCommand.Create(this, model);
+
+ State.AddCommand(command);
+
+ return command;
+ }
+ ///
+ /// Gets a collection of all global commands.
+ ///
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents the asynchronous get operation. The task result contains a read-only collection of global
+ /// application commands.
+ ///
+ public async Task> GetGlobalApplicationCommandsAsync(RequestOptions options = null)
+ {
+ var commands = (await ApiClient.GetGlobalApplicationCommandsAsync(options)).Select(x => SocketApplicationCommand.Create(this, x));
+
+ foreach(var command in commands)
+ {
+ State.AddCommand(command);
+ }
+
+ return commands.ToImmutableArray();
+ }
+
///
/// Clears cached users from the client.
///
@@ -1891,8 +1939,6 @@ namespace Discord.WebSocket
{
await _gatewayLogger.DebugAsync("Received Dispatch (INTERACTION_CREATE)").ConfigureAwait(false);
- // 0x546861742062696720656e6469616e20656e636f64696e67206d616b6573206d79316d687a20636c6f636b207469636b
-
var data = (payload as JToken).ToObject(_serializer);
SocketChannel channel = null;
@@ -1958,6 +2004,8 @@ namespace Discord.WebSocket
var applicationCommand = SocketApplicationCommand.Create(this, data);
+ State.AddCommand(applicationCommand);
+
await TimedInvokeAsync(_applicationCommandCreated, nameof(ApplicationCommandCreated), applicationCommand).ConfigureAwait(false);
}
break;
@@ -1979,6 +2027,8 @@ namespace Discord.WebSocket
var applicationCommand = SocketApplicationCommand.Create(this, data);
+ State.AddCommand(applicationCommand);
+
await TimedInvokeAsync(_applicationCommandUpdated, nameof(ApplicationCommandUpdated), applicationCommand).ConfigureAwait(false);
}
break;
@@ -2000,6 +2050,8 @@ namespace Discord.WebSocket
var applicationCommand = SocketApplicationCommand.Create(this, data);
+ State.RemoveCommand(applicationCommand.Id);
+
await TimedInvokeAsync(_applicationCommandDeleted, nameof(ApplicationCommandDeleted), applicationCommand).ConfigureAwait(false);
}
break;
@@ -2611,6 +2663,13 @@ namespace Discord.WebSocket
async Task IDiscordClient.GetVoiceRegionAsync(string id, RequestOptions options)
=> await GetVoiceRegionAsync(id, options).ConfigureAwait(false);
+ ///
+ async Task IDiscordClient.GetGlobalApplicationCommandAsync(ulong id, RequestOptions options)
+ => await GetGlobalApplicationCommandAsync(id, options);
+ ///
+ async Task> IDiscordClient.GetGlobalApplicationCommandsAsync(RequestOptions options)
+ => await GetGlobalApplicationCommandsAsync(options);
+
///
async Task IDiscordClient.StartAsync()
=> await StartAsync().ConfigureAwait(false);
diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
index 5c385fe01..3b92e6a22 100644
--- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
+++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
@@ -785,13 +785,13 @@ namespace Discord.WebSocket
//Interactions
///
- /// Deletes all slash commands in the current guild.
+ /// Deletes all application commands in the current guild.
///
/// The options to be used when sending the request.
///
/// A task that represents the asynchronous delete operation.
///
- public Task DeleteSlashCommandsAsync(RequestOptions options = null)
+ public Task DeleteApplicationCommandsAsync(RequestOptions options = null)
=> InteractionHelper.DeleteAllGuildCommandsAsync(Discord, this.Id, options);
///
@@ -802,20 +802,39 @@ namespace Discord.WebSocket
/// A task that represents the asynchronous get operation. The task result contains a read-only collection of
/// slash commands created by the current user.
///
- public Task> GetSlashCommandsAsync(RequestOptions options = null)
- => GuildHelper.GetSlashCommandsAsync(this, Discord, options);
+ public async Task> GetApplicationCommandsAsync(RequestOptions options = null)
+ {
+ var commands = (await Discord.ApiClient.GetGuildApplicationCommandsAsync(this.Id, options)).Select(x => SocketApplicationCommand.Create(Discord, x));
- ///
- /// Gets a slash command in the current guild.
- ///
- /// The unique identifier of the slash command.
- /// The options to be used when sending the request.
- ///
- /// A task that represents the asynchronous get operation. The task result contains a
- /// slash command created by the current user.
- ///
- public Task GetSlashCommandAsync(ulong id, RequestOptions options = null)
- => GuildHelper.GetSlashCommandAsync(this, id, Discord, options);
+ foreach (var command in commands)
+ {
+ Discord.State.AddCommand(command);
+ }
+
+ return commands.ToImmutableArray();
+ }
+
+ public async ValueTask GetApplicationCommandAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null)
+ {
+ var command = Discord.State.GetCommand(id);
+
+ if (command != null)
+ return command;
+
+ if (mode == CacheMode.CacheOnly)
+ return null;
+
+ var model = await Discord.ApiClient.GetGlobalApplicationCommandAsync(id, options);
+
+ if (model == null)
+ return null;
+
+ command = SocketApplicationCommand.Create(Discord, model);
+
+ Discord.State.AddCommand(command);
+
+ return command;
+ }
//Invites
///
@@ -1079,18 +1098,6 @@ namespace Discord.WebSocket
public Task> GetWebhooksAsync(RequestOptions options = null)
=> GuildHelper.GetWebhooksAsync(this, Discord, options);
- //Interactions
- ///
- /// Gets this guilds slash commands commands
- ///
- /// The options to be used when sending the request.
- ///
- /// A task that represents the asynchronous get operation. The task result contains a read-only collection
- /// of application commands found within the guild.
- ///
- public async Task> GetApplicationCommandsAsync(RequestOptions options = null)
- => await Discord.Rest.GetGuildApplicationCommands(this.Id, options);
-
//Emotes
///
public Task> GetEmotesAsync(RequestOptions options = null)
@@ -1481,6 +1488,8 @@ namespace Discord.WebSocket
///
async Task> IGuild.GetApplicationCommandsAsync (RequestOptions options)
=> await GetApplicationCommandsAsync(options).ConfigureAwait(false);
+ async Task IGuild.GetApplicationCommandAsync(ulong id, CacheMode mode, RequestOptions options)
+ => await GetApplicationCommandAsync(id, mode, options);
void IDisposable.Dispose()
{
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandCache.cs b/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandCache.cs
deleted file mode 100644
index 7dd30151d..000000000
--- a/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandCache.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Discord.WebSocket.Entities.Interaction
-{
- internal class SlashCommandCache
- {
- private readonly ConcurrentDictionary _slashCommands;
- private readonly ConcurrentQueue _orderedSlashCommands;
- private readonly int _size;
-
- public IReadOnlyCollection Messages => _slashCommands.ToReadOnlyCollection();
-
- public SlashCommandCache(DiscordSocketClient client)
- {
- _size = 256;
- _slashCommands = new ConcurrentDictionary();
-
- }
-
- public void Add(SocketSlashCommand slashCommand)
- {
- if (_slashCommands.TryAdd(slashCommand.Id, slashCommand))
- {
- _orderedSlashCommands.Enqueue(slashCommand.Id);
-
- while (_orderedSlashCommands.Count > _size && _orderedSlashCommands.TryDequeue(out ulong msgId))
- _slashCommands.TryRemove(msgId, out _);
- }
- }
-
- public SocketSlashCommand Remove(ulong id)
- {
- _slashCommands.TryRemove(id, out var slashCommand);
- return slashCommand;
- }
-
- public SocketSlashCommand Get(ulong id)
- {
- _slashCommands.TryGetValue(id, out var slashCommands);
- return slashCommands;
- }
- }
-}
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs
index 8d4a4d485..77a43a1e3 100644
--- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs
+++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs
@@ -5,7 +5,8 @@ using System.Collections.Immutable;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Model = Discord.API.Gateway.ApplicationCommandCreatedUpdatedEvent;
+using GatewayModel = Discord.API.Gateway.ApplicationCommandCreatedUpdatedEvent;
+using Model = Discord.API.ApplicationCommand;
namespace Discord.WebSocket
{
@@ -60,14 +61,21 @@ namespace Discord.WebSocket
{
this.GuildId = guildId;
}
- internal static SocketApplicationCommand Create(DiscordSocketClient client, Model model)
+ internal static SocketApplicationCommand Create(DiscordSocketClient client, GatewayModel model)
{
var entity = new SocketApplicationCommand(client, model.Id, model.GuildId.ToNullable());
entity.Update(model);
return entity;
}
- internal void Update(API.ApplicationCommand model)
+ internal static SocketApplicationCommand Create(DiscordSocketClient client, Model model, ulong? guildId = null)
+ {
+ var entity = new SocketApplicationCommand(client, model.Id, guildId);
+ entity.Update(model);
+ return entity;
+ }
+
+ internal void Update(Model model)
{
this.ApplicationId = model.ApplicationId;
this.Description = model.Description;
@@ -102,7 +110,7 @@ namespace Discord.WebSocket
throw new InvalidOperationException($"Cannot modify this application command with the parameter type {nameof(TArg)}");
}
- API.ApplicationCommand command = null;
+ Model command = null;
if (this.IsGlobalCommand)
{