From 57880de5b87d9f8afdc2852f11e6355023fe9fc4 Mon Sep 17 00:00:00 2001 From: Paulo Date: Mon, 15 Jun 2020 01:02:23 -0300 Subject: [PATCH] (ifcbrk) Add SearchUsersAsync (#1556) --- .../Entities/Guilds/IGuild.cs | 16 ++++++++++++ .../API/Rest/SearchGuildMembersParams.cs | 9 +++++++ src/Discord.Net.Rest/DiscordRestApiClient.cs | 16 ++++++++++++ .../Entities/Guilds/GuildHelper.cs | 11 ++++++++ .../Entities/Guilds/RestGuild.cs | 25 +++++++++++++++++++ .../Entities/Guilds/SocketGuild.cs | 25 +++++++++++++++++++ 6 files changed, 102 insertions(+) create mode 100644 src/Discord.Net.Rest/API/Rest/SearchGuildMembersParams.cs diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs index cdf0118c4..81b5e8dd9 100644 --- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs +++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs @@ -710,6 +710,22 @@ namespace Discord /// be or has been removed from this guild. /// Task PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null); + /// + /// Gets a collection of users in this guild that the name or nickname starts with the + /// provided at . + /// + /// + /// The can not be higher than . + /// + /// The partial name or nickname to search. + /// The maximum number of users to be gotten. + /// The that determines whether the object should be fetched from cache. + /// The options to be used when sending the request. + /// + /// A task that represents the asynchronous get operation. The task result contains a collection of guild + /// users that the name or nickname starts with the provided at . + /// + Task> SearchUsersAsync(string query, int limit = DiscordConfig.MaxUsersPerBatch, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); /// /// Gets the specified number of audit log entries for this guild. diff --git a/src/Discord.Net.Rest/API/Rest/SearchGuildMembersParams.cs b/src/Discord.Net.Rest/API/Rest/SearchGuildMembersParams.cs new file mode 100644 index 000000000..7c933ff82 --- /dev/null +++ b/src/Discord.Net.Rest/API/Rest/SearchGuildMembersParams.cs @@ -0,0 +1,9 @@ +#pragma warning disable CS1591 +namespace Discord.API.Rest +{ + internal class SearchGuildMembersParams + { + public string Query { get; set; } + public Optional Limit { get; set; } + } +} diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index 732cb5f17..49a256378 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -1136,6 +1136,22 @@ namespace Discord.API await SendJsonAsync("PATCH", () => $"guilds/{guildId}/members/{userId}", args, ids, options: options).ConfigureAwait(false); } } + public async Task> SearchGuildMembersAsync(ulong guildId, SearchGuildMembersParams args, RequestOptions options = null) + { + Preconditions.NotEqual(guildId, 0, nameof(guildId)); + Preconditions.NotNull(args, nameof(args)); + Preconditions.GreaterThan(args.Limit, 0, nameof(args.Limit)); + Preconditions.AtMost(args.Limit, DiscordConfig.MaxUsersPerBatch, nameof(args.Limit)); + Preconditions.NotNullOrEmpty(args.Query, nameof(args.Query)); + options = RequestOptions.CreateOrClone(options); + + int limit = args.Limit.GetValueOrDefault(DiscordConfig.MaxUsersPerBatch); + string query = args.Query; + + var ids = new BucketIds(guildId: guildId); + Expression> endpoint = () => $"guilds/{guildId}/members/search?limit={limit}&query={query}"; + return await SendAsync>("GET", endpoint, ids, options: options).ConfigureAwait(false); + } //Guild Roles public async Task> GetGuildRolesAsync(ulong guildId, RequestOptions options = null) diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs index 790b1e5c3..2b3219c21 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs @@ -387,6 +387,17 @@ namespace Discord.Rest model = await client.ApiClient.BeginGuildPruneAsync(guild.Id, args, options).ConfigureAwait(false); return model.Pruned; } + public static async Task> SearchUsersAsync(IGuild guild, BaseDiscordClient client, + string query, int? limit, RequestOptions options) + { + var apiArgs = new SearchGuildMembersParams + { + Query = query, + Limit = limit ?? Optional.Create() + }; + var models = await client.ApiClient.SearchGuildMembersAsync(guild.Id, apiArgs, options).ConfigureAwait(false); + return models.Select(x => RestGuildUser.Create(client, guild, x)).ToImmutableArray(); + } // Audit logs public static IAsyncEnumerable> GetAuditLogsAsync(IGuild guild, BaseDiscordClient client, diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs index 900f5045e..f0b5be0f7 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs @@ -634,6 +634,23 @@ namespace Discord.Rest public Task PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null) => GuildHelper.PruneUsersAsync(this, Discord, days, simulate, options); + /// + /// Gets a collection of users in this guild that the name or nickname starts with the + /// provided at . + /// + /// + /// The can not be higher than . + /// + /// The partial name or nickname to search. + /// The maximum number of users to be gotten. + /// The options to be used when sending the request. + /// + /// A task that represents the asynchronous get operation. The task result contains a collection of guild + /// users that the name or nickname starts with the provided at . + /// + public Task> SearchUsersAsync(string query, int limit = DiscordConfig.MaxUsersPerBatch, RequestOptions options = null) + => GuildHelper.SearchUsersAsync(this, Discord, query, limit, options); + //Audit logs /// /// Gets the specified number of audit log entries for this guild. @@ -884,6 +901,14 @@ namespace Discord.Rest /// Downloading users is not supported for a REST-based guild. Task IGuild.DownloadUsersAsync() => throw new NotSupportedException(); + /// + async Task> IGuild.SearchUsersAsync(string query, int limit, CacheMode mode, RequestOptions options) + { + if (mode == CacheMode.AllowDownload) + return await SearchUsersAsync(query, limit, options).ConfigureAwait(false); + else + return ImmutableArray.Create(); + } async Task> IGuild.GetAuditLogsAsync(int limit, CacheMode cacheMode, RequestOptions options, ulong? beforeId, ulong? userId, ActionType? actionType) diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs index cdba2b67d..d2d759bb3 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -850,6 +850,23 @@ namespace Discord.WebSocket _downloaderPromise.TrySetResultAsync(true); } + /// + /// Gets a collection of users in this guild that the name or nickname starts with the + /// provided at . + /// + /// + /// The can not be higher than . + /// + /// The partial name or nickname to search. + /// The maximum number of users to be gotten. + /// The options to be used when sending the request. + /// + /// A task that represents the asynchronous get operation. The task result contains a collection of guild + /// users that the name or nickname starts with the provided at . + /// + public Task> SearchUsersAsync(string query, int limit = DiscordConfig.MaxUsersPerBatch, RequestOptions options = null) + => GuildHelper.SearchUsersAsync(this, Discord, query, limit, options); + //Audit logs /// /// Gets the specified number of audit log entries for this guild. @@ -1224,6 +1241,14 @@ namespace Discord.WebSocket /// Task IGuild.GetOwnerAsync(CacheMode mode, RequestOptions options) => Task.FromResult(Owner); + /// + async Task> IGuild.SearchUsersAsync(string query, int limit, CacheMode mode, RequestOptions options) + { + if (mode == CacheMode.AllowDownload) + return await SearchUsersAsync(query, limit, options).ConfigureAwait(false); + else + return ImmutableArray.Create(); + } /// async Task> IGuild.GetAuditLogsAsync(int limit, CacheMode cacheMode, RequestOptions options,