From 7e3e971f96b673b19b916583056d23677b4fe98d Mon Sep 17 00:00:00 2001 From: Cenngo Date: Fri, 22 Jul 2022 14:43:47 +0300 Subject: [PATCH] add locale parameter to Get*ApplicationCommandsAsync methods for fetching localized command names/descriptions --- .../Entities/Guilds/IGuild.cs | 3 ++- src/Discord.Net.Core/IDiscordClient.cs | 3 ++- src/Discord.Net.Rest/BaseDiscordClient.cs | 2 +- src/Discord.Net.Rest/ClientHelper.cs | 8 ++++---- src/Discord.Net.Rest/DiscordRestApiClient.cs | 20 +++++++++++++++++-- src/Discord.Net.Rest/DiscordRestClient.cs | 12 +++++------ .../Entities/Guilds/GuildHelper.cs | 4 ++-- .../Entities/Guilds/RestGuild.cs | 16 +++++++++------ .../DiscordSocketClient.cs | 10 ++++++---- .../Entities/Guilds/SocketGuild.cs | 10 ++++++---- 10 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs index d58012d89..88255d56c 100644 --- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs +++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs @@ -1198,12 +1198,13 @@ namespace Discord /// Whether to include full localization dictionaries in the returned objects, /// instead of the localized name and description fields. /// + /// The target locale of the localized name and description fields. Sets X-Discord-Locale header, which takes precedence over Accept-Language. /// 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. /// - Task> GetApplicationCommandsAsync(bool withLocalizations = false, RequestOptions options = null); + Task> GetApplicationCommandsAsync(bool withLocalizations = false, string locale = null, RequestOptions options = null); /// /// Gets an application command within this guild with the specified id. diff --git a/src/Discord.Net.Core/IDiscordClient.cs b/src/Discord.Net.Core/IDiscordClient.cs index ed32b182a..dd1da3ae3 100644 --- a/src/Discord.Net.Core/IDiscordClient.cs +++ b/src/Discord.Net.Core/IDiscordClient.cs @@ -156,12 +156,13 @@ namespace Discord /// Gets a collection of all global commands. /// /// Whether to include full localization dictionaries in the returned objects, instead of the name localized and description localized fields. + /// The target locale of the localized name and description fields. Sets X-Discord-Locale header, which takes precedence over Accept-Language. /// 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(bool withLocalizations = false, RequestOptions options = null); + Task> GetGlobalApplicationCommandsAsync(bool withLocalizations = false, string locale = null, RequestOptions options = null); /// /// Creates a global application command. diff --git a/src/Discord.Net.Rest/BaseDiscordClient.cs b/src/Discord.Net.Rest/BaseDiscordClient.cs index 07f69d93c..adc93999e 100644 --- a/src/Discord.Net.Rest/BaseDiscordClient.cs +++ b/src/Discord.Net.Rest/BaseDiscordClient.cs @@ -243,7 +243,7 @@ namespace Discord.Rest => Task.FromResult(null); /// - Task> IDiscordClient.GetGlobalApplicationCommandsAsync(bool withLocalizations, RequestOptions options) + Task> IDiscordClient.GetGlobalApplicationCommandsAsync(bool withLocalizations, string locale, RequestOptions options) => Task.FromResult>(ImmutableArray.Create()); Task IDiscordClient.CreateGlobalApplicationCommand(ApplicationCommandProperties properties, RequestOptions options) => Task.FromResult(null); diff --git a/src/Discord.Net.Rest/ClientHelper.cs b/src/Discord.Net.Rest/ClientHelper.cs index 166e14de3..0c8f8c42f 100644 --- a/src/Discord.Net.Rest/ClientHelper.cs +++ b/src/Discord.Net.Rest/ClientHelper.cs @@ -195,9 +195,9 @@ namespace Discord.Rest } public static async Task> GetGlobalApplicationCommandsAsync(BaseDiscordClient client, bool withLocalizations = false, - RequestOptions options = null) + string locale = null, RequestOptions options = null) { - var response = await client.ApiClient.GetGlobalApplicationCommandsAsync(withLocalizations, options).ConfigureAwait(false); + var response = await client.ApiClient.GetGlobalApplicationCommandsAsync(withLocalizations, locale, options).ConfigureAwait(false); if (!response.Any()) return Array.Empty(); @@ -213,9 +213,9 @@ namespace Discord.Rest } public static async Task> GetGuildApplicationCommandsAsync(BaseDiscordClient client, ulong guildId, bool withLocalizations = false, - RequestOptions options = null) + string locale = null, RequestOptions options = null) { - var response = await client.ApiClient.GetGuildApplicationCommandsAsync(guildId, withLocalizations, options).ConfigureAwait(false); + var response = await client.ApiClient.GetGuildApplicationCommandsAsync(guildId, withLocalizations, locale, options).ConfigureAwait(false); if (!response.Any()) return ImmutableArray.Create(); diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index 714f602b7..faff1541e 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -1213,10 +1213,18 @@ namespace Discord.API #endregion #region Interactions - public async Task GetGlobalApplicationCommandsAsync(bool withLocalizations = false, RequestOptions options = null) + public async Task GetGlobalApplicationCommandsAsync(bool withLocalizations = false, string locale = null, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); + if (locale is not null) + { + if (!System.Text.RegularExpressions.Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) + throw new ArgumentException($"{locale} is not a valid locale.", nameof(locale)); + + options.RequestHeaders["X-Discord-Locale"] = new[] { locale }; + } + //with_localizations=false doesnt return localized names and descriptions return await SendAsync("GET", () => $"applications/{CurrentApplicationId}/commands{(withLocalizations ? "?with_localizations=true" : string.Empty)}", new BucketIds(), options: options).ConfigureAwait(false); @@ -1284,12 +1292,20 @@ namespace Discord.API return await SendJsonAsync("PUT", () => $"applications/{CurrentApplicationId}/commands", commands, new BucketIds(), options: options).ConfigureAwait(false); } - public async Task GetGuildApplicationCommandsAsync(ulong guildId, bool withLocalizations = false, RequestOptions options = null) + public async Task GetGuildApplicationCommandsAsync(ulong guildId, bool withLocalizations = false, string locale = null, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); var bucket = new BucketIds(guildId: guildId); + if (locale is not null) + { + if (!System.Text.RegularExpressions.Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) + throw new ArgumentException($"{locale} is not a valid locale.", nameof(locale)); + + options.RequestHeaders["X-Discord-Locale"] = new[] { locale }; + } + //with_localizations=false doesnt return localized names and descriptions return await SendAsync("GET", () => $"applications/{CurrentApplicationId}/commands{(withLocalizations ? "?with_localizations=true" : string.Empty)}", bucket, options: options).ConfigureAwait(false); diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs index c0f61295f..ddd38c5be 100644 --- a/src/Discord.Net.Rest/DiscordRestClient.cs +++ b/src/Discord.Net.Rest/DiscordRestClient.cs @@ -205,10 +205,10 @@ namespace Discord.Rest => ClientHelper.CreateGlobalApplicationCommandAsync(this, properties, options); public Task CreateGuildCommand(ApplicationCommandProperties properties, ulong guildId, RequestOptions options = null) => ClientHelper.CreateGuildApplicationCommandAsync(this, guildId, properties, options); - public Task> GetGlobalApplicationCommands(bool withLocalizations = false, RequestOptions options = null) - => ClientHelper.GetGlobalApplicationCommandsAsync(this, withLocalizations, options); - public Task> GetGuildApplicationCommands(ulong guildId, bool withLocalizations = false, RequestOptions options = null) - => ClientHelper.GetGuildApplicationCommandsAsync(this, guildId, withLocalizations, options); + public Task> GetGlobalApplicationCommands(bool withLocalizations = false, string locale = null, RequestOptions options = null) + => ClientHelper.GetGlobalApplicationCommandsAsync(this, withLocalizations, locale, options); + public Task> GetGuildApplicationCommands(ulong guildId, bool withLocalizations = false, string locale = null, RequestOptions options = null) + => ClientHelper.GetGuildApplicationCommandsAsync(this, guildId, withLocalizations, locale, options); public Task> BulkOverwriteGlobalCommands(ApplicationCommandProperties[] commandProperties, RequestOptions options = null) => ClientHelper.BulkOverwriteGlobalApplicationCommandAsync(this, commandProperties, options); public Task> BulkOverwriteGuildCommands(ApplicationCommandProperties[] commandProperties, ulong guildId, RequestOptions options = null) @@ -319,8 +319,8 @@ namespace Discord.Rest => await GetWebhookAsync(id, options).ConfigureAwait(false); /// - async Task> IDiscordClient.GetGlobalApplicationCommandsAsync(bool withLocalizations, RequestOptions options) - => await GetGlobalApplicationCommands(withLocalizations, options).ConfigureAwait(false); + async Task> IDiscordClient.GetGlobalApplicationCommandsAsync(bool withLocalizations, string locale, RequestOptions options) + => await GetGlobalApplicationCommands(withLocalizations, locale, options).ConfigureAwait(false); /// async Task IDiscordClient.GetGlobalApplicationCommandAsync(ulong id, RequestOptions options) => await ClientHelper.GetGlobalApplicationCommandAsync(this, id, options).ConfigureAwait(false); diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs index 402fbca14..1c340faed 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs @@ -363,9 +363,9 @@ namespace Discord.Rest #region Interactions public static async Task> GetSlashCommandsAsync(IGuild guild, BaseDiscordClient client, bool withLocalizations, - RequestOptions options) + string locale, RequestOptions options) { - var models = await client.ApiClient.GetGuildApplicationCommandsAsync(guild.Id, withLocalizations, options); + var models = await client.ApiClient.GetGuildApplicationCommandsAsync(guild.Id, withLocalizations, locale, options); return models.Select(x => RestGuildCommand.Create(client, x, guild.Id)).ToImmutableArray(); } public static async Task GetSlashCommandAsync(IGuild guild, ulong id, BaseDiscordClient client, diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs index 915747b4e..a7e6c0d23 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs @@ -311,13 +311,15 @@ namespace Discord.Rest /// /// Gets a collection of slash commands created by the current user in this guild. /// + /// Whether to include full localization dictionaries in the returned objects, instead of the name localized and description localized fields. + /// The target locale of the localized name and description fields. Sets X-Discord-Locale header, which takes precedence over Accept-Language. /// 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 /// slash commands created by the current user. /// - public Task> GetSlashCommandsAsync(bool withLocalizations = false, RequestOptions options = null) - => GuildHelper.GetSlashCommandsAsync(this, Discord, withLocalizations, options); + public Task> GetSlashCommandsAsync(bool withLocalizations = false, string locale = null, RequestOptions options = null) + => GuildHelper.GetSlashCommandsAsync(this, Discord, withLocalizations, locale, options); /// /// Gets a slash command in the current guild. @@ -928,13 +930,15 @@ namespace Discord.Rest /// /// Gets this guilds slash commands /// + /// Whether to include full localization dictionaries in the returned objects, instead of the name localized and description localized fields. + /// The target locale of the localized name and description fields. Sets X-Discord-Locale header, which takes precedence over Accept-Language. /// 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 (bool withLocalizations = false, RequestOptions options = null) - => await ClientHelper.GetGuildApplicationCommandsAsync(Discord, Id, withLocalizations, options).ConfigureAwait(false); + public async Task> GetApplicationCommandsAsync (bool withLocalizations = false, string locale = null, RequestOptions options = null) + => await ClientHelper.GetGuildApplicationCommandsAsync(Discord, Id, withLocalizations, locale, options).ConfigureAwait(false); /// /// Gets an application command within this guild with the specified id. /// @@ -1467,8 +1471,8 @@ namespace Discord.Rest async Task> IGuild.GetWebhooksAsync(RequestOptions options) => await GetWebhooksAsync(options).ConfigureAwait(false); /// - async Task> IGuild.GetApplicationCommandsAsync (bool withLocalizations, RequestOptions options) - => await GetApplicationCommandsAsync(withLocalizations, options).ConfigureAwait(false); + async Task> IGuild.GetApplicationCommandsAsync (bool withLocalizations, string locale, RequestOptions options) + => await GetApplicationCommandsAsync(withLocalizations, locale, options).ConfigureAwait(false); /// async Task IGuild.CreateStickerAsync(string name, string description, IEnumerable tags, Image image, RequestOptions options) => await CreateStickerAsync(name, description, tags, image, options); diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 2ad386d36..55426234b 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -450,14 +450,16 @@ namespace Discord.WebSocket /// /// Gets a collection of all global commands. /// + /// Whether to include full localization dictionaries in the returned objects, instead of the name localized and description localized fields. + /// The target locale of the localized name and description fields. Sets X-Discord-Locale header, which takes precedence over Accept-Language. /// 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(bool withLocalizations = false, RequestOptions options = null) + public async Task> GetGlobalApplicationCommandsAsync(bool withLocalizations = false, string locale = null, RequestOptions options = null) { - var commands = (await ApiClient.GetGlobalApplicationCommandsAsync(withLocalizations, options)).Select(x => SocketApplicationCommand.Create(this, x)); + var commands = (await ApiClient.GetGlobalApplicationCommandsAsync(withLocalizations, locale, options)).Select(x => SocketApplicationCommand.Create(this, x)); foreach(var command in commands) { @@ -3230,8 +3232,8 @@ namespace Discord.WebSocket async Task IDiscordClient.GetGlobalApplicationCommandAsync(ulong id, RequestOptions options) => await GetGlobalApplicationCommandAsync(id, options); /// - async Task> IDiscordClient.GetGlobalApplicationCommandsAsync(bool withLocalizations, RequestOptions options) - => await GetGlobalApplicationCommandsAsync(withLocalizations, options); + async Task> IDiscordClient.GetGlobalApplicationCommandsAsync(bool withLocalizations, string locale, RequestOptions options) + => await GetGlobalApplicationCommandsAsync(withLocalizations, locale, options); /// async Task IDiscordClient.StartAsync() diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs index ab8d39e07..a8535ca1d 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -877,14 +877,16 @@ namespace Discord.WebSocket /// /// Gets a collection of slash commands created by the current user in this guild. /// + /// Whether to include full localization dictionaries in the returned objects, instead of the name localized and description localized fields. + /// The target locale of the localized name and description fields. Sets X-Discord-Locale header, which takes precedence over Accept-Language. /// 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 /// slash commands created by the current user. /// - public async Task> GetApplicationCommandsAsync(bool withLocalizations = false, RequestOptions options = null) + public async Task> GetApplicationCommandsAsync(bool withLocalizations = false, string locale = null, RequestOptions options = null) { - var commands = (await Discord.ApiClient.GetGuildApplicationCommandsAsync(Id, withLocalizations, options)) + var commands = (await Discord.ApiClient.GetGuildApplicationCommandsAsync(Id, withLocalizations, locale, options)) .Select(x => SocketApplicationCommand.Create(Discord, x, Id)); foreach (var command in commands) @@ -1981,8 +1983,8 @@ namespace Discord.WebSocket async Task> IGuild.GetWebhooksAsync(RequestOptions options) => await GetWebhooksAsync(options).ConfigureAwait(false); /// - async Task> IGuild.GetApplicationCommandsAsync (bool withLocalizations, RequestOptions options) - => await GetApplicationCommandsAsync(withLocalizations, options).ConfigureAwait(false); + async Task> IGuild.GetApplicationCommandsAsync (bool withLocalizations, string locale, RequestOptions options) + => await GetApplicationCommandsAsync(withLocalizations, locale, options).ConfigureAwait(false); /// async Task IGuild.CreateStickerAsync(string name, string description, IEnumerable tags, Image image, RequestOptions options) => await CreateStickerAsync(name, description, tags, image, options);