From abfa8d1751046660685f02134fd7feeeb839b3d7 Mon Sep 17 00:00:00 2001 From: Misha133 <61027276+Misha-133@users.noreply.github.com> Date: Mon, 27 Feb 2023 16:06:58 +0300 Subject: [PATCH] Missing invite properties (#2615) --- .../Entities/Guilds/IGuildScheduledEvent.cs | 5 ++++ src/Discord.Net.Core/Entities/IApplication.cs | 15 +++++++++++ .../Entities/Invites/IInvite.cs | 20 ++++++++++++-- .../API/Common/Application.cs | 9 +++++++ src/Discord.Net.Rest/API/Common/Invite.cs | 19 +++++++++++++- src/Discord.Net.Rest/ClientHelper.cs | 5 ++-- src/Discord.Net.Rest/DiscordRestApiClient.cs | 8 ++++-- src/Discord.Net.Rest/DiscordRestClient.cs | 4 +-- .../Entities/Guilds/RestGuildEvent.cs | 4 +++ .../Entities/Invites/RestInvite.cs | 26 +++++++++++++++++++ .../Entities/RestApplication.cs | 12 +++++++++ .../API/Gateway/InviteCreateEvent.cs | 8 +++++- src/Discord.Net.WebSocket/BaseSocketClient.cs | 5 ++-- .../Entities/Guilds/SocketGuildEvent.cs | 4 +++ .../Entities/Invites/SocketInvite.cs | 15 +++++++++++ 15 files changed, 146 insertions(+), 13 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuildScheduledEvent.cs b/src/Discord.Net.Core/Entities/Guilds/IGuildScheduledEvent.cs index 9cd89160..5c937f78 100644 --- a/src/Discord.Net.Core/Entities/Guilds/IGuildScheduledEvent.cs +++ b/src/Discord.Net.Core/Entities/Guilds/IGuildScheduledEvent.cs @@ -16,6 +16,11 @@ namespace Discord /// IGuild Guild { get; } + /// + /// Gets the id of the guild this event is scheduled in. + /// + ulong GuildId { get; } + /// /// Gets the optional channel id where this event will be hosted. /// diff --git a/src/Discord.Net.Core/Entities/IApplication.cs b/src/Discord.Net.Core/Entities/IApplication.cs index 8027d8d3..6aff992f 100644 --- a/src/Discord.Net.Core/Entities/IApplication.cs +++ b/src/Discord.Net.Core/Entities/IApplication.cs @@ -60,5 +60,20 @@ namespace Discord /// public string PrivacyPolicy { get; } + /// + /// Gets application's default custom authorization url. if disabled. + /// + public string CustomInstallUrl { get; } + + /// + /// Gets the application's role connection verification entry point. if not set. + /// + public string RoleConnectionsVerificationUrl { get; } + + /// + /// Gets the hex encoded key for verification in interactions. + /// + public string VerifyKey { get; } + } } diff --git a/src/Discord.Net.Core/Entities/Invites/IInvite.cs b/src/Discord.Net.Core/Entities/Invites/IInvite.cs index eb1f6a24..37a412f6 100644 --- a/src/Discord.Net.Core/Entities/Invites/IInvite.cs +++ b/src/Discord.Net.Core/Entities/Invites/IInvite.cs @@ -1,3 +1,5 @@ +using System; + namespace Discord { /// @@ -80,7 +82,7 @@ namespace Discord /// /// /// An representing the approximated online member count of the guild that the - /// invite points to; null if one cannot be obtained. + /// invite points to; if one cannot be obtained. /// int? PresenceCount { get; } /// @@ -88,7 +90,7 @@ namespace Discord /// /// /// An representing the approximated total member count of the guild that the - /// invite points to; null if one cannot be obtained. + /// invite points to; if one cannot be obtained. /// int? MemberCount { get; } /// @@ -105,5 +107,19 @@ namespace Discord /// The type of the linked user that is linked to this invite. /// TargetUserType TargetUserType { get; } + + /// + /// Gets the embedded application to open for this voice channel embedded application invite. + /// + /// + /// A partial object. if + /// is not . + /// + IApplication Application { get; } + + /// + /// Gets the expiration date of this invite. if the invite never expires. + /// + DateTimeOffset? ExpiresAt { get; } } } diff --git a/src/Discord.Net.Rest/API/Common/Application.cs b/src/Discord.Net.Rest/API/Common/Application.cs index 62a1d968..a6069310 100644 --- a/src/Discord.Net.Rest/API/Common/Application.cs +++ b/src/Discord.Net.Rest/API/Common/Application.cs @@ -32,5 +32,14 @@ namespace Discord.API public string TermsOfService { get; set; } [JsonProperty("privacy_policy_url")] public string PrivacyPolicy { get; set; } + + [JsonProperty("custom_install_url")] + public Optional CustomInstallUrl { get; set; } + + [JsonProperty("role_connections_verification_url")] + public Optional RoleConnectionsUrl { get; set; } + + [JsonProperty("verify_key")] + public string VerifyKey { get; set; } } } diff --git a/src/Discord.Net.Rest/API/Common/Invite.cs b/src/Discord.Net.Rest/API/Common/Invite.cs index f9d53bad..9e2e6b86 100644 --- a/src/Discord.Net.Rest/API/Common/Invite.cs +++ b/src/Discord.Net.Rest/API/Common/Invite.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using System; namespace Discord.API { @@ -6,19 +7,35 @@ namespace Discord.API { [JsonProperty("code")] public string Code { get; set; } + [JsonProperty("guild")] public Optional Guild { get; set; } + [JsonProperty("channel")] public InviteChannel Channel { get; set; } + [JsonProperty("inviter")] public Optional Inviter { get; set; } + [JsonProperty("approximate_presence_count")] public Optional PresenceCount { get; set; } + [JsonProperty("approximate_member_count")] public Optional MemberCount { get; set; } + [JsonProperty("target_user")] public Optional TargetUser { get; set; } - [JsonProperty("target_user_type")] + + [JsonProperty("target_type")] public Optional TargetUserType { get; set; } + + [JsonProperty("target_application")] + public Optional Application { get; set; } + + [JsonProperty("expires_at")] + public Optional ExpiresAt { get; set; } + + [JsonProperty("guild_scheduled_event")] + public Optional ScheduledEvent { get; set; } } } diff --git a/src/Discord.Net.Rest/ClientHelper.cs b/src/Discord.Net.Rest/ClientHelper.cs index 3950cd31..38919224 100644 --- a/src/Discord.Net.Rest/ClientHelper.cs +++ b/src/Discord.Net.Rest/ClientHelper.cs @@ -52,10 +52,9 @@ namespace Discord.Rest return models.Select(model => RestConnection.Create(client, model)).ToImmutableArray(); } - public static async Task GetInviteAsync(BaseDiscordClient client, - string inviteId, RequestOptions options) + public static async Task GetInviteAsync(BaseDiscordClient client, string inviteId, RequestOptions options, ulong? scheduledEventId = null) { - var model = await client.ApiClient.GetInviteAsync(inviteId, options).ConfigureAwait(false); + var model = await client.ApiClient.GetInviteAsync(inviteId, options, scheduledEventId).ConfigureAwait(false); if (model != null) return RestInviteMetadata.Create(client, null, null, model); return null; diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index fbe3ffd2..4a5ea199 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -1732,7 +1732,7 @@ namespace Discord.API #region Guild Invites /// cannot be blank. /// must not be . - public async Task GetInviteAsync(string inviteId, RequestOptions options = null) + public async Task GetInviteAsync(string inviteId, RequestOptions options = null, ulong? scheduledEventId = null) { Preconditions.NotNullOrEmpty(inviteId, nameof(inviteId)); options = RequestOptions.CreateOrClone(options); @@ -1745,9 +1745,13 @@ namespace Discord.API if (index >= 0) inviteId = inviteId.Substring(index + 1); + var scheduledEventQuery = scheduledEventId is not null + ? $"&guild_scheduled_event_id={scheduledEventId}" + : string.Empty; + try { - return await SendAsync("GET", () => $"invites/{inviteId}?with_counts=true", new BucketIds(), options: options).ConfigureAwait(false); + return await SendAsync("GET", () => $"invites/{inviteId}?with_counts=true&with_expiration=true{scheduledEventQuery}", new BucketIds(), options: options).ConfigureAwait(false); } catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } } diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs index 7e976cfc..e3860f07 100644 --- a/src/Discord.Net.Rest/DiscordRestClient.cs +++ b/src/Discord.Net.Rest/DiscordRestClient.cs @@ -182,8 +182,8 @@ namespace Discord.Rest public Task> GetConnectionsAsync(RequestOptions options = null) => ClientHelper.GetConnectionsAsync(this, options); - public Task GetInviteAsync(string inviteId, RequestOptions options = null) - => ClientHelper.GetInviteAsync(this, inviteId, options); + public Task GetInviteAsync(string inviteId, RequestOptions options = null, ulong? scheduledEventId = null) + => ClientHelper.GetInviteAsync(this, inviteId, options, scheduledEventId); public Task GetGuildAsync(ulong id, RequestOptions options = null) => ClientHelper.GetGuildAsync(this, id, false, options); diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuildEvent.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuildEvent.cs index 0b02e60b..39e63b2f 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/RestGuildEvent.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuildEvent.cs @@ -13,6 +13,9 @@ namespace Discord.Rest /// public IGuild Guild { get; private set; } + /// + public ulong GuildId { get; private set; } + /// public ulong? ChannelId { get; private set; } @@ -102,6 +105,7 @@ namespace Discord.Rest Location = model.EntityMetadata?.Location.GetValueOrDefault(); UserCount = model.UserCount.ToNullable(); CoverImageId = model.Image; + GuildId = model.GuildId; } /// diff --git a/src/Discord.Net.Rest/Entities/Invites/RestInvite.cs b/src/Discord.Net.Rest/Entities/Invites/RestInvite.cs index cec771d3..4f671937 100644 --- a/src/Discord.Net.Rest/Entities/Invites/RestInvite.cs +++ b/src/Discord.Net.Rest/Entities/Invites/RestInvite.cs @@ -38,6 +38,17 @@ namespace Discord.Rest /// public InviteGuild InviteGuild { get; private set; } + /// + public RestApplication Application { get; private set; } + + /// + public DateTimeOffset? ExpiresAt { get; private set; } + + /// + /// Gets guild scheduled event data. if event id was invalid. + /// + public RestGuildEvent ScheduledEvent { get; private set; } + internal IChannel Channel { get; } internal IGuild Guild { get; } @@ -97,6 +108,14 @@ namespace Discord.Rest ch.EmojiId.IsSpecified ? ch.EmojiId.Value : null)).ToImmutableArray()) : null); } + + if(model.Application.IsSpecified) + Application = RestApplication.Create(Discord, model.Application.Value); + + ExpiresAt = model.ExpiresAt.IsSpecified ? model.ExpiresAt.Value : null; + + if(model.ScheduledEvent.IsSpecified) + ScheduledEvent = RestGuildEvent.Create(Discord, Guild, model.ScheduledEvent.Value); } /// @@ -118,6 +137,8 @@ namespace Discord.Rest public override string ToString() => Url; private string DebuggerDisplay => $"{Url} ({GuildName} / {ChannelName})"; + #region IInvite + /// IGuild IInvite.Guild { @@ -140,5 +161,10 @@ namespace Discord.Rest throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); } } + + /// + IApplication IInvite.Application => Application; + + #endregion } } diff --git a/src/Discord.Net.Rest/Entities/RestApplication.cs b/src/Discord.Net.Rest/Entities/RestApplication.cs index a9a30ef7..eaaf8c27 100644 --- a/src/Discord.Net.Rest/Entities/RestApplication.cs +++ b/src/Discord.Net.Rest/Entities/RestApplication.cs @@ -35,6 +35,14 @@ namespace Discord.Rest public string TermsOfService { get; private set; } /// public string PrivacyPolicy { get; private set; } + + /// + public string VerifyKey { get; private set; } + /// + public string CustomInstallUrl { get; private set; } + /// + public string RoleConnectionsVerificationUrl { get; private set; } + /// public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); /// @@ -74,6 +82,10 @@ namespace Discord.Rest Owner = RestUser.Create(Discord, model.Owner.Value); if (model.Team != null) Team = RestTeam.Create(Discord, model.Team); + + CustomInstallUrl = model.CustomInstallUrl.IsSpecified ? model.CustomInstallUrl.Value : null; + RoleConnectionsVerificationUrl = model.RoleConnectionsUrl.IsSpecified ? model.RoleConnectionsUrl.Value : null; + VerifyKey = model.VerifyKey; } /// Unable to update this object from a different application token. diff --git a/src/Discord.Net.WebSocket/API/Gateway/InviteCreateEvent.cs b/src/Discord.Net.WebSocket/API/Gateway/InviteCreateEvent.cs index e2ddd881..013471c9 100644 --- a/src/Discord.Net.WebSocket/API/Gateway/InviteCreateEvent.cs +++ b/src/Discord.Net.WebSocket/API/Gateway/InviteCreateEvent.cs @@ -21,11 +21,17 @@ namespace Discord.API.Gateway public int MaxUses { get; set; } [JsonProperty("target_user")] public Optional TargetUser { get; set; } - [JsonProperty("target_user_type")] + [JsonProperty("target_type")] public Optional TargetUserType { get; set; } [JsonProperty("temporary")] public bool Temporary { get; set; } [JsonProperty("uses")] public int Uses { get; set; } + + [JsonProperty("target_application")] + public Optional Application { get; set; } + + [JsonProperty("expires_at")] + public Optional ExpiresAt { get; set; } } } diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.cs b/src/Discord.Net.WebSocket/BaseSocketClient.cs index 64c402e3..482a08a0 100644 --- a/src/Discord.Net.WebSocket/BaseSocketClient.cs +++ b/src/Discord.Net.WebSocket/BaseSocketClient.cs @@ -268,11 +268,12 @@ namespace Discord.WebSocket /// /// The invitation identifier. /// The options to be used when sending the request. + /// The id of the guild scheduled event to include with the invite. /// /// A task that represents the asynchronous get operation. The task result contains the invite information. /// - public Task GetInviteAsync(string inviteId, RequestOptions options = null) - => ClientHelper.GetInviteAsync(this, inviteId, options ?? RequestOptions.Default); + public Task GetInviteAsync(string inviteId, RequestOptions options = null, ulong? scheduledEventId = null) + => ClientHelper.GetInviteAsync(this, inviteId, options ?? RequestOptions.Default, scheduledEventId); /// /// Gets a sticker. /// diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuildEvent.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuildEvent.cs index 2a17143f..1be5e194 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuildEvent.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuildEvent.cs @@ -19,6 +19,9 @@ namespace Discord.WebSocket /// public SocketGuild Guild { get; private set; } + /// + public ulong GuildId { get; private set; } + /// /// Gets the channel of the event. /// @@ -113,6 +116,7 @@ namespace Discord.WebSocket Status = model.Status; UserCount = model.UserCount.ToNullable(); CoverImageId = model.Image; + GuildId = model.GuildId; } /// diff --git a/src/Discord.Net.WebSocket/Entities/Invites/SocketInvite.cs b/src/Discord.Net.WebSocket/Entities/Invites/SocketInvite.cs index 2b64e170..3d54c628 100644 --- a/src/Discord.Net.WebSocket/Entities/Invites/SocketInvite.cs +++ b/src/Discord.Net.WebSocket/Entities/Invites/SocketInvite.cs @@ -90,6 +90,12 @@ namespace Discord.WebSocket /// public TargetUserType TargetUserType { get; private set; } + /// + public RestApplication Application { get; private set; } + + /// + public DateTimeOffset? ExpiresAt { get; private set; } + /// public string Code => Id; /// @@ -119,6 +125,8 @@ namespace Discord.WebSocket Uses = model.Uses; _createdAtTicks = model.CreatedAt.UtcTicks; TargetUserType = model.TargetUserType.IsSpecified ? model.TargetUserType.Value : TargetUserType.Undefined; + ExpiresAt = model.ExpiresAt.IsSpecified ? model.ExpiresAt.Value : null; + Application = model.Application.IsSpecified ? RestApplication.Create(Discord, model.Application.Value) : null; } /// @@ -134,6 +142,8 @@ namespace Discord.WebSocket public override string ToString() => Url; private string DebuggerDisplay => $"{Url} ({Guild?.Name} / {Channel.Name})"; + #region IInvite + /// IGuild IInvite.Guild => Guild; /// @@ -142,5 +152,10 @@ namespace Discord.WebSocket IUser IInvite.Inviter => Inviter; /// IUser IInvite.TargetUser => TargetUser; + + /// + IApplication IInvite.Application => Application; + + #endregion } }