diff --git a/src/Discord.Net.Core/Entities/AppSubscriptions/EntitlementType.cs b/src/Discord.Net.Core/Entities/AppSubscriptions/EntitlementType.cs index 6dac36761e..e6a23866d6 100644 --- a/src/Discord.Net.Core/Entities/AppSubscriptions/EntitlementType.cs +++ b/src/Discord.Net.Core/Entities/AppSubscriptions/EntitlementType.cs @@ -1,7 +1,45 @@ namespace Discord; +/// +/// Represents the type of entitlement. +/// public enum EntitlementType { + /// + /// The entitlement was purchased by user. + /// + Purchase = 1, + + /// + /// Entitlement for Discord Nitro subscription. + /// + PremiumSubscription = 2, + + /// + /// Entitlement was gifted by developer. + /// + DeveloperGift = 3, + + /// + /// Entitlement was purchased by a dev in application test mode. + /// + TestModePurchase = 4, + + /// + /// Entitlement was granted when the SKU was free. + /// + FreePurchase = 5, + + /// + /// Entitlement was gifted by another user. + /// + UserGift = 6, + + /// + /// Entitlement was claimed by user for free as a Nitro Subscriber. + /// + PremiumPurchase = 7, + /// /// The entitlement was purchased as an app subscription. /// diff --git a/src/Discord.Net.Core/Entities/AppSubscriptions/SKUFlags.cs b/src/Discord.Net.Core/Entities/AppSubscriptions/SKUFlags.cs index d748bf7b17..09e5a90ae4 100644 --- a/src/Discord.Net.Core/Entities/AppSubscriptions/SKUFlags.cs +++ b/src/Discord.Net.Core/Entities/AppSubscriptions/SKUFlags.cs @@ -2,10 +2,19 @@ namespace Discord; +/// +/// SKU flags for subscriptions. +/// [Flags] public enum SKUFlags { + /// + /// The SKU is a guild subscription. + /// GuildSubscription = 1 << 7, + /// + /// The SKU is a user subscription. + /// UserSubscription = 1 << 8 } diff --git a/src/Discord.Net.Core/Entities/AppSubscriptions/SKUType.cs b/src/Discord.Net.Core/Entities/AppSubscriptions/SKUType.cs index a15b6c598e..8adcf66c20 100644 --- a/src/Discord.Net.Core/Entities/AppSubscriptions/SKUType.cs +++ b/src/Discord.Net.Core/Entities/AppSubscriptions/SKUType.cs @@ -2,13 +2,23 @@ namespace Discord; public enum SKUType { + /// + /// Durable one-time purchase. + /// + Durable = 2, + + /// + /// Consumable one-time purchase. + /// + Consumable = 3, + /// /// Represents a recurring subscription. /// Subscription = 5, /// - /// System-generated group for each SKU created. + /// System-generated group for each SKU created. /// SubscriptionGroup = 6, } diff --git a/src/Discord.Net.Core/IDiscordClient.cs b/src/Discord.Net.Core/IDiscordClient.cs index a87a25c7a9..90562840da 100644 --- a/src/Discord.Net.Core/IDiscordClient.cs +++ b/src/Discord.Net.Core/IDiscordClient.cs @@ -349,5 +349,12 @@ IAsyncEnumerable> GetEntitlementsAsync(int? li /// Returns all SKUs for a given application. /// Task> GetSKUsAsync(RequestOptions options = null); + + /// + /// Marks a given one-time purchase entitlement for the user as consumed. + /// + /// The id of the entitlement. + /// The options to be used when sending the request. + Task ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options = null); } } diff --git a/src/Discord.Net.Rest/API/Common/Entitlement.cs b/src/Discord.Net.Rest/API/Common/Entitlement.cs index f12945e4da..01acabd685 100644 --- a/src/Discord.Net.Rest/API/Common/Entitlement.cs +++ b/src/Discord.Net.Rest/API/Common/Entitlement.cs @@ -24,7 +24,7 @@ internal class Entitlement public EntitlementType Type { get; set; } [JsonProperty("consumed")] - public bool IsConsumed { get; set; } + public Optional IsConsumed { get; set; } [JsonProperty("starts_at")] public Optional StartsAt { get; set; } diff --git a/src/Discord.Net.Rest/BaseDiscordClient.cs b/src/Discord.Net.Rest/BaseDiscordClient.cs index d385395373..d369050e72 100644 --- a/src/Discord.Net.Rest/BaseDiscordClient.cs +++ b/src/Discord.Net.Rest/BaseDiscordClient.cs @@ -292,6 +292,11 @@ IAsyncEnumerable> IDiscordClient.GetEntitlemen /// Task> IDiscordClient.GetSKUsAsync(RequestOptions options) => Task.FromResult>(Array.Empty()); + /// + /// Marks a given one-time purchase entitlement for the user as consumed. + /// + Task IDiscordClient.ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options) => Task.CompletedTask; + #endregion } } diff --git a/src/Discord.Net.Rest/ClientHelper.cs b/src/Discord.Net.Rest/ClientHelper.cs index 3d7d3c97b7..b660697a27 100644 --- a/src/Discord.Net.Rest/ClientHelper.cs +++ b/src/Discord.Net.Rest/ClientHelper.cs @@ -446,6 +446,9 @@ public static async Task> ListSKUsAsync(BaseDiscordClie return models.Select(x => new SKU(x.Id, x.Type, x.ApplicationId, x.Name, x.Slug)).ToImmutableArray(); } + public static Task ConsumeEntitlementAsync(BaseDiscordClient client, ulong entitlementId, RequestOptions options = null) + => client.ApiClient.ConsumeEntitlementAsync(entitlementId, options); + #endregion } } diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index 5c1b6c6233..b10efa928d 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -2828,6 +2828,9 @@ public Task ListEntitlementAsync(ListEntitlementsParams args, Req public Task ListSKUsAsync(RequestOptions options = null) => SendAsync("GET", () => $"applications/{CurrentApplicationId}/skus", new BucketIds(), options: options); + public Task ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options = null) + => SendAsync("POST", () => $"applications/{CurrentApplicationId}/entitlements/{entitlementId}/consume", new BucketIds(), options: options); + #endregion } } diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs index 4c8615db5e..0d5ae05843 100644 --- a/src/Discord.Net.Rest/DiscordRestClient.cs +++ b/src/Discord.Net.Rest/DiscordRestClient.cs @@ -296,6 +296,10 @@ public IAsyncEnumerable> GetEntitlementsAsync( public Task> GetSKUsAsync(RequestOptions options = null) => ClientHelper.ListSKUsAsync(this, options); + /// + public Task ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options = null) + => ClientHelper.ConsumeEntitlementAsync(this, entitlementId, options); + #endregion #region IDiscordClient diff --git a/src/Discord.Net.Rest/Entities/AppSubscriptions/RestEntitlement.cs b/src/Discord.Net.Rest/Entities/AppSubscriptions/RestEntitlement.cs index e1d2b61e90..5c7f70d8f4 100644 --- a/src/Discord.Net.Rest/Entities/AppSubscriptions/RestEntitlement.cs +++ b/src/Discord.Net.Rest/Entities/AppSubscriptions/RestEntitlement.cs @@ -55,7 +55,7 @@ internal void Update(Model model) : null; ApplicationId = model.ApplicationId; Type = model.Type; - IsConsumed = model.IsConsumed; + IsConsumed = model.IsConsumed.GetValueOrDefault(false); StartsAt = model.StartsAt.IsSpecified ? model.StartsAt.Value : null; diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 2001ae01db..0bb23a6dbe 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -447,6 +447,10 @@ public IAsyncEnumerable> GetEntitlementsAsync( public Task> GetSKUsAsync(RequestOptions options = null) => ClientHelper.ListSKUsAsync(this, options); + /// + public Task ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options = null) + => ClientHelper.ConsumeEntitlementAsync(this, entitlementId, options); + /// /// Gets entitlements from cache. /// diff --git a/src/Discord.Net.WebSocket/Entities/AppSubscriptions/SocketEntitlement.cs b/src/Discord.Net.WebSocket/Entities/AppSubscriptions/SocketEntitlement.cs index 0bfafe87d2..a4b71d9299 100644 --- a/src/Discord.Net.WebSocket/Entities/AppSubscriptions/SocketEntitlement.cs +++ b/src/Discord.Net.WebSocket/Entities/AppSubscriptions/SocketEntitlement.cs @@ -67,7 +67,7 @@ internal void Update(Model model) ApplicationId = model.ApplicationId; Type = model.Type; - IsConsumed = model.IsConsumed; + IsConsumed = model.IsConsumed.GetValueOrDefault(false); StartsAt = model.StartsAt.IsSpecified ? model.StartsAt.Value : null;