Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Member search v2 #2931

Merged
merged 9 commits into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Discord.Net.Core/Entities/Guilds/IGuild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,7 @@ public interface IGuild : IDeletable, ISnowflakeEntity
/// be or has been removed from this guild.
/// </returns>
Task<int> PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null, IEnumerable<ulong> includeRoleIds = null);

/// <summary>
/// Gets a collection of users in this guild that the name or nickname starts with the
/// provided <see cref="string"/> at <paramref name="query"/>.
Expand All @@ -1104,6 +1105,11 @@ public interface IGuild : IDeletable, ISnowflakeEntity
/// </returns>
Task<IReadOnlyCollection<IGuildUser>> SearchUsersAsync(string query, int limit = DiscordConfig.MaxUsersPerBatch, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);

/// <summary>
/// Gets a collection of users in this guild that match the provided search criteria.
/// </summary>
Task<MemberSearchResult> SearchUsersAsyncV2(int limit = DiscordConfig.MaxUsersPerBatch, MemberSearchPropertiesV2 args = null, RequestOptions options = null);

/// <summary>
/// Gets the specified number of audit log entries for this guild.
/// </summary>
Expand Down
47 changes: 47 additions & 0 deletions src/Discord.Net.Core/Entities/Guilds/JoinSourceType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
namespace Discord;

/// <summary>
/// Represents the source of a user joining a guild.
/// </summary>
public enum JoinSourceType
{
/// <summary>
/// Unknown source.
/// </summary>
Unknown = 0,

/// <summary>
/// The user was invited by a bot.
/// </summary>
BotInvite = 1,

/// <summary>
/// The user was invited by an integration.
/// </summary>
Integration = 2,

/// <summary>
/// The user joined via server discovery.
/// </summary>
ServerDiscovery = 3,

/// <summary>
/// The user joined via the student hub.
/// </summary>
StudentHub = 4,

/// <summary>
/// The user joined via an invite code.
/// </summary>
InviteCode = 5,

/// <summary>
/// The user joined via a vanity URL.
/// </summary>
VanityUrl = 6,

/// <summary>
/// The user was manually verified
/// </summary>
ManualVerification = 7
}
183 changes: 183 additions & 0 deletions src/Discord.Net.Core/Entities/Guilds/MemberSearchPropertiesV2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Discord;


/// <summary>
/// Represents the properties for searching members in a guild.
/// </summary>
public class MemberSearchPropertiesV2
{
/// <summary>
/// Gets or sets the after property for the search.
/// </summary>
public MemberSearchPropertiesV2After After { get; set; }

/// <summary>
/// Gets or sets the sort type for the search.
/// </summary>
public MemberSearchV2SortType? Sort { get; set; }

/// <summary>
/// Gets or sets the and query for the search.
/// </summary>
public MemberSearchV2QueryParams? AndQuery { get; set; }

/// <summary>
/// Gets or sets the or query for the search.
/// </summary>
public MemberSearchV2QueryParams? OrQuery { get; set; }
}


/// <summary>
/// Represents the after property for searching members in a guild.
/// </summary>
public struct MemberSearchPropertiesV2After
{
/// <summary>
/// Gets or sets the user ID to search after.
/// </summary>
public ulong UserId { get; set; }

/// <summary>
/// Gets or sets the guild joined at timestamp to search after.
/// </summary>
public long GuildJoinedAt { get; set; }

public MemberSearchPropertiesV2After(ulong userId, long guildJoinedAt)
{
UserId = userId;
GuildJoinedAt = guildJoinedAt;
}

public MemberSearchPropertiesV2After(ulong userId, DateTimeOffset guildJoinedAt)
{
UserId = userId;
GuildJoinedAt = guildJoinedAt.ToUnixTimeMilliseconds();
}
}


/// <summary>
/// Represents the query parameters for searching members in a guild.
/// </summary>
public struct MemberSearchV2QueryParams
{
/// <summary>
/// Gets or sets the safety signal search properties.
/// </summary>
public MemberSearchV2SafetySignalsProperties? SafetySignals { get; set; }

/// <summary>
/// Gets or sets the role IDs to search for.
/// </summary>
public MemberSearchV2QueryProperties? RoleIds { get; set; }

/// <summary>
/// Gets or sets the range to search for the user ID.
/// </summary>
public MemberSearchV2RangeProperties? UserId { get; set; }

/// <summary>
/// Gets or sets the range to search for the user's guild joined at timestamp.
/// </summary>
public MemberSearchV2RangeProperties? GuildJoinedAt { get; set; }

/// <summary>
/// Gets or sets the source invite code to search for.
/// </summary>
public MemberSearchV2QueryProperties? SourceInviteCode { get; set; }

/// <summary>
/// Gets or sets the join source type to search for.
/// </summary>
public MemberSearchV2QueryProperties? JoinSourceType { get; set; }
}


/// <summary>
/// Represents the safety signal properties for searching members in a guild.
/// </summary>
public struct MemberSearchV2SafetySignalsProperties
{
/// <summary>
/// Gets or sets the unusual DM activity until property for the search.
/// </summary>
public MemberSearchV2SafetySignalProperties? UnusualDmActivityUntil { get; set; }

/// <summary>
/// Gets or sets the communication disabled until property for the search.
/// </summary>
public MemberSearchV2SafetySignalProperties? CommunicationDisabledUntil { get; set; }

/// <summary>
/// Gets or sets the unusual account activity property for the search.
/// </summary>
public bool? UnusualAccountActivity { get; set; }

/// <summary>
/// Gets or sets the automod quarantined username property for the search.
/// </summary>
public bool? AutomodQuarantinedUsername { get; set; }
}


/// <summary>
/// Represents the query properties for searching members in a guild.
/// </summary>
public readonly struct MemberSearchV2QueryProperties
{
/// <summary>
/// Gets the and query for the search.
/// </summary>
public Dictionary<int, object> AndQuery { get; }

/// <summary>
/// Gets the or query for the search.
/// </summary>
public Dictionary<int, object> OrQuery { get; }

public MemberSearchV2QueryProperties(Dictionary<int, string> andQuery, Dictionary<int, string> orQuery)
{
AndQuery = andQuery.Select(x => new KeyValuePair<int, object>(x.Key, x.Value)).ToDictionary();
OrQuery = orQuery.Select(x => new KeyValuePair<int, object>(x.Key, x.Value)).ToDictionary();
}

public MemberSearchV2QueryProperties(Dictionary<int, long> andQuery, Dictionary<int, long> orQuery)
{
AndQuery = andQuery.Select(x => new KeyValuePair<int, object>(x.Key, x.Value)).ToDictionary();
OrQuery = orQuery.Select(x => new KeyValuePair<int, object>(x.Key, x.Value)).ToDictionary();
}
}


/// <summary>
/// Represents the safety signal properties for searching members in a guild.
/// </summary>
public struct MemberSearchV2SafetySignalProperties
{
/// <summary>
/// Gets or sets the range for the search.
/// </summary>
public MemberSearchV2RangeProperties Range { get; set; }
}


/// <summary>
/// Represents the range properties for searching members in a guild.
/// </summary>
public struct MemberSearchV2RangeProperties
{
/// <summary>
/// Gets or sets the less than property for the search.
/// </summary>
public long? LessThanOrEqual { get; set; }

/// <summary>
/// Gets or sets the greater than property for the search.
/// </summary>
public long? GreaterThanOrEqual { get; set; }
}
45 changes: 45 additions & 0 deletions src/Discord.Net.Core/Entities/Guilds/MemberSearchResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Collections.Generic;
using System.Diagnostics;

namespace Discord;

public struct MemberSearchResult
{
public ulong GuildId { get; }

public IReadOnlyCollection<MemberSearchData> Members { get; }

public int PageResultCount { get; }

public int TotalResultCount { get; }

public MemberSearchResult(ulong guildId, IReadOnlyCollection<MemberSearchData> members, int pageResultCount, int totalResultCount)
{
GuildId = guildId;
Members = members;
PageResultCount = pageResultCount;
TotalResultCount = totalResultCount;
}
}

[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public readonly struct MemberSearchData
{
public IGuildUser User { get; }

public string SourceInviteCode { get; }

public JoinSourceType JoinSourceType { get; }

public ulong? InviterId { get; }

public MemberSearchData(IGuildUser user, string sourceInviteCode, JoinSourceType joinSourceType, ulong? inviterId)
{
User = user;
SourceInviteCode = sourceInviteCode;
JoinSourceType = joinSourceType;
InviterId = inviterId;
}

private string DebuggerDisplay => $"{User.Username} ({User.Id})";
}
27 changes: 27 additions & 0 deletions src/Discord.Net.Core/Entities/Guilds/MemberSearchV2SortType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace Discord;

/// <summary>
/// Represents the sort type for searching members in a guild.
/// </summary>
public enum MemberSearchV2SortType
{
/// <summary>
/// Sort by member since newest first.
/// </summary>
MemberSinceNewestFirst = 1,

/// <summary>
/// Sort by member since oldest first.
/// </summary>
MemberSinceOldestFirst = 2,

/// <summary>
/// Sort by joined discord since newest first.
/// </summary>
JoinedDiscordNewestFirst = 3,

/// <summary>
/// Sort by joined discord since oldest first.
/// </summary>
JoinedDiscordOldestFirst = 4,
}
18 changes: 18 additions & 0 deletions src/Discord.Net.Rest/API/Common/GuildMemberSearchResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Newtonsoft.Json;

namespace Discord.API;

internal class GuildMemberSearchResponse
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }

[JsonProperty("members")]
public GuildSearchMemberData[] Members { get; set; }

[JsonProperty("page_result_count")]
public int PageResultCount { get; set; }

[JsonProperty("total_result_count")]
public int TotalResultCount { get; set; }
}
18 changes: 18 additions & 0 deletions src/Discord.Net.Rest/API/Common/GuildSearchMemberData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Newtonsoft.Json;

namespace Discord.API;

internal class GuildSearchMemberData
{
[JsonProperty("member")]
public GuildMember Member { get; set; }

[JsonProperty("source_invite_code")]
public string InviteCode { get; set; }

[JsonProperty("join_source_type")]
public JoinSourceType JoinSourceType { get; set; }

[JsonProperty("inviter_id")]
public ulong? InviterId { get; set; }
}
Loading