From f942cdd9c5edf3330c0ea8fef1b9e0a7deb01e3b Mon Sep 17 00:00:00 2001 From: "Tobias \"Syzuna\" Teske" Date: Fri, 17 Mar 2023 20:15:41 +0100 Subject: [PATCH 01/55] [skip-ci] Bump version to 3.10.0 --- TwitchLib.Api.Core.Enums/TwitchLib.Api.Core.Enums.csproj | 6 +++--- .../TwitchLib.Api.Core.Interfaces.csproj | 6 +++--- .../TwitchLib.Api.Core.Models.csproj | 6 +++--- TwitchLib.Api.Core/TwitchLib.Api.Core.csproj | 6 +++--- .../TwitchLib.Api.Helix.Models.csproj | 6 +++--- TwitchLib.Api.Helix/TwitchLib.Api.Helix.csproj | 6 +++--- TwitchLib.Api/TwitchLib.Api.csproj | 8 ++++---- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/TwitchLib.Api.Core.Enums/TwitchLib.Api.Core.Enums.csproj b/TwitchLib.Api.Core.Enums/TwitchLib.Api.Core.Enums.csproj index 2390ae24..221cab33 100644 --- a/TwitchLib.Api.Core.Enums/TwitchLib.Api.Core.Enums.csproj +++ b/TwitchLib.Api.Core.Enums/TwitchLib.Api.Core.Enums.csproj @@ -3,7 +3,7 @@ netstandard2.0 TwitchLib.Api.Core.Enums - 3.9.0 + 3.10.0 $(VersionSuffix) Project containing the enums of TwitchLib.Api true @@ -18,8 +18,8 @@ Git twitch library irc chat c# csharp api events pubsub net standard 2.0 en-US - 3.9.0 - 3.9.0 + 3.10.0 + 3.10.0 True diff --git a/TwitchLib.Api.Core.Interfaces/TwitchLib.Api.Core.Interfaces.csproj b/TwitchLib.Api.Core.Interfaces/TwitchLib.Api.Core.Interfaces.csproj index d839ef30..fe55d227 100644 --- a/TwitchLib.Api.Core.Interfaces/TwitchLib.Api.Core.Interfaces.csproj +++ b/TwitchLib.Api.Core.Interfaces/TwitchLib.Api.Core.Interfaces.csproj @@ -3,7 +3,7 @@ netstandard2.0 TwitchLib.Api.Core.Interfaces - 3.9.0 + 3.10.0 $(VersionSuffix) Project containing all of the interfaces used in TwitchLib.Api true @@ -18,8 +18,8 @@ Git twitch library irc chat c# csharp api events pubsub net standard 2.0 en-US - 3.9.0 - 3.9.0 + 3.10.0 + 3.10.0 True diff --git a/TwitchLib.Api.Core.Models/TwitchLib.Api.Core.Models.csproj b/TwitchLib.Api.Core.Models/TwitchLib.Api.Core.Models.csproj index e8e913ea..2a709f73 100644 --- a/TwitchLib.Api.Core.Models/TwitchLib.Api.Core.Models.csproj +++ b/TwitchLib.Api.Core.Models/TwitchLib.Api.Core.Models.csproj @@ -3,7 +3,7 @@ netstandard2.0 TwitchLib.Api.Core.Models - 3.9.0 + 3.10.0 $(VersionSuffix) Project containing the core models used in TwitchLib.Api true @@ -18,8 +18,8 @@ Git twitch library irc chat c# csharp api events pubsub net standard 2.0 en-US - 3.9.0 - 3.9.0 + 3.10.0 + 3.10.0 True diff --git a/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj b/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj index 62f0bb2e..f1c11827 100644 --- a/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj +++ b/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj @@ -3,7 +3,7 @@ netstandard2.0 TwitchLib.Api.Core - 3.9.0 + 3.10.0 $(VersionSuffix) Project containing the core of TwitchLib.Api true @@ -18,8 +18,8 @@ Git twitch library irc chat c# csharp api events pubsub net standard 2.0 en-US - 3.9.0 - 3.9.0 + 3.10.0 + 3.10.0 True diff --git a/TwitchLib.Api.Helix.Models/TwitchLib.Api.Helix.Models.csproj b/TwitchLib.Api.Helix.Models/TwitchLib.Api.Helix.Models.csproj index 8db0b3af..4a11874e 100644 --- a/TwitchLib.Api.Helix.Models/TwitchLib.Api.Helix.Models.csproj +++ b/TwitchLib.Api.Helix.Models/TwitchLib.Api.Helix.Models.csproj @@ -3,7 +3,7 @@ netstandard2.0 TwitchLib.Api.Helix.Models - 3.9.0 + 3.10.0 $(VersionSuffix) Project containing the Helix models used in TwitchLib.Api true @@ -18,8 +18,8 @@ Git twitch library irc chat c# csharp api events pubsub net standard 2.0 en-US - 3.9.0 - 3.9.0 + 3.10.0 + 3.10.0 True diff --git a/TwitchLib.Api.Helix/TwitchLib.Api.Helix.csproj b/TwitchLib.Api.Helix/TwitchLib.Api.Helix.csproj index 1a75c090..f7fed3d9 100644 --- a/TwitchLib.Api.Helix/TwitchLib.Api.Helix.csproj +++ b/TwitchLib.Api.Helix/TwitchLib.Api.Helix.csproj @@ -3,7 +3,7 @@ netstandard2.0 TwitchLib.Api.Helix - 3.9.0 + 3.10.0 $(VersionSuffix) Project containing the Helix section of TwitchLib.Api true @@ -18,8 +18,8 @@ Git twitch library irc chat c# csharp api events pubsub net standard 2.0 en-US - 3.9.0 - 3.9.0 + 3.10.0 + 3.10.0 True diff --git a/TwitchLib.Api/TwitchLib.Api.csproj b/TwitchLib.Api/TwitchLib.Api.csproj index ca3d26ef..f86c442f 100644 --- a/TwitchLib.Api/TwitchLib.Api.csproj +++ b/TwitchLib.Api/TwitchLib.Api.csproj @@ -3,7 +3,7 @@ netstandard2.0 TwitchLib.Api - 3.9.0 + 3.10.0 $(VersionSuffix) Api component of TwitchLib. This component allows you to access the Twitch API, as well as undocumented and third party APIs. true @@ -13,13 +13,13 @@ https://github.com/TwitchLib/TwitchLib.Api MIT Copyright 2022 - Updated dependencies, Added missing Auth subclass to ITwitchInterface, Added HttpResponse to Http related exceptions for better debugging, Added IgdbId to Games and added support for IgdbId lookup for Games, Added type parameter to GetStreams, Added tags to all related Stream models, Added UserId and UserName to GetChatters, Added GetCharityDonation support, Added Shield Mode support, Added Send Shoutout support, Added new Follower Endpoints support, Switched Follower Service to new Follwer rndpoint, Reason for BanUser now defaults to string.Empty, Fixed wrong Whisper Endpoint, Fixed wrong property name in CreateCustomRewards Request, Fixed issue with force_verify in generated Auth strings by GetAuthorizationCodeUrl, Fixed UpdateUserCall using the wrong HTTP method + https://github.com/swiftyspiffy/TwitchLib Git twitch library irc chat c# csharp api events pubsub net standard 2.0 en-US - 3.9.0 - 3.9.0 + 3.10.0 + 3.10.0 True From 4a58c3083fd10ff1ac2cfa956a9dc7a69bdc53b8 Mon Sep 17 00:00:00 2001 From: Proddy Date: Wed, 29 Mar 2023 13:12:55 +0100 Subject: [PATCH 02/55] Update ChatSettings.cs Primitive type `bool` defaults to `false` when not nullable. Making them nullable to prevent accidentally changing unwanted settings. --- .../Chat/ChatSettings/ChatSettings.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Chat/ChatSettings/ChatSettings.cs b/TwitchLib.Api.Helix.Models/Chat/ChatSettings/ChatSettings.cs index f8328623..54db8699 100644 --- a/TwitchLib.Api.Helix.Models/Chat/ChatSettings/ChatSettings.cs +++ b/TwitchLib.Api.Helix.Models/Chat/ChatSettings/ChatSettings.cs @@ -8,21 +8,21 @@ namespace TwitchLib.Api.Helix.Models.Chat.ChatSettings public class ChatSettings { [JsonProperty(PropertyName = "slow_mode")] - public bool SlowMode; + public bool? SlowMode; [JsonProperty(PropertyName = "slow_mode_wait_time")] public int? SlowModeWaitTime; [JsonProperty(PropertyName = "follower_mode")] - public bool FollowerMode; + public bool? FollowerMode; [JsonProperty(PropertyName = "follower_mode_duration")] public int? FollowerModeDuration; [JsonProperty(PropertyName = "subscriber_mode")] - public bool SubscriberMode; + public bool? SubscriberMode; [JsonProperty(PropertyName = "emote_mode")] - public bool EmoteMode; + public bool? EmoteMode; [JsonProperty(PropertyName = "unique_chat_mode")] - public bool UniqueChatMode; + public bool? UniqueChatMode; [JsonProperty(PropertyName = "non_moderator_chat_delay")] - public bool NonModeratorChatDelay; + public bool? NonModeratorChatDelay; [JsonProperty(PropertyName = "non_moderator_chat_delay_duration")] public int? NonModeratorChatDelayDuration; } From 5478c3f677da78fcc63a1f12722f3e56160cabbd Mon Sep 17 00:00:00 2001 From: Proddy Date: Fri, 31 Mar 2023 15:22:04 +0100 Subject: [PATCH 03/55] Update BadgeVersion.cs Add support for the new return information, see [this announcement](https://discuss.dev.twitch.tv/t/legacy-badges-endpoint-shutdown-details-and-timeline-june-2023/44621) Note: `ClickAction` and `ClickUrl` are nullable because twitch docs say set to `null` if not specified --- TwitchLib.Api.Helix.Models/Chat/Badges/BadgeVersion.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/TwitchLib.Api.Helix.Models/Chat/Badges/BadgeVersion.cs b/TwitchLib.Api.Helix.Models/Chat/Badges/BadgeVersion.cs index fa302eb1..7b7451ae 100644 --- a/TwitchLib.Api.Helix.Models/Chat/Badges/BadgeVersion.cs +++ b/TwitchLib.Api.Helix.Models/Chat/Badges/BadgeVersion.cs @@ -12,5 +12,13 @@ public class BadgeVersion public string ImageUrl2x { get; protected set; } [JsonProperty(PropertyName = "image_url_4x")] public string ImageUrl4x { get; protected set; } + [JsonProperty(PropertyName = "title")] + public string Title { get; protected set; } + [JsonProperty(PropertyName = "description")] + public string Description { get; protected set; } + [JsonProperty(PropertyName = "click_action")] + public string? ClickAction { get; protected set; } + [JsonProperty(PropertyName = "click_url")] + public string? ClickUrl { get; protected set; } } } From 81534cb61639979e0722c6a66a7e1aaa4b7bdf79 Mon Sep 17 00:00:00 2001 From: Proddy Date: Fri, 31 Mar 2023 15:24:49 +0100 Subject: [PATCH 04/55] Update BadgeVersion.cs Removing nullables because C# 7.3 --- TwitchLib.Api.Helix.Models/Chat/Badges/BadgeVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Chat/Badges/BadgeVersion.cs b/TwitchLib.Api.Helix.Models/Chat/Badges/BadgeVersion.cs index 7b7451ae..734aff6a 100644 --- a/TwitchLib.Api.Helix.Models/Chat/Badges/BadgeVersion.cs +++ b/TwitchLib.Api.Helix.Models/Chat/Badges/BadgeVersion.cs @@ -17,8 +17,8 @@ public class BadgeVersion [JsonProperty(PropertyName = "description")] public string Description { get; protected set; } [JsonProperty(PropertyName = "click_action")] - public string? ClickAction { get; protected set; } + public string ClickAction { get; protected set; } [JsonProperty(PropertyName = "click_url")] - public string? ClickUrl { get; protected set; } + public string ClickUrl { get; protected set; } } } From 5ca26f56aded8096017d9525f551e9a1bc7a7778 Mon Sep 17 00:00:00 2001 From: swiftyspiffy Date: Fri, 7 Apr 2023 22:58:24 +0800 Subject: [PATCH 05/55] remove Entitlements/GetCodeStatus and Entitlements/RedeemCode --- .../GetCodeStatus/GetCodeStatusResponse.cs | 10 ---- .../RedeemCode/RedeemCodeResponse.cs | 10 ---- TwitchLib.Api.Helix/Entitlements.cs | 60 ------------------- 3 files changed, 80 deletions(-) delete mode 100644 TwitchLib.Api.Helix.Models/Entitlements/GetCodeStatus/GetCodeStatusResponse.cs delete mode 100644 TwitchLib.Api.Helix.Models/Entitlements/RedeemCode/RedeemCodeResponse.cs diff --git a/TwitchLib.Api.Helix.Models/Entitlements/GetCodeStatus/GetCodeStatusResponse.cs b/TwitchLib.Api.Helix.Models/Entitlements/GetCodeStatus/GetCodeStatusResponse.cs deleted file mode 100644 index 66b2b690..00000000 --- a/TwitchLib.Api.Helix.Models/Entitlements/GetCodeStatus/GetCodeStatusResponse.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace TwitchLib.Api.Helix.Models.Entitlements.GetCodeStatus -{ - public class GetCodeStatusResponse - { - [JsonProperty(PropertyName = "data")] - public Status[] Data { get; protected set; } - } -} diff --git a/TwitchLib.Api.Helix.Models/Entitlements/RedeemCode/RedeemCodeResponse.cs b/TwitchLib.Api.Helix.Models/Entitlements/RedeemCode/RedeemCodeResponse.cs deleted file mode 100644 index 3297bd64..00000000 --- a/TwitchLib.Api.Helix.Models/Entitlements/RedeemCode/RedeemCodeResponse.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace TwitchLib.Api.Helix.Models.Entitlements.RedeemCode -{ - public class RedeemCodeResponse - { - [JsonProperty(PropertyName = "data")] - public Status[] Data { get; protected set; } - } -} diff --git a/TwitchLib.Api.Helix/Entitlements.cs b/TwitchLib.Api.Helix/Entitlements.cs index f306e8a8..577e0b89 100644 --- a/TwitchLib.Api.Helix/Entitlements.cs +++ b/TwitchLib.Api.Helix/Entitlements.cs @@ -1,14 +1,10 @@ using Newtonsoft.Json; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using TwitchLib.Api.Core; using TwitchLib.Api.Core.Enums; -using TwitchLib.Api.Core.Exceptions; using TwitchLib.Api.Core.Interfaces; -using TwitchLib.Api.Helix.Models.Entitlements.GetCodeStatus; using TwitchLib.Api.Helix.Models.Entitlements.GetDropsEntitlements; -using TwitchLib.Api.Helix.Models.Entitlements.RedeemCode; using TwitchLib.Api.Helix.Models.Entitlements.UpdateDropsEntitlements; namespace TwitchLib.Api.Helix @@ -22,39 +18,6 @@ public Entitlements(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHa { } - #region GetCodeStatus - /// - /// Gets the status of one or more provided codes. - /// This API requires that the caller is an authenticated Twitch user. - /// The API is throttled to one request per second per authenticated user. - /// - /// - /// The codes to get the status of. - /// 1-20 code parameters are allowed. - /// - /// The user account which is going to receive the entitlement associated with the code. - /// optional access token to override the use of the stored one in the TwitchAPI instance - /// - /// - public Task GetCodeStatusAsync(List codes, string userId, string accessToken = null) - { - if (codes == null || codes.Count == 0 || codes.Count > 20) - throw new BadParameterException("codes cannot be null and must have between 1 and 20 items"); - - if (userId == null) - throw new BadParameterException("userId cannot be null"); - - var getParams = new List>() - { - new KeyValuePair("user_id", userId) - }; - - getParams.AddRange(codes.Select(code => new KeyValuePair("code", code))); - - return TwitchPostGenericAsync("/entitlements/codes", ApiVersion.Helix, null, getParams, accessToken); - } - #endregion - #region GetDropsEntitlements /// /// Gets a list of entitlements for a given organization that have been granted to a game, user, or both. @@ -120,28 +83,5 @@ public Task UpdateDropsEntitlementsAsync(string #endregion - #region RedeemCode - /// - /// Redeems one or more redemption codes. - /// Redeeming a code credits the user’s account with the entitlement associated with the code. - /// For example, a Bits reward earned when playing a game. - /// Rate limit: You may send at most one request per second per user. - /// Only client IDs approved by Twitch may redeem codes on behalf of any Twitch user account. - /// - /// The redemption codes to redeem. You may specify a maximum of 20 codes. - /// optional access token to override the use of the stored one in the TwitchAPI instance - /// - /// - public Task RedeemCodeAsync(List codes, string accessToken = null) - { - if (codes == null || codes.Count == 0 || codes.Count > 20) - throw new BadParameterException("codes cannot be null and must have between 1 and 20 items"); - - var getParams = codes.Select(code => new KeyValuePair("code", code)).ToList(); - - return TwitchPostGenericAsync("/entitlements/codes", ApiVersion.Helix, null, getParams, accessToken); - } - #endregion - } } \ No newline at end of file From 59f3fbb0a7fbf84030f841258224f285bcbe921e Mon Sep 17 00:00:00 2001 From: swiftyspiffy Date: Fri, 7 Apr 2023 23:08:28 +0800 Subject: [PATCH 06/55] remove Streams/ReplaceStreamTags --- TwitchLib.Api.Helix/Streams.cs | 37 ---------------------------------- 1 file changed, 37 deletions(-) diff --git a/TwitchLib.Api.Helix/Streams.cs b/TwitchLib.Api.Helix/Streams.cs index f3612aaf..8329e88d 100644 --- a/TwitchLib.Api.Helix/Streams.cs +++ b/TwitchLib.Api.Helix/Streams.cs @@ -1,5 +1,4 @@ using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -102,42 +101,6 @@ public Task GetStreamTagsAsync(string broadcasterId, stri return TwitchGetGenericAsync("/streams/tags", ApiVersion.Helix, getParams, accessToken); } - /// - /// Applies one or more tags to the specified channel, overwriting any existing tags. - /// If the request does not specify tags, all existing tags are removed from the channel. - /// You may not specify automatic tags; the call will fail if you specify automatic tags. - /// Tags expire 72 hours after they are applied, unless the channel is live within that time period. - /// The expiration period is subject to change. - /// Requires a user OAuth access token with a scope of channel:manage:broadcast. - /// - /// The user ID of the channel to apply the tags to. - /// - /// A list of IDs that identify the tags to apply to the channel. - /// You may specify a maximum of five tags. - /// To remove all tags from the channel, set tagIds to an empty list / null. - /// - /// optional access token to override the use of the stored one in the TwitchAPI instance - /// - public Task ReplaceStreamTagsAsync(string broadcasterId, List tagIds = null, string accessToken = null) - { - var getParams = new List> - { - new KeyValuePair("broadcaster_id", broadcasterId) - }; - - string payload = null; - if (tagIds != null && tagIds.Count > 0) - { - var dynamicPayload = new JObject - { - { "tag_ids", new JArray(tagIds) } - }; - payload = dynamicPayload.ToString(); - } - - return TwitchPutAsync("/streams/tags", ApiVersion.Helix, payload, getParams, accessToken); - } - /// /// Gets the channel stream key for a user. /// Required scope: channel:read:stream_key From e1dc36fd31d579e8bfb28db2ac16440813f4a6a2 Mon Sep 17 00:00:00 2001 From: Elysia <116725056+koishibuh@users.noreply.github.com> Date: Thu, 13 Apr 2023 20:16:24 +0100 Subject: [PATCH 07/55] Updated CreatedMarker ID from int to string (Submitting this to the dev branch oops) Changed the type of CreatedMarker ID to match the Twitch API: https://dev.twitch.tv/docs/api/reference/#create-stream-marker When making a request to the TwitchAPI for creating a stream marker, I get an exception that it could not convert a string to an integer. --- .../Streams/CreateStreamMarker/CreatedMarker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TwitchLib.Api.Helix.Models/Streams/CreateStreamMarker/CreatedMarker.cs b/TwitchLib.Api.Helix.Models/Streams/CreateStreamMarker/CreatedMarker.cs index fdeb2656..5dc5d610 100644 --- a/TwitchLib.Api.Helix.Models/Streams/CreateStreamMarker/CreatedMarker.cs +++ b/TwitchLib.Api.Helix.Models/Streams/CreateStreamMarker/CreatedMarker.cs @@ -6,7 +6,7 @@ namespace TwitchLib.Api.Helix.Models.Streams.CreateStreamMarker public class CreatedMarker { [JsonProperty(PropertyName = "id")] - public int Id { get; protected set; } + public string Id { get; protected set; } [JsonProperty(PropertyName = "created_at")] public DateTime CreatedAt { get; protected set; } [JsonProperty(PropertyName = "description")] From 16ae8fe5ac9f49c6be65fba0917e88e560ef9c3f Mon Sep 17 00:00:00 2001 From: "Tobias \"Syzuna\" Teske" Date: Mon, 17 Apr 2023 21:56:16 +0200 Subject: [PATCH 08/55] hotfix compression support for Twitch API --- .../Internal/TwitchLibCustomHttpMessageHandler.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TwitchLib.Api.Core/Internal/TwitchLibCustomHttpMessageHandler.cs b/TwitchLib.Api.Core/Internal/TwitchLibCustomHttpMessageHandler.cs index 6c6ccf51..18d7b485 100644 --- a/TwitchLib.Api.Core/Internal/TwitchLibCustomHttpMessageHandler.cs +++ b/TwitchLib.Api.Core/Internal/TwitchLibCustomHttpMessageHandler.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -19,7 +20,7 @@ public class TwitchHttpClientHandler : DelegatingHandler /// Creates a new TwitchHttpClientHandler /// /// Logger to use for logging - public TwitchHttpClientHandler(ILogger logger) : base(new HttpClientHandler()) + public TwitchHttpClientHandler(ILogger logger) : base(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }) { _logger = logger; } From 76883c5e91e753c14e11993f267a4a2f11f52931 Mon Sep 17 00:00:00 2001 From: Mahsaap Date: Mon, 1 May 2023 13:21:30 -0300 Subject: [PATCH 09/55] Remove v5 from summary [skip ci] --- TwitchLib.Api/Auth/Auth.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TwitchLib.Api/Auth/Auth.cs b/TwitchLib.Api/Auth/Auth.cs index 0be63f6a..801352ab 100644 --- a/TwitchLib.Api/Auth/Auth.cs +++ b/TwitchLib.Api/Auth/Auth.cs @@ -8,7 +8,7 @@ namespace TwitchLib.Api.Auth { - /// These endpoints fall outside of v5 and Helix, and relate to Authorization + /// These endpoints fall outside of Helix, and relate to Authorization public class Auth : ApiBase { public Auth(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandler http) : base(settings, rateLimiter, http) From d22a61d400be46bb5afba7247d4bad7fed1d5e0e Mon Sep 17 00:00:00 2001 From: NioZero Date: Sat, 3 Jun 2023 23:13:24 -0400 Subject: [PATCH 10/55] Update Chat Auth invalid scope. According to the Reference, the correct scope is `channel:moderate` ref: https://dev.twitch.tv/docs/authentication/scopes/#chat-and-pubsub-scopes --- TwitchLib.Api.Core.Enums/AuthScopesEnum.cs | 2 +- TwitchLib.Api.Core/Common/Helpers.cs | 4 ++-- TwitchLib.Api/ThirdParty/AuthorizationFlow/PingResponse.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs b/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs index 7edc8c27..ae8008d7 100644 --- a/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs +++ b/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs @@ -13,7 +13,7 @@ public enum AuthScopes Channel_Subscriptions, Chat_Read, Chat_Edit, - Chat_Moderate, + Channel_Moderate, Collections_Edit, Communities_Edit, Communities_Moderate, diff --git a/TwitchLib.Api.Core/Common/Helpers.cs b/TwitchLib.Api.Core/Common/Helpers.cs index e8ed9e81..c10409b2 100644 --- a/TwitchLib.Api.Core/Common/Helpers.cs +++ b/TwitchLib.Api.Core/Common/Helpers.cs @@ -38,8 +38,8 @@ public static string AuthScopesToString(AuthScopes scope) return "channel_feed_read"; case AuthScopes.Chat_Read: return "chat:read"; - case AuthScopes.Chat_Moderate: - return "chat:moderate"; + case AuthScopes.Channel_Moderate: + return "channel:moderate"; case AuthScopes.Chat_Edit: return "chat:edit"; case AuthScopes.Channel_Read: diff --git a/TwitchLib.Api/ThirdParty/AuthorizationFlow/PingResponse.cs b/TwitchLib.Api/ThirdParty/AuthorizationFlow/PingResponse.cs index a7801a29..c7184e5a 100644 --- a/TwitchLib.Api/ThirdParty/AuthorizationFlow/PingResponse.cs +++ b/TwitchLib.Api/ThirdParty/AuthorizationFlow/PingResponse.cs @@ -68,7 +68,7 @@ private AuthScopes StringToScope(string scope) case "chat:edit": return AuthScopes.Chat_Edit; case "chat:moderate": - return AuthScopes.Chat_Moderate; + return AuthScopes.Channel_Moderate; case "channel_editor": return AuthScopes.Channel_Editor; case "channel_feed_read": From d914e12c183328ad79da82021acc454dac71900f Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 8 Jun 2023 14:39:34 +0100 Subject: [PATCH 11/55] - Added XML comments for the ChannelPoint Reward Models using the Twitch API documentation --- .../CreateCustomRewardsRequest.cs | 114 +++++++++--- .../CreateCustomRewardsResponse.cs | 16 +- .../ChannelPoints/CustomReward.cs | 175 +++++++++++++----- .../ChannelPoints/DefaultImage.cs | 31 +++- .../GetCustomRewardsResponse.cs | 16 +- .../GetCustomRewardRedemptionResponse.cs | 24 ++- .../ChannelPoints/GlobalCooldownSetting.cs | 24 ++- .../ChannelPoints/Image.cs | 32 +++- .../ChannelPoints/MaxPerStreamSetting.cs | 24 ++- .../MaxPerUserPerStreamSetting.cs | 24 ++- .../ChannelPoints/Reward.cs | 40 ++-- .../ChannelPoints/RewardRedemption.cs | 100 +++++++--- .../UpdateCustomRewardRequest.cs | 129 +++++++++---- .../UpdateCustomRewardResponse.cs | 16 +- ...dateCustomRewardRedemptionStatusRequest.cs | 18 +- ...ateCustomRewardRedemptionStatusResponse.cs | 17 +- 16 files changed, 584 insertions(+), 216 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsRequest.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsRequest.cs index 4e35755f..f83caabe 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsRequest.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsRequest.cs @@ -2,33 +2,89 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints.CreateCustomReward { - public class CreateCustomRewardsRequest - { - [JsonProperty(PropertyName = "title")] - public string Title { get; set; } - [JsonProperty(PropertyName = "prompt")] - public string Prompt { get; set; } - [JsonProperty(PropertyName = "cost")] - public int Cost { get; set; } - [JsonProperty(PropertyName = "is_enabled")] - public bool IsEnabled { get; set; } - [JsonProperty(PropertyName = "background_color")] - public string BackgroundColor { get; set; } - [JsonProperty(PropertyName = "is_user_input_required")] - public bool IsUserInputRequired { get; set; } - [JsonProperty(PropertyName = "is_max_per_stream_enabled")] - public bool IsMaxPerStreamEnabled { get; set; } - [JsonProperty(PropertyName = "max_per_stream")] - public int? MaxPerStream { get; set; } - [JsonProperty(PropertyName = "is_max_per_user_per_stream_enabled")] - public bool IsMaxPerUserPerStreamEnabled { get; set; } - [JsonProperty(PropertyName = "max_per_user_per_stream")] - public int? MaxPerUserPerStream { get; set; } - [JsonProperty(PropertyName = "is_global_cooldown_enabled")] - public bool IsGlobalCooldownEnabled { get; set; } - [JsonProperty(PropertyName = "global_cooldown_seconds")] - public int? GlobalCooldownSeconds { get; set; } - [JsonProperty(PropertyName = "should_redemptions_skip_request_queue")] - public bool ShouldRedemptionsSkipRequestQueue { get; set; } - } + /// + /// Creates a Custom Reward in the broadcaster’s channel. The maximum number of custom rewards per channel is 50, which includes both enabled and disabled rewards. + /// + /// Requires a user access token that includes the channel:manage:redemptions scope. + /// + public class CreateCustomRewardsRequest + { + /// + /// The custom reward’s title. The title may contain a maximum of 45 characters and it must be unique amongst all of the broadcaster’s custom rewards. + /// + [JsonProperty(PropertyName = "title")] + public string Title { get; set; } + + /// + /// The prompt shown to the viewer when they redeem the reward. Specify a prompt if IsUserInputRequired is true. The prompt is limited to a maximum of 200 characters. + /// + [JsonProperty(PropertyName = "prompt")] + public string Prompt { get; set; } + + /// + /// The cost of the reward, in Channel Points. The minimum is 1 point. + /// + [JsonProperty(PropertyName = "cost")] + public int Cost { get; set; } + + /// + /// A Boolean value that determines whether the reward is enabled. Viewers see only enabled rewards. The default is true. + /// + [JsonProperty(PropertyName = "is_enabled")] + public bool IsEnabled { get; set; } + + /// + /// The background color to use for the reward. Specify the color using Hex format (for example, #9147FF). + /// + [JsonProperty(PropertyName = "background_color")] + public string BackgroundColor { get; set; } + + /// + /// A Boolean value that determines whether the user needs to enter information when redeeming the reward. See the Prompt field. The default is false. + /// + [JsonProperty(PropertyName = "is_user_input_required")] + public bool IsUserInputRequired { get; set; } + + /// + /// A Boolean value that determines whether to limit the maximum number of redemptions allowed per live stream (see the MaxPerStream field). The default is false. + /// + [JsonProperty(PropertyName = "is_max_per_stream_enabled")] + public bool IsMaxPerStreamEnabled { get; set; } + + /// + /// The maximum number of redemptions allowed per live stream. Applied only if IsMaxPerStreamEnabled is true. The minimum value is 1. + /// + [JsonProperty(PropertyName = "max_per_stream")] + public int? MaxPerStream { get; set; } + + /// + /// A Boolean value that determines whether to limit the maximum number of redemptions allowed per user per stream (see the MaxPerUserPerStream field). The default is false. + /// + [JsonProperty(PropertyName = "is_max_per_user_per_stream_enabled")] + public bool IsMaxPerUserPerStreamEnabled { get; set; } + + /// + /// The maximum number of redemptions allowed per user per stream. Applied only if IsMaxPerUserPerStreamEnabled is true. The minimum value is 1. + /// + [JsonProperty(PropertyName = "max_per_user_per_stream")] + public int? MaxPerUserPerStream { get; set; } + + /// + /// A Boolean value that determines whether to apply a cooldown period between redemptions (see the GlobalCooldownSeconds field for the duration of the cooldown period). The default is false. + /// + [JsonProperty(PropertyName = "is_global_cooldown_enabled")] + public bool IsGlobalCooldownEnabled { get; set; } + + /// + /// The cooldown period, in seconds. Applied only if the IsGlobalCooldownEnabled field is true. The minimum value is 1; however, the minimum value is 60 for it to be shown in the Twitch UX. + /// + [JsonProperty(PropertyName = "global_cooldown_seconds")] + public int? GlobalCooldownSeconds { get; set; } + + /// + /// A Boolean value that determines whether redemptions should be set to FULFILLED status immediately when a reward is redeemed. If false, status is set to UNFULFILLED and follows the normal request queue process. The default is false. + /// + [JsonProperty(PropertyName = "should_redemptions_skip_request_queue")] + public bool ShouldRedemptionsSkipRequestQueue { get; set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsResponse.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsResponse.cs index 4138cd33..9a1da03a 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsResponse.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsResponse.cs @@ -2,9 +2,15 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints.CreateCustomReward { - public class CreateCustomRewardsResponse - { - [JsonProperty(PropertyName = "data")] - public CustomReward[] Data { get; protected set; } - } + /// + /// The response for creating a Custom Reward in the broadcaster’s channel. + /// + public class CreateCustomRewardsResponse + { + /// + /// A list that contains the single custom reward you created. + /// + [JsonProperty(PropertyName = "data")] + public CustomReward[] Data { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/CustomReward.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/CustomReward.cs index c3e881b3..b047e90d 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/CustomReward.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/CustomReward.cs @@ -2,47 +2,136 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints { - public class CustomReward - { - [JsonProperty(PropertyName = "broadcaster_id")] - public string BroadcasterId { get; protected set; } - [JsonProperty(PropertyName = "broadcaster_login")] - public string BroadcasterLogin { get; protected set; } - [JsonProperty(PropertyName = "broadcaster_name")] - public string BroadcasterName { get; protected set; } - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - [JsonProperty(PropertyName = "title")] - public string Title { get; protected set; } - [JsonProperty(PropertyName = "prompt")] - public string Prompt { get; protected set; } - [JsonProperty(PropertyName = "cost")] - public int Cost { get; protected set; } - [JsonProperty(PropertyName = "image")] - public Image Image { get; protected set; } - [JsonProperty(PropertyName = "default_image")] - public DefaultImage DefaultImage { get; protected set; } - [JsonProperty(PropertyName = "background_color")] - public string BackgroundColor { get; protected set; } - [JsonProperty(PropertyName = "is_enabled")] - public bool IsEnabled { get; protected set; } - [JsonProperty(PropertyName = "is_user_input_required")] - public bool IsUserInputRequired { get; protected set; } - [JsonProperty(PropertyName = "max_per_stream_setting")] - public MaxPerStreamSetting MaxPerStreamSetting { get; protected set; } - [JsonProperty(PropertyName = "max_per_user_per_stream_setting")] - public MaxPerUserPerStreamSetting MaxPerUserPerStreamSetting { get; protected set; } - [JsonProperty(PropertyName = "global_cooldown_setting")] - public GlobalCooldownSetting GlobalCooldownSetting { get; protected set; } - [JsonProperty(PropertyName = "is_paused")] - public bool IsPaused { get; protected set; } - [JsonProperty(PropertyName = "is_in_stock")] - public bool IsInStock { get; protected set; } - [JsonProperty(PropertyName = "should_redemptions_skip_request_queue")] - public bool ShouldRedemptionsSkipQueue { get; protected set; } - [JsonProperty(PropertyName = "redemptions_redeemed_current_stream")] - public int? RedemptionsRedeemedCurrentStream { get; protected set; } - [JsonProperty(PropertyName = "cooldown_expires_at")] - public string CooldownExpiresAt { get; protected set; } - } + /// + /// Custom reward that the specified broadcaster created. + /// + public class CustomReward + { + /// + /// The ID that uniquely identifies the broadcaster. + /// + [JsonProperty(PropertyName = "broadcaster_id")] + public string BroadcasterId { get; protected set; } + + /// + /// The broadcaster’s login name. (Name is lowercase) + /// + [JsonProperty(PropertyName = "broadcaster_login")] + public string BroadcasterLogin { get; protected set; } + + /// + /// The broadcaster’s display name. (Name has capitalization) + /// + [JsonProperty(PropertyName = "broadcaster_name")] + public string BroadcasterName { get; protected set; } + + /// + /// The ID that uniquely identifies this custom reward. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } + + /// + /// The title of the reward. + /// + [JsonProperty(PropertyName = "title")] + public string Title { get; protected set; } + + /// + /// The prompt shown to the viewer when they redeem the reward if user input is required (see the IsUserInputRequired field). + /// + [JsonProperty(PropertyName = "prompt")] + public string Prompt { get; protected set; } + + /// + /// The cost of the reward in Channel Points. + /// + [JsonProperty(PropertyName = "cost")] + public int Cost { get; protected set; } + + + /// + /// A set of custom images for the reward. This field is null if the broadcaster didn’t upload images. + /// + [JsonProperty(PropertyName = "image")] + public Image Image { get; protected set; } + + + /// + /// A set of default images for the reward. + /// + [JsonProperty(PropertyName = "default_image")] + public DefaultImage DefaultImage { get; protected set; } + + + /// + /// The background color to use for the reward. The color is in Hex format (for example, #00E5CB). + /// + [JsonProperty(PropertyName = "background_color")] + public string BackgroundColor { get; protected set; } + + + /// + /// A Boolean value that determines whether the reward is enabled. Is true if enabled; otherwise, false. Disabled rewards aren’t shown to the user. + /// + [JsonProperty(PropertyName = "is_enabled")] + public bool IsEnabled { get; protected set; } + + + /// + /// A Boolean value that determines whether the user must enter information when redeeming the reward. Is true if the user is prompted. + /// + [JsonProperty(PropertyName = "is_user_input_required")] + public bool IsUserInputRequired { get; protected set; } + + + /// + /// The settings used to determine whether to apply a maximum to the number of redemptions allowed per live stream. + /// + [JsonProperty(PropertyName = "max_per_stream_setting")] + public MaxPerStreamSetting MaxPerStreamSetting { get; protected set; } + + + /// + /// The settings used to determine whether to apply a maximum to the number of redemptions allowed per user per live stream. + /// + [JsonProperty(PropertyName = "max_per_user_per_stream_setting")] + public MaxPerUserPerStreamSetting MaxPerUserPerStreamSetting { get; protected set; } + + /// + /// The settings used to determine whether to apply a cooldown period between redemptions and the length of the cooldown. + /// + [JsonProperty(PropertyName = "global_cooldown_setting")] + public GlobalCooldownSetting GlobalCooldownSetting { get; protected set; } + + /// + /// A Boolean value that determines whether to pause the reward. Set to true to pause the reward. Viewers can’t redeem paused rewards, however the reward will still be visible with "Reward is temporarily unavailable. Check back for it soon." message. + /// + [JsonProperty(PropertyName = "is_paused")] + public bool IsPaused { get; protected set; } + + /// + /// A Boolean value that determines whether the reward is currently in stock. Is true if the reward is in stock. Viewers can’t redeem out of stock rewards. + /// + [JsonProperty(PropertyName = "is_in_stock")] + public bool IsInStock { get; protected set; } + + /// + /// A Boolean value that determines whether redemptions should be set to FULFILLED status immediately when a reward is redeemed. If false, status is set to UNFULFILLED and follows the normal request queue process. + /// + [JsonProperty(PropertyName = "should_redemptions_skip_request_queue")] + public bool ShouldRedemptionsSkipQueue { get; protected set; } + + /// + /// The number of redemptions redeemed during the current live stream. The number counts against the MaxPerStreamSetting limit. This field is null if the broadcaster’s stream isn’t live or MaxPerStreamSetting isn’t enabled. + /// + [JsonProperty(PropertyName = "redemptions_redeemed_current_stream")] + public int? RedemptionsRedeemedCurrentStream { get; protected set; } + + /// + /// The timestamp of when the cooldown period expires. Is null if the reward isn’t in a cooldown state. See the GlobalCooldownSetting field. + /// + [JsonProperty(PropertyName = "cooldown_expires_at")] + public string CooldownExpiresAt { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/DefaultImage.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/DefaultImage.cs index 89735a8d..a433c7a3 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/DefaultImage.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/DefaultImage.cs @@ -2,14 +2,27 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints { - public class DefaultImage - { + /// + /// A set of default images for the reward. + /// + public class DefaultImage + { + /// + /// The URL to a small version of the image. + /// + [JsonProperty(PropertyName = "url_1x")] + public string Url1x { get; } - [JsonProperty(PropertyName = "url_1x")] - public string Url1x { get; } - [JsonProperty(PropertyName = "url_2x")] - public string Url2x { get; } - [JsonProperty(PropertyName = "url_4x")] - public string Url4x { get; } - } + /// + /// The URL to a medium version of the image. + /// + [JsonProperty(PropertyName = "url_2x")] + public string Url2x { get; } + + /// + /// The URL to a large version of the image. + /// + [JsonProperty(PropertyName = "url_4x")] + public string Url4x { get; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/GetCustomReward/GetCustomRewardsResponse.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/GetCustomReward/GetCustomRewardsResponse.cs index 17ea01e6..6daeb872 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/GetCustomReward/GetCustomRewardsResponse.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/GetCustomReward/GetCustomRewardsResponse.cs @@ -2,9 +2,15 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints.GetCustomReward { - public class GetCustomRewardsResponse - { - [JsonProperty(PropertyName = "data")] - public CustomReward[] Data { get; protected set; } - } + /// + /// The response for getting a list of custom rewards that the specified broadcaster created. + /// + public class GetCustomRewardsResponse + { + /// + /// A list of custom rewards. The list is in ascending order by id. If the broadcaster hasn’t created custom rewards, the list is empty. + /// + [JsonProperty(PropertyName = "data")] + public CustomReward[] Data { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/GetCustomRewardRedemption/GetCustomRewardRedemptionResponse.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/GetCustomRewardRedemption/GetCustomRewardRedemptionResponse.cs index 791deae7..5d129c02 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/GetCustomRewardRedemption/GetCustomRewardRedemptionResponse.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/GetCustomRewardRedemption/GetCustomRewardRedemptionResponse.cs @@ -3,11 +3,21 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints.GetCustomRewardRedemption { - public class GetCustomRewardRedemptionResponse - { - [JsonProperty(PropertyName = "data")] - public RewardRedemption[] Data { get; protected set; } - [JsonProperty(PropertyName = "pagination")] - public Pagination Pagination { get; protected set; } - } + /// + /// The response for getting a list of redemptions for a custom reward. + /// + public class GetCustomRewardRedemptionResponse + { + /// + /// The list of redemptions for the specified reward. The list is empty if there are no redemptions that match the redemption criteria. + /// + [JsonProperty(PropertyName = "data")] + public RewardRedemption[] Data { get; protected set; } + + /// + /// + /// + [JsonProperty(PropertyName = "pagination")] + public Pagination Pagination { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/GlobalCooldownSetting.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/GlobalCooldownSetting.cs index e4f82ddf..fa3416ca 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/GlobalCooldownSetting.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/GlobalCooldownSetting.cs @@ -2,11 +2,21 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints { - public class GlobalCooldownSetting - { - [JsonProperty(PropertyName = "is_enabled")] - public bool IsEnabled { get; protected set; } - [JsonProperty(PropertyName = "global_cooldown_seconds")] - public int GlobalCooldownSeconds { get; protected set; } - } + /// + /// The settings used to determine whether to apply a cooldown period between redemptions and the length of the cooldown. + /// + public class GlobalCooldownSetting + { + /// + /// A Boolean value that determines whether to apply a cooldown period. Is true if a cooldown period is enabled. + /// + [JsonProperty(PropertyName = "is_enabled")] + public bool IsEnabled { get; protected set; } + + /// + /// The cooldown period, in seconds. + /// + [JsonProperty(PropertyName = "global_cooldown_seconds")] + public int GlobalCooldownSeconds { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/Image.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/Image.cs index 2144009d..b68d84cf 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/Image.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/Image.cs @@ -2,13 +2,27 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints { - public class Image - { - [JsonProperty(PropertyName = "url_1x")] - public string Url1x { get; protected set; } - [JsonProperty(PropertyName = "url_2x")] - public string Url2x { get; protected set; } - [JsonProperty(PropertyName = "url_4x")] - public string Url4x { get; protected set; } - } + /// + /// A set of custom images for the reward. This field is null if the broadcaster didn’t upload images. + /// + public class Image + { + /// + /// The URL to a small version of the image. + /// + [JsonProperty(PropertyName = "url_1x")] + public string Url1x { get; protected set; } + + /// + /// The URL to a medium version of the image. + /// + [JsonProperty(PropertyName = "url_2x")] + public string Url2x { get; protected set; } + + /// + /// The URL to a large version of the image. + /// + [JsonProperty(PropertyName = "url_4x")] + public string Url4x { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/MaxPerStreamSetting.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/MaxPerStreamSetting.cs index 4c84f0d0..f11c35c2 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/MaxPerStreamSetting.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/MaxPerStreamSetting.cs @@ -2,11 +2,21 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints { - public class MaxPerStreamSetting - { - [JsonProperty(PropertyName = "is_enabled")] - public bool IsEnabled { get; protected set; } - [JsonProperty(PropertyName = "max_per_stream")] - public int MaxPerStream { get; protected set; } - } + /// + /// The settings used to determine whether to apply a maximum to the number of redemptions allowed per live stream. + /// + public class MaxPerStreamSetting + { + /// + /// A Boolean value that determines whether the reward applies a limit on the number of redemptions allowed per live stream. Is true if the reward applies a limit. + /// + [JsonProperty(PropertyName = "is_enabled")] + public bool IsEnabled { get; protected set; } + + /// + /// The maximum number of redemptions allowed per live stream. + /// + [JsonProperty(PropertyName = "max_per_stream")] + public int MaxPerStream { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/MaxPerUserPerStreamSetting.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/MaxPerUserPerStreamSetting.cs index 8354097c..301ba6a6 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/MaxPerUserPerStreamSetting.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/MaxPerUserPerStreamSetting.cs @@ -2,11 +2,21 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints { - public class MaxPerUserPerStreamSetting - { - [JsonProperty(PropertyName = "is_enabled")] - public bool IsEnabled { get; protected set; } - [JsonProperty(PropertyName = "max_per_user_per_stream")] - public int MaxPerUserPerStream { get; protected set; } - } + /// + /// The settings used to determine whether to apply a maximum to the number of redemptions allowed per user per live stream. + /// + public class MaxPerUserPerStreamSetting + { + /// + /// A Boolean value that determines whether the reward applies a limit on the number of redemptions allowed per user per live stream. Is true if the reward applies a limit. + /// + [JsonProperty(PropertyName = "is_enabled")] + public bool IsEnabled { get; protected set; } + + /// + /// The maximum number of redemptions allowed per user per live stream. + /// + [JsonProperty(PropertyName = "max_per_user_per_stream")] + public int MaxPerUserPerStream { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/Reward.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/Reward.cs index a0ef3406..0d4da674 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/Reward.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/Reward.cs @@ -2,15 +2,33 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints { - public class Reward - { - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - [JsonProperty(PropertyName = "title")] - public string Title { get; protected set; } - [JsonProperty(PropertyName = "prompt")] - public string Prompt { get; protected set; } - [JsonProperty(PropertyName = "cost")] - public int Cost { get; protected set; } - } + /// + /// The reward that the user redeemed. + /// + public class Reward + { + /// + /// The ID that uniquely identifies the redeemed reward. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } + + /// + /// The reward’s title. + /// + [JsonProperty(PropertyName = "title")] + public string Title { get; protected set; } + + /// + /// The prompt displayed to the viewer if user input is required. + /// + [JsonProperty(PropertyName = "prompt")] + public string Prompt { get; protected set; } + + /// + /// The reward’s cost, in Channel Points. + /// + [JsonProperty(PropertyName = "cost")] + public int Cost { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/RewardRedemption.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/RewardRedemption.cs index ff872623..c29abc0a 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/RewardRedemption.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/RewardRedemption.cs @@ -1,32 +1,78 @@ -using System; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System; using TwitchLib.Api.Core.Enums; namespace TwitchLib.Api.Helix.Models.ChannelPoints { - public class RewardRedemption - { - [JsonProperty(PropertyName = "broadcaster_id")] - public string BroadcasterId { get; protected set; } - [JsonProperty(PropertyName = "broadcaster_login")] - public string BroadcasterLogin { get; protected set; } - [JsonProperty(PropertyName = "broadcaster_name")] - public string BroadcasterName { get; protected set; } - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - [JsonProperty(PropertyName = "user_id")] - public string UserId { get; protected set; } - [JsonProperty(PropertyName = "user_login")] - public string UserLogin { get; protected set; } - [JsonProperty(PropertyName = "user_name")] - public string UserName { get; protected set; } - [JsonProperty(PropertyName = "user_input")] - public string UserInput { get; protected set; } - [JsonProperty(PropertyName = "status")] - public CustomRewardRedemptionStatus Status { get; protected set; } - [JsonProperty(PropertyName = "redeemed_at")] - public DateTime RedeemedAt { get; protected set; } - [JsonProperty(PropertyName = "reward")] - public Reward Reward { get; protected set; } - } + /// + /// A redemption for a custom reward. + /// + public class RewardRedemption + { + /// + /// The ID that uniquely identifies the broadcaster. + /// + [JsonProperty(PropertyName = "broadcaster_id")] + public string BroadcasterId { get; protected set; } + + /// + /// The broadcaster’s login name. (Name is lowercase) + /// + [JsonProperty(PropertyName = "broadcaster_login")] + public string BroadcasterLogin { get; protected set; } + + /// + /// The broadcaster’s display name. (Name has capitalization) + /// + [JsonProperty(PropertyName = "broadcaster_name")] + public string BroadcasterName { get; protected set; } + + /// + /// The ID that uniquely identifies this redemption. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } + + /// + /// The ID that uniquely identifies the user that redeemed the reward. + /// + [JsonProperty(PropertyName = "user_id")] + public string UserId { get; protected set; } + + /// + /// The user’s login name. (Name is lowercase) + /// + [JsonProperty(PropertyName = "user_login")] + public string UserLogin { get; protected set; } + + /// + /// The user’s display name. (Name has capitalization) + /// + [JsonProperty(PropertyName = "user_name")] + public string UserName { get; protected set; } + + /// + /// The text that the user entered at the prompt when they redeemed the reward; otherwise, an empty string if user input was not required. + /// + [JsonProperty(PropertyName = "user_input")] + public string UserInput { get; protected set; } + + /// + /// The state of the redemption. Possible values are: CANCELED, FULFILLED, UNFULFILLED + /// + [JsonProperty(PropertyName = "status")] + public CustomRewardRedemptionStatus Status { get; protected set; } + + /// + /// The date and time of when the reward was redeemed. + /// + [JsonProperty(PropertyName = "redeemed_at")] + public DateTime RedeemedAt { get; protected set; } + + /// + /// The reward that the user redeemed. + /// + [JsonProperty(PropertyName = "reward")] + public Reward Reward { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs index 3fe620c4..84521966 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs @@ -2,38 +2,99 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints.UpdateCustomReward { - [JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)] - public class UpdateCustomRewardRequest - { - [JsonProperty(PropertyName = "broadcaster_id")] - public string BroadcasterId { get; set; } - [JsonProperty(PropertyName = "title")] - public string Title { get; set; } - [JsonProperty(PropertyName = "prompt")] - public string Prompt { get; set; } - [JsonProperty(PropertyName = "cost")] - public int? Cost { get; set; } - [JsonProperty(PropertyName = "is_enabled")] - public bool? IsEnabled { get; set; } - [JsonProperty(PropertyName = "background_color")] - public string BackgroundColor { get; set; } - [JsonProperty(PropertyName = "is_user_input_required")] - public bool? IsUserInputRequired { get; set; } - [JsonProperty(PropertyName = "is_max_per_stream_enabled")] - public bool? IsMaxPerStreamEnabled { get; set; } - [JsonProperty(PropertyName = "max_per_stream")] - public int? MaxPerStream { get; set; } - [JsonProperty(PropertyName = "is_max_per_user_per_stream_enabled")] - public bool? IsMaxPerUserPerStreamEnabled { get; set; } - [JsonProperty(PropertyName = "max_per_user_per_stream")] - public int? MaxPerUserPerStream { get; set; } - [JsonProperty(PropertyName = "is_global_cooldown_enabled")] - public bool? IsGlobalCooldownEnabled { get; set; } - [JsonProperty(PropertyName = "global_cooldown_seconds")] - public int? GlobalCooldownSeconds { get; set; } - [JsonProperty(PropertyName = "is_paused")] - public bool? IsPaused { get; set; } - [JsonProperty(PropertyName = "should_redemptions_skip_request_queue")] - public bool? ShouldRedemptionsSkipRequestQueue { get; set; } - } + /// + /// Updates a custom reward. The app used to create the reward is the only app that may update the reward. + /// + /// Requires a user access token that includes the channel:manage:redemptions scope. + /// + [JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)] + public class UpdateCustomRewardRequest + { + [JsonProperty(PropertyName = "broadcaster_id")] + public string BroadcasterId { get; set; } + + /// + /// The reward’s title. The title may contain a maximum of 45 characters and it must be unique amongst all of the broadcaster’s custom rewards. + /// + [JsonProperty(PropertyName = "title")] + public string Title { get; set; } + + /// + /// The prompt shown to the viewer when they redeem the reward. Specify a prompt if IsUserInputRequired is true. The prompt is limited to a maximum of 200 characters. + /// + [JsonProperty(PropertyName = "prompt")] + public string Prompt { get; set; } + + /// + /// The cost of the reward, in channel points. The minimum is 1 point. + /// + [JsonProperty(PropertyName = "cost")] + public int? Cost { get; set; } + + /// + /// A Boolean value that indicates whether the reward is enabled. Set to true to enable the reward. Viewers see only enabled rewards. + /// + [JsonProperty(PropertyName = "is_enabled")] + public bool? IsEnabled { get; set; } + + /// + /// The background color to use for the reward. Specify the color using Hex format (for example, #00E5CB). + /// + [JsonProperty(PropertyName = "background_color")] + public string BackgroundColor { get; set; } + + /// + /// A Boolean value that determines whether users must enter information to redeem the reward. Set to true if user input is required. See the Prompt field. + /// + [JsonProperty(PropertyName = "is_user_input_required")] + public bool? IsUserInputRequired { get; set; } + + /// + /// A Boolean value that determines whether to limit the maximum number of redemptions allowed per live stream (see the MaxPerStream field). Set to true to limit redemptions. + /// + [JsonProperty(PropertyName = "is_max_per_stream_enabled")] + public bool? IsMaxPerStreamEnabled { get; set; } + + /// + /// The maximum number of redemptions allowed per live stream. Applied only if IsMaxPerUserPerStreamEnabled is true. The minimum value is 1. + /// + [JsonProperty(PropertyName = "max_per_stream")] + public int? MaxPerStream { get; set; } + + /// + /// A Boolean value that determines whether to limit the maximum number of redemptions allowed per user per stream (see MaxPerUserPerStream). The minimum value is 1. Set to true to limit redemptions. + /// + [JsonProperty(PropertyName = "is_max_per_user_per_stream_enabled")] + public bool? IsMaxPerUserPerStreamEnabled { get; set; } + + /// + /// The maximum number of redemptions allowed per user per stream. Applied only if IsMaxPerUserPerStreamEnabled is true. + /// + [JsonProperty(PropertyName = "max_per_user_per_stream")] + public int? MaxPerUserPerStream { get; set; } + + /// + /// A Boolean value that determines whether to apply a cooldown period between redemptions. Set to true to apply a cooldown period. For the duration of the cooldown period, see GlobalCooldownSeconds. + /// + [JsonProperty(PropertyName = "is_global_cooldown_enabled")] + public bool? IsGlobalCooldownEnabled { get; set; } + + /// + /// The cooldown period, in seconds. Applied only if IsGlobalCooldownEnabled is true. The minimum value is 1; however, for it to be shown in the Twitch UX, the minimum value is 60. + /// + [JsonProperty(PropertyName = "global_cooldown_seconds")] + public int? GlobalCooldownSeconds { get; set; } + + /// + /// A Boolean value that determines whether to pause the reward. Set to true to pause the reward. Viewers can’t redeem paused rewards, however the reward will still be visible with "Reward is temporarily unavailable. Check back for it soon." message. + /// + [JsonProperty(PropertyName = "is_paused")] + public bool? IsPaused { get; set; } + + /// + /// A Boolean value that determines whether redemptions should be set to FULFILLED status immediately when a reward is redeemed. If false, status is set to UNFULFILLED and follows the normal request queue process. + /// + [JsonProperty(PropertyName = "should_redemptions_skip_request_queue")] + public bool? ShouldRedemptionsSkipRequestQueue { get; set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardResponse.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardResponse.cs index 0f9f91d5..62a220bc 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardResponse.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardResponse.cs @@ -2,9 +2,15 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints.UpdateCustomReward { - public class UpdateCustomRewardResponse - { - [JsonProperty(PropertyName = "data")] - public CustomReward[] Data { get; protected set; } - } + /// + /// The response for updating a custom reward. + /// + public class UpdateCustomRewardResponse + { + /// + /// The list contains the single reward that you updated. + /// + [JsonProperty(PropertyName = "data")] + public CustomReward[] Data { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusRequest.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusRequest.cs index 6073fc68..4d12d060 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusRequest.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusRequest.cs @@ -4,10 +4,16 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints.UpdateCustomRewardRedemptionStatus { - public class UpdateCustomRewardRedemptionStatusRequest - { - [JsonConverter(typeof(StringEnumConverter))] - [JsonProperty(PropertyName = "status")] - public CustomRewardRedemptionStatus Status { get; set; } - } + /// + /// The request for updating a redemption’s status. + /// + public class UpdateCustomRewardRedemptionStatusRequest + { + /// + /// The status to set the redemption to. Possible values are: CANCELED, FULFILLED. Setting the status to CANCELED refunds the user’s channel points. + /// + [JsonConverter(typeof(StringEnumConverter))] + [JsonProperty(PropertyName = "status")] + public CustomRewardRedemptionStatus Status { get; set; } + } } diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusResponse.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusResponse.cs index 0550e297..64c396e2 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusResponse.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusResponse.cs @@ -2,9 +2,16 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints.UpdateRedemptionStatus { - public class UpdateRedemptionStatusResponse - { - [JsonProperty(PropertyName = "data")] - public RewardRedemption[] Data { get; protected set; } - } + + /// + /// The response for updating a redemption’s status. + /// + public class UpdateRedemptionStatusResponse + { + /// + /// The state of the redemption. Possible values are: CANCELED, FULFILLED, UNFULFILLED + /// + [JsonProperty(PropertyName = "data")] + public RewardRedemption[] Data { get; protected set; } + } } From 80674332b5d009f3423d26147d2173ad0d45e724 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 8 Jun 2023 14:42:50 +0100 Subject: [PATCH 12/55] - Removed BroadcasterId from UpdateCustomRewardRequest as it is not on the Twitch API documentation --- .../UpdateCustomReward/UpdateCustomRewardRequest.cs | 3 --- .../UpdateCustomRewardRedemptionStatusResponse.cs | 1 - 2 files changed, 4 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs index 84521966..6028bae9 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs @@ -10,9 +10,6 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints.UpdateCustomReward [JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)] public class UpdateCustomRewardRequest { - [JsonProperty(PropertyName = "broadcaster_id")] - public string BroadcasterId { get; set; } - /// /// The reward’s title. The title may contain a maximum of 45 characters and it must be unique amongst all of the broadcaster’s custom rewards. /// diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusResponse.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusResponse.cs index 64c396e2..5d1a95b9 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusResponse.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateRedemptionStatus/UpdateCustomRewardRedemptionStatusResponse.cs @@ -2,7 +2,6 @@ namespace TwitchLib.Api.Helix.Models.ChannelPoints.UpdateRedemptionStatus { - /// /// The response for updating a redemption’s status. /// From 3097dbe8765c21cb4e2524717ba2f7e938370ec0 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 8 Jun 2023 14:50:08 +0100 Subject: [PATCH 13/55] - Rearranging model properties to match Twitch API Documentation --- .../CreateCustomReward/CreateCustomRewardsRequest.cs | 12 ++++++------ .../ChannelPoints/RewardRedemption.cs | 12 ++++++------ .../UpdateCustomReward/UpdateCustomRewardRequest.cs | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsRequest.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsRequest.cs index f83caabe..50bb4770 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsRequest.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/CreateCustomReward/CreateCustomRewardsRequest.cs @@ -15,18 +15,18 @@ public class CreateCustomRewardsRequest [JsonProperty(PropertyName = "title")] public string Title { get; set; } - /// - /// The prompt shown to the viewer when they redeem the reward. Specify a prompt if IsUserInputRequired is true. The prompt is limited to a maximum of 200 characters. - /// - [JsonProperty(PropertyName = "prompt")] - public string Prompt { get; set; } - /// /// The cost of the reward, in Channel Points. The minimum is 1 point. /// [JsonProperty(PropertyName = "cost")] public int Cost { get; set; } + /// + /// The prompt shown to the viewer when they redeem the reward. Specify a prompt if IsUserInputRequired is true. The prompt is limited to a maximum of 200 characters. + /// + [JsonProperty(PropertyName = "prompt")] + public string Prompt { get; set; } + /// /// A Boolean value that determines whether the reward is enabled. Viewers see only enabled rewards. The default is true. /// diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/RewardRedemption.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/RewardRedemption.cs index c29abc0a..1e2476ef 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/RewardRedemption.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/RewardRedemption.cs @@ -33,18 +33,18 @@ public class RewardRedemption [JsonProperty(PropertyName = "id")] public string Id { get; protected set; } - /// - /// The ID that uniquely identifies the user that redeemed the reward. - /// - [JsonProperty(PropertyName = "user_id")] - public string UserId { get; protected set; } - /// /// The user’s login name. (Name is lowercase) /// [JsonProperty(PropertyName = "user_login")] public string UserLogin { get; protected set; } + /// + /// The ID that uniquely identifies the user that redeemed the reward. + /// + [JsonProperty(PropertyName = "user_id")] + public string UserId { get; protected set; } + /// /// The user’s display name. (Name has capitalization) /// diff --git a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs index 6028bae9..6fe1ff71 100644 --- a/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs +++ b/TwitchLib.Api.Helix.Models/ChannelPoints/UpdateCustomReward/UpdateCustomRewardRequest.cs @@ -28,18 +28,18 @@ public class UpdateCustomRewardRequest [JsonProperty(PropertyName = "cost")] public int? Cost { get; set; } - /// - /// A Boolean value that indicates whether the reward is enabled. Set to true to enable the reward. Viewers see only enabled rewards. - /// - [JsonProperty(PropertyName = "is_enabled")] - public bool? IsEnabled { get; set; } - /// /// The background color to use for the reward. Specify the color using Hex format (for example, #00E5CB). /// [JsonProperty(PropertyName = "background_color")] public string BackgroundColor { get; set; } + /// + /// A Boolean value that indicates whether the reward is enabled. Set to true to enable the reward. Viewers see only enabled rewards. + /// + [JsonProperty(PropertyName = "is_enabled")] + public bool? IsEnabled { get; set; } + /// /// A Boolean value that determines whether users must enter information to redeem the reward. Set to true if user input is required. See the Prompt field. /// From 84951b80353bd0ec05b223e54576d596a2138014 Mon Sep 17 00:00:00 2001 From: Bukk94 Date: Fri, 7 Jul 2023 00:13:50 +0200 Subject: [PATCH 14/55] Aligned Auth Scopes with Twitch docs, Modified ModifyChannelInformationAsync to return bool value --- .gitignore | 4 +- TwitchLib.Api.Core.Enums/AuthScopesEnum.cs | 380 +++++++++++++++--- TwitchLib.Api.Core/ApiBase.cs | 4 +- TwitchLib.Api.Core/Common/Helpers.cs | 294 ++++++++++---- TwitchLib.Api.Helix/Channels.cs | 7 +- .../AuthorizationFlow/PingResponse.cs | 99 +---- 6 files changed, 533 insertions(+), 255 deletions(-) diff --git a/.gitignore b/.gitignore index 89ad0e0e..24012de9 100644 --- a/.gitignore +++ b/.gitignore @@ -233,4 +233,6 @@ $RECYCLE.BIN/ *.msp # Windows shortcuts -*.lnk \ No newline at end of file +*.lnk + +.idea/* \ No newline at end of file diff --git a/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs b/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs index ae8008d7..6b9bebd8 100644 --- a/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs +++ b/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs @@ -1,77 +1,323 @@ -namespace TwitchLib.Api.Core.Enums +using System; + +namespace TwitchLib.Api.Core.Enums { public enum AuthScopes { + /// + /// Any scope. + /// Any, - Channel_Check_Subscription, - Channel_Commercial, - Channel_Editor, - Channel_Feed_Edit, - Channel_Feed_Read, - Channel_Read, - Channel_Stream, - Channel_Subscriptions, + + /// + /// View live stream chat messages. + /// Chat_Read, + + /// + /// Send live stream chat messages. + /// Chat_Edit, + + /// + /// Perform moderation actions in a channel. The user requesting the scope must be a moderator in the channel. + /// Channel_Moderate, - Collections_Edit, - Communities_Edit, - Communities_Moderate, - User_Blocks_Edit, - User_Blocks_Read, - User_Follows_Edit, - User_Read, - User_Subscriptions, - Viewing_Activity_Read, - OpenId, - Helix_Analytics_Read_Extensions, - Helix_Analytics_Read_Games, - Helix_Bits_Read, - Helix_Channel_Edit_Commercial, - Helix_Channel_Manage_Broadcast, - Helix_Channel_Manage_Extensions, - Helix_Channel_Manage_Moderators, - Helix_Channel_Manage_Polls, - Helix_Channel_Manage_Predictions, - Helix_Channel_Manage_Redemptions, - Helix_Channel_Manage_Schedule, - Helix_Channel_Manage_Videos, - Helix_Channel_Manage_VIPs, - Helix_Channel_Read_Charity, - Helix_Channel_Read_Editors, - Helix_Channel_Read_Goals, - Helix_Channel_Read_Hype_Train, - Helix_Channel_Read_Polls, - Helix_Channel_Read_Predictions, - Helix_Channel_Read_Redemptions, - Helix_Channel_Read_Stream_Key, - Helix_Channel_Read_Subscriptions, - Helix_Channel_Read_VIPs, - Helix_Clips_Edit, - Helix_Moderation_Read, - Helix_Moderator_Manage_Banned_Users, - Helix_Moderator_Manage_Blocked_Terms, - Helix_Moderator_Manage_Announcements, - Helix_Moderator_Manage_Automod, - Helix_Moderator_Manage_Automod_Settings, - Helix_moderator_Manage_Chat_Messages, - Helix_Moderator_Manage_Chat_Settings, - Helix_Moderator_Read_Blocked_Terms, - Helix_Moderator_Read_Automod_Settings, - Helix_Moderator_Read_Chat_Settings, - Helix_Moderator_Read_Chatters, - Helix_User_Edit, - Helix_User_Edit_Broadcast, - Helix_User_Edit_Follows, - Helix_User_Manage_BlockedUsers, - Helix_User_Manage_Chat_Color, - Helix_User_Manage_Whispers, - Helix_User_Read_BlockedUsers, - Helix_User_Read_Broadcast, - Helix_User_Read_Email, - Helix_User_Read_Follows, - Helix_User_Read_Subscriptions, - Helix_Moderator_Read_Followers, + + /// + /// View your whisper messages. + /// + Whisper_Read, + + /// + /// Send whisper messages. + /// + Whisper_Edit, + + /// + /// View analytics data for the Twitch Extensions owned by the authenticated account. + /// + Analytics_Read_Extensions, + + /// + /// View analytics data for the games owned by the authenticated account. + /// + Analytics_Read_Games, + + /// + /// View Bits information for a channel. + /// + Bits_Read, + + /// + /// Run commercials on a channel. + /// + Channel_Edit_Commercial, + + /// + /// Manage a channel’s broadcast configuration, including updating channel configuration and managing stream markers and stream tags. + /// + Channel_Manage_Broadcast, + + /// + /// Manage a channel’s Extension configuration, including activating Extensions. + /// + Channel_Manage_Extensions, + + /// + /// Add or remove the moderator role from users in your channel. + /// + Channel_Manage_Moderators, + + /// + /// Manage a channel’s polls. + /// + Channel_Manage_Polls, + + /// + /// Manage of channel’s Channel Points Predictions + /// + Channel_Manage_Predictions, + + /// + /// Manage Channel Points custom rewards and their redemptions on a channel. + /// + Channel_Manage_Redemptions, + + /// + /// Manage a channel’s stream schedule. + /// + Channel_Manage_Schedule, + + /// + /// Manage Guest Star for your channel. + /// + Channel_Manage_Guest_Star, + + /// + /// Manage a channel raiding another channel. + /// + Channel_Manage_Raids, + + /// + /// Manage a channel’s videos, including deleting videos. + /// + Channel_Manage_Videos, + + /// + /// Add or remove the VIP role from users in your channel. + /// + Channel_Manage_VIPs, + + /// + /// Read charity campaign details and user donations on your channel. + /// + Channel_Read_Charity, + + /// + /// View a list of users with the editor role for a channel. + /// + Channel_Read_Editors, + + /// + /// View Creator Goals for a channel. + /// + Channel_Read_Goals, + + /// + /// View Hype Train information for a channel. + /// + Channel_Read_Hype_Train, + + /// + /// View a channel’s polls. + /// + Channel_Read_Polls, + + /// + /// View a channel’s Channel Points Predictions. + /// + Channel_Read_Predictions, + + /// + /// View Channel Points custom rewards and their redemptions on a channel. + /// + Channel_Read_Redemptions, + + /// + /// Read Guest Star details for your channel. + /// + Channel_Read_Guest_Star, + + /// + /// View an authorized user’s stream key. + /// + Channel_Read_Stream_Key, + + /// + /// View a list of all subscribers to a channel and check if a user is subscribed to a channel. + /// + Channel_Read_Subscriptions, + + /// + /// Read the list of VIPs in your channel. + /// + Channel_Read_VIPs, + + /// + /// Manage Clips for a channel. + /// + Clips_Edit, + + /// + /// View a channel’s moderation data including Moderators, Bans, Timeouts, and Automod settings. + /// + Moderation_Read, + + /// + /// Send announcements in channels where you have the moderator role. + /// + Moderator_Manage_Announcements, + + /// + /// Manage messages held for review by AutoMod in channels where you are a moderator. + /// + Moderator_Manage_Automod, + + /// + /// Manage a broadcaster’s AutoMod settings. + /// + Moderator_Manage_Automod_Settings, + + /// + /// Ban and unban users. + /// + Moderator_Manage_Banned_Users, + + /// + /// Manage a broadcaster’s list of blocked terms. + /// + Moderator_Manage_Blocked_Terms, + + /// + /// Delete chat messages in channels where you have the moderator role + /// + Moderator_Manage_Chat_Messages, + + /// + /// Manage a broadcaster’s chat room settings. + /// + Moderator_Manage_Chat_Settings, + + /// + /// Manage Guest Star for channels where you are a Guest Star moderator. + /// + Moderator_Manage_Guest_Star, + + /// + /// Manage a broadcaster’s Shield Mode status. + /// + Moderator_Manage_Shield_Mode, + + /// + /// Manage a broadcaster’s shoutouts. + /// + Moderator_Manage_Shoutouts, + + /// + /// View a broadcaster’s AutoMod settings. + /// + Moderator_Read_Automod_Settings, + + /// + /// View a broadcaster’s list of blocked terms. + /// + Moderator_Read_Blocked_Terms, + + /// + /// View a broadcaster’s chat room settings. + /// + Moderator_Read_Chat_Settings, + + /// + /// View the chatters in a broadcaster’s chat room. + /// + Moderator_Read_Chatters, + + /// + /// Read the followers of a broadcaster. + /// + Moderator_Read_Followers, + + /// + /// Read Guest Star details for channels where you are a Guest Star moderator. + /// + Moderator_Read_Guest_Star, + + /// + /// View a broadcaster’s Shield Mode status. + /// + Moderator_Read_Shield_Mode, + + /// + /// View a broadcaster’s shoutouts. + /// + Moderator_Read_Shoutouts, + + /// + /// Manage a user object. + /// + User_Edit, + + /// + /// Deprecated. Was previously used for “Create User Follows” and “Delete User Follows.” + /// + [Obsolete("Deprecated")] + User_Edit_Follows, + + /// + /// Manage the block list of a user. + /// + User_Manage_BlockedUsers, + + /// + /// Update the color used for the user’s name in chat. + /// + User_Manage_Chat_Color, + + /// + /// Read whispers that you send and receive, and send whispers on your behalf. + /// + User_Manage_Whispers, + + /// + /// View the block list of a user. + /// + User_Read_BlockedUsers, + + /// + /// View a user’s broadcasting configuration, including Extension configurations. + /// + User_Read_Broadcast, + + /// + /// View a user’s email address. + /// + User_Read_Email, + + /// + /// View the list of channels a user follows. + /// + User_Read_Follows, + + /// + /// View if an authorized user is subscribed to specific channels. + /// + User_Read_Subscriptions, + + /// + /// No scope + /// None } } diff --git a/TwitchLib.Api.Core/ApiBase.cs b/TwitchLib.Api.Core/ApiBase.cs index 68487b6e..a81642da 100644 --- a/TwitchLib.Api.Core/ApiBase.cs +++ b/TwitchLib.Api.Core/ApiBase.cs @@ -112,7 +112,7 @@ protected async Task TwitchPatchGenericAsync(string resource, ApiVersion a return await _rateLimiter.Perform(async () => JsonConvert.DeserializeObject((await _http.GeneralRequestAsync(url, "PATCH", payload, api, clientId, accessToken).ConfigureAwait(false)).Value, _twitchLibJsonDeserializer)).ConfigureAwait(false); } - protected async Task TwitchPatchAsync(string resource, ApiVersion api, string payload, List> getParams = null, string accessToken = null, string clientId = null, string customBase = null) + protected async Task> TwitchPatchAsync(string resource, ApiVersion api, string payload, List> getParams = null, string accessToken = null, string clientId = null, string customBase = null) { var url = ConstructResourceUrl(resource, getParams, api, customBase); @@ -122,7 +122,7 @@ protected async Task TwitchPatchAsync(string resource, ApiVersion api, s accessToken = await GetAccessTokenAsync(accessToken).ConfigureAwait(false); ForceAccessTokenAndClientIdForHelix(clientId, accessToken, api); - return await _rateLimiter.Perform(async () => (await _http.GeneralRequestAsync(url, "PATCH", payload, api, clientId, accessToken).ConfigureAwait(false)).Value).ConfigureAwait(false); + return await _rateLimiter.Perform(async () => (await _http.GeneralRequestAsync(url, "PATCH", payload, api, clientId, accessToken).ConfigureAwait(false))).ConfigureAwait(false); } protected async Task> TwitchDeleteAsync(string resource, ApiVersion api, List> getParams = null, string accessToken = null, string clientId = null, string customBase = null) diff --git a/TwitchLib.Api.Core/Common/Helpers.cs b/TwitchLib.Api.Core/Common/Helpers.cs index c10409b2..8a6dc3f7 100644 --- a/TwitchLib.Api.Core/Common/Helpers.cs +++ b/TwitchLib.Api.Core/Common/Helpers.cs @@ -26,148 +26,270 @@ public static string AuthScopesToString(AuthScopes scope) { switch (scope) { - case AuthScopes.Channel_Check_Subscription: - return "channel_check_subscription"; - case AuthScopes.Channel_Commercial: - return "channel_commercial"; - case AuthScopes.Channel_Editor: - return "channel_editor"; - case AuthScopes.Channel_Feed_Edit: - return "channel_feed_edit"; - case AuthScopes.Channel_Feed_Read: - return "channel_feed_read"; case AuthScopes.Chat_Read: return "chat:read"; case AuthScopes.Channel_Moderate: return "channel:moderate"; case AuthScopes.Chat_Edit: return "chat:edit"; - case AuthScopes.Channel_Read: - return "channel_read"; - case AuthScopes.Channel_Stream: - return "channel_stream"; - case AuthScopes.Channel_Subscriptions: - return "channel_subscriptions"; - case AuthScopes.Collections_Edit: - return "collections_edit"; - case AuthScopes.Communities_Edit: - return "communities_edit"; - case AuthScopes.Communities_Moderate: - return "communities_moderate"; - case AuthScopes.OpenId: - return "openid"; - case AuthScopes.User_Blocks_Edit: - return "user_blocks_edit"; - case AuthScopes.User_Blocks_Read: - return "user_blocks_read"; - case AuthScopes.User_Follows_Edit: - return "user_follows_edit"; - case AuthScopes.User_Read: - return "user_read"; - case AuthScopes.User_Subscriptions: - return "user_subscriptions"; - case AuthScopes.Viewing_Activity_Read: - return "viewing_activity_read"; - case AuthScopes.Helix_Analytics_Read_Extensions: + case AuthScopes.Whisper_Read: + return "whispers:read"; + case AuthScopes.Whisper_Edit: + return "whispers:edit"; + case AuthScopes.Analytics_Read_Extensions: return "analytics:read:extensions"; - case AuthScopes.Helix_Analytics_Read_Games: + case AuthScopes.Analytics_Read_Games: return "analytics:read:games"; - case AuthScopes.Helix_Bits_Read: + case AuthScopes.Bits_Read: return "bits:read"; - case AuthScopes.Helix_Channel_Edit_Commercial: + case AuthScopes.Channel_Edit_Commercial: return "channel:edit:commercial"; - case AuthScopes.Helix_Channel_Manage_Broadcast: + case AuthScopes.Channel_Manage_Broadcast: return "channel:manage:broadcast"; - case AuthScopes.Helix_Channel_Manage_Extensions: + case AuthScopes.Channel_Manage_Extensions: return "channel:manage:extensions"; - case AuthScopes.Helix_Channel_Manage_Moderators: + case AuthScopes.Channel_Manage_Moderators: return "channel:manage:moderators"; - case AuthScopes.Helix_Channel_Manage_Redemptions: + case AuthScopes.Channel_Manage_Redemptions: return "channel:manage:redemptions"; - case AuthScopes.Helix_Channel_Manage_Polls: + case AuthScopes.Channel_Manage_Polls: return "channel:manage:polls"; - case AuthScopes.Helix_Channel_Manage_Predictions: + case AuthScopes.Channel_Manage_Predictions: return "channel:manage:predictions"; - case AuthScopes.Helix_Channel_Manage_Schedule: + case AuthScopes.Channel_Manage_Schedule: return "channel:manage:schedule"; - case AuthScopes.Helix_Channel_Manage_Videos: + case AuthScopes.Channel_Manage_Videos: return "channel:manage:videos"; - case AuthScopes.Helix_Channel_Manage_VIPs: + case AuthScopes.Channel_Manage_VIPs: return "channel:manage:vips"; - case AuthScopes.Helix_Channel_Read_Charity: + case AuthScopes.Channel_Manage_Guest_Star: + return "channel:manage:guest_star"; + case AuthScopes.Channel_Manage_Raids: + return "channel:manage:raids"; + case AuthScopes.Channel_Read_Charity: return "channel:read:charity"; - case AuthScopes.Helix_Channel_Read_Editors: + case AuthScopes.Channel_Read_Editors: return "channel:read:editors"; - case AuthScopes.Helix_Channel_Read_Goals: + case AuthScopes.Channel_Read_Goals: return "channel:read:goals"; - case AuthScopes.Helix_Channel_Read_Hype_Train: + case AuthScopes.Channel_Read_Hype_Train: return "channel:read:hype_train"; - case AuthScopes.Helix_Channel_Read_Polls: + case AuthScopes.Channel_Read_Polls: return "channel:read:polls"; - case AuthScopes.Helix_Channel_Read_Predictions: + case AuthScopes.Channel_Read_Predictions: return "channel:read:predictions"; - case AuthScopes.Helix_Channel_Read_Redemptions: + case AuthScopes.Channel_Read_Redemptions: return "channel:read:redemptions"; - case AuthScopes.Helix_Channel_Read_Stream_Key: + case AuthScopes.Channel_Read_Stream_Key: return "channel:read:stream_key"; - case AuthScopes.Helix_Channel_Read_Subscriptions: + case AuthScopes.Channel_Read_Subscriptions: return "channel:read:subscriptions"; - case AuthScopes.Helix_Channel_Read_VIPs: + case AuthScopes.Channel_Read_VIPs: return "channel:read:vips"; - case AuthScopes.Helix_Clips_Edit: + case AuthScopes.Channel_Read_Guest_Star: + return "channel:read:guest_star"; + case AuthScopes.Clips_Edit: return "clips:edit"; - case AuthScopes.Helix_Moderation_Read: + case AuthScopes.Moderation_Read: return "moderation:read"; - case AuthScopes.Helix_User_Edit: + case AuthScopes.User_Edit: return "user:edit"; - case AuthScopes.Helix_User_Edit_Broadcast: - return "user:edit:broadcast"; - case AuthScopes.Helix_User_Edit_Follows: + case AuthScopes.User_Edit_Follows: return "user:edit:follows"; - case AuthScopes.Helix_User_Read_BlockedUsers: + case AuthScopes.User_Read_BlockedUsers: return "user:read:blocked_users"; - case AuthScopes.Helix_User_Read_Broadcast: + case AuthScopes.User_Read_Broadcast: return "user:read:broadcast"; - case AuthScopes.Helix_User_Read_Email: + case AuthScopes.User_Read_Email: return "user:read:email"; - case AuthScopes.Helix_User_Read_Follows: + case AuthScopes.User_Read_Follows: return "user:read:follows"; - case AuthScopes.Helix_User_Read_Subscriptions: + case AuthScopes.User_Read_Subscriptions: return "user:read:subscriptions"; - case AuthScopes.Helix_User_Manage_BlockedUsers: + case AuthScopes.User_Manage_BlockedUsers: return "user:manage:blocked_users"; - case AuthScopes.Helix_User_Manage_Chat_Color: + case AuthScopes.User_Manage_Chat_Color: return "user:manage:chat_color"; - case AuthScopes.Helix_User_Manage_Whispers: + case AuthScopes.User_Manage_Whispers: return "user:manage:whispers"; - case AuthScopes.Helix_Moderator_Manage_Announcements: + case AuthScopes.Moderator_Manage_Announcements: return "moderator:manage:announcements"; - case AuthScopes.Helix_Moderator_Manage_Automod: + case AuthScopes.Moderator_Manage_Automod: return "moderator:manage:automod"; - case AuthScopes.Helix_Moderator_Manage_Automod_Settings: + case AuthScopes.Moderator_Manage_Automod_Settings: return "moderator:manage:automod_settings"; - case AuthScopes.Helix_Moderator_Manage_Banned_Users: + case AuthScopes.Moderator_Manage_Banned_Users: return "moderator:manage:banned_users"; - case AuthScopes.Helix_Moderator_Manage_Blocked_Terms: + case AuthScopes.Moderator_Manage_Blocked_Terms: return "moderator:manage:blocked_terms"; - case AuthScopes.Helix_moderator_Manage_Chat_Messages: + case AuthScopes.Moderator_Manage_Chat_Messages: return "moderator:manage:chat_messages"; - case AuthScopes.Helix_Moderator_Manage_Chat_Settings: + case AuthScopes.Moderator_Manage_Chat_Settings: return "moderator:manage:chat_settings"; - case AuthScopes.Helix_Moderator_Read_Automod_Settings: + case AuthScopes.Moderator_Read_Automod_Settings: return "moderator:read:automod_settings"; - case AuthScopes.Helix_Moderator_Read_Blocked_Terms: + case AuthScopes.Moderator_Read_Blocked_Terms: return "moderator:read:blocked_terms"; - case AuthScopes.Helix_Moderator_Read_Chat_Settings: + case AuthScopes.Moderator_Read_Chat_Settings: return "moderator:read:chat_settings"; - case AuthScopes.Helix_Moderator_Read_Chatters: + case AuthScopes.Moderator_Read_Chatters: return "moderator:read:chatters"; - case AuthScopes.Helix_Moderator_Read_Followers: + case AuthScopes.Moderator_Read_Followers: return "moderator:read:followers"; + case AuthScopes.Moderator_Read_Guest_Star: + return "moderator:read:guest_star"; + case AuthScopes.Moderator_Read_Shield_Mode: + return "moderator:read:shield_mode"; + case AuthScopes.Moderator_Read_Shoutouts: + return "moderator:read:shoutouts"; + case AuthScopes.Moderator_Manage_Guest_Star: + return "moderator:manage:guest_star"; + case AuthScopes.Moderator_Manage_Shield_Mode: + return "moderator:manage:shield_mode"; + case AuthScopes.Moderator_Manage_Shoutouts: + return "moderator:manage:shoutouts"; case AuthScopes.Any: case AuthScopes.None: default: - return ""; + return string.Empty; + } + } + + /// + /// Converts Twitch string to AuthScope enum. + /// + /// Scope as twitch string + /// Twitch scope as AuthScope + public static AuthScopes StringToScope(string scope) + { + switch (scope) + { + case "chat:read": + return AuthScopes.Chat_Read; + case "channel:moderate": + return AuthScopes.Channel_Moderate; + case "chat:edit": + return AuthScopes.Chat_Edit; + case "whispers:read": + return AuthScopes.Whisper_Read; + case "whispers:edit": + return AuthScopes.Whisper_Edit; + case "analytics:read:extensions": + return AuthScopes.Analytics_Read_Extensions; + case "analytics:read:games": + return AuthScopes.Analytics_Read_Games; + case "bits:read": + return AuthScopes.Bits_Read; + case "channel:edit:commercial": + return AuthScopes.Channel_Edit_Commercial; + case "channel:manage:broadcast": + return AuthScopes.Channel_Manage_Broadcast; + case "channel:manage:extensions": + return AuthScopes.Channel_Manage_Extensions; + case "channel:manage:moderators": + return AuthScopes.Channel_Manage_Moderators; + case "channel:manage:redemptions": + return AuthScopes.Channel_Manage_Redemptions; + case "channel:manage:polls": + return AuthScopes.Channel_Manage_Polls; + case "channel:manage:predictions": + return AuthScopes.Channel_Manage_Predictions; + case "channel:manage:schedule": + return AuthScopes.Channel_Manage_Schedule; + case "channel:manage:videos": + return AuthScopes.Channel_Manage_Videos; + case "channel:manage:vips": + return AuthScopes.Channel_Manage_VIPs; + case "channel:manage:guest_star": + return AuthScopes.Channel_Manage_Guest_Star; + case "channel:manage:raids": + return AuthScopes.Channel_Manage_Raids; + case "channel:read:charity": + return AuthScopes.Channel_Read_Charity; + case "channel:read:editors": + return AuthScopes.Channel_Read_Editors; + case "channel:read:goals": + return AuthScopes.Channel_Read_Goals; + case "channel:read:hype_train": + return AuthScopes.Channel_Read_Hype_Train; + case "channel:read:polls": + return AuthScopes.Channel_Read_Polls; + case "channel:read:predictions": + return AuthScopes.Channel_Read_Predictions; + case "channel:read:redemptions": + return AuthScopes.Channel_Read_Redemptions; + case "channel:read:stream_key": + return AuthScopes.Channel_Read_Stream_Key; + case "channel:read:subscriptions": + return AuthScopes.Channel_Read_Subscriptions; + case "channel:read:vips": + return AuthScopes.Channel_Read_VIPs; + case "channel:read:guest_star": + return AuthScopes.Channel_Read_Guest_Star; + case "clips:edit": + return AuthScopes.Clips_Edit; + case "moderation:read": + return AuthScopes.Moderation_Read; + case "user:edit": + return AuthScopes.User_Edit; + case "user:edit:follows": + return AuthScopes.User_Edit_Follows; + case "user:read:blocked_users": + return AuthScopes.User_Read_BlockedUsers; + case "user:read:broadcast": + return AuthScopes.User_Read_Broadcast; + case "user:read:email": + return AuthScopes.User_Read_Email; + case "user:read:follows": + return AuthScopes.User_Read_Follows; + case "user:read:subscriptions": + return AuthScopes.User_Read_Subscriptions; + case "user:manage:blocked_users": + return AuthScopes.User_Manage_BlockedUsers; + case "user:manage:chat_color": + return AuthScopes.User_Manage_Chat_Color; + case "user:manage:whispers": + return AuthScopes.User_Manage_Whispers; + case "moderator:manage:announcements": + return AuthScopes.Moderator_Manage_Announcements; + case "moderator:manage:automod": + return AuthScopes.Moderator_Manage_Automod; + case "moderator:manage:automod_settings": + return AuthScopes.Moderator_Manage_Automod_Settings; + case "moderator:manage:banned_users": + return AuthScopes.Moderator_Manage_Banned_Users; + case "moderator:manage:blocked_terms": + return AuthScopes.Moderator_Manage_Blocked_Terms; + case "moderator:manage:chat_messages": + return AuthScopes.Moderator_Manage_Chat_Messages; + case "moderator:manage:chat_settings": + return AuthScopes.Moderator_Manage_Chat_Settings; + case "moderator:manage:guest_star": + return AuthScopes.Moderator_Manage_Guest_Star; + case "moderator:manage:shield_mode": + return AuthScopes.Moderator_Manage_Shield_Mode; + case "moderator:manage:shoutouts": + return AuthScopes.Moderator_Manage_Shoutouts; + case "moderator:read:automod_settings": + return AuthScopes.Moderator_Read_Automod_Settings; + case "moderator:read:blocked_terms": + return AuthScopes.Moderator_Read_Blocked_Terms; + case "moderator:read:chat_settings": + return AuthScopes.Moderator_Read_Chat_Settings; + case "moderator:read:chatters": + return AuthScopes.Moderator_Read_Chatters; + case "moderator:read:followers": + return AuthScopes.Moderator_Read_Followers; + case "moderator:read:guest_star": + return AuthScopes.Moderator_Read_Guest_Star; + case "moderator:read:shield_mode": + return AuthScopes.Moderator_Read_Shield_Mode; + case "moderator:read:shoutouts": + return AuthScopes.Moderator_Read_Shoutouts; + case "": + return AuthScopes.None; + default: + throw new Exception("Unknown scope"); } } diff --git a/TwitchLib.Api.Helix/Channels.cs b/TwitchLib.Api.Helix/Channels.cs index a96b70cb..926b4818 100644 --- a/TwitchLib.Api.Helix/Channels.cs +++ b/TwitchLib.Api.Helix/Channels.cs @@ -56,7 +56,7 @@ public Task GetChannelInformationAsync(string bro /// optional access token to override the use of the stored one in the TwitchAPI instance /// /// - public Task ModifyChannelInformationAsync(string broadcasterId, ModifyChannelInformationRequest request, string accessToken = null) + public async Task ModifyChannelInformationAsync(string broadcasterId, ModifyChannelInformationRequest request, string accessToken = null) { if (string.IsNullOrEmpty(broadcasterId)) throw new BadParameterException("broadcasterId must be set"); @@ -66,7 +66,10 @@ public Task ModifyChannelInformationAsync(string broadcasterId, ModifyChannelInf new KeyValuePair("broadcaster_id", broadcasterId) }; - return TwitchPatchAsync("/channels", ApiVersion.Helix, JsonConvert.SerializeObject(request), getParams, accessToken); + var response = await TwitchPatchAsync("/channels", ApiVersion.Helix, JsonConvert.SerializeObject(request), getParams, accessToken); + + // Successfully updated the channel's properties if return code is 204 (No Content) + return response.Key == 204; } #endregion diff --git a/TwitchLib.Api/ThirdParty/AuthorizationFlow/PingResponse.cs b/TwitchLib.Api/ThirdParty/AuthorizationFlow/PingResponse.cs index c7184e5a..e26a4915 100644 --- a/TwitchLib.Api/ThirdParty/AuthorizationFlow/PingResponse.cs +++ b/TwitchLib.Api/ThirdParty/AuthorizationFlow/PingResponse.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using Newtonsoft.Json.Linq; using TwitchLib.Api.Core.Enums; @@ -31,106 +30,12 @@ public PingResponse(string jsonStr) { Scopes = new List(); foreach (var scope in json.SelectToken("scopes")) - Scopes.Add(StringToScope(scope.ToString())); + Scopes.Add(Core.Common.Helpers.StringToScope(scope.ToString())); Token = json.SelectToken("token").ToString(); Refresh = json.SelectToken("refresh").ToString(); Username = json.SelectToken("username").ToString(); ClientId = json.SelectToken("client_id").ToString(); } } - - private AuthScopes StringToScope(string scope) - { - switch (scope) - { - case "user_read": - return AuthScopes.User_Read; - case "user_blocks_edit": - return AuthScopes.User_Blocks_Edit; - case "user_blocks_read": - return AuthScopes.User_Blocks_Read; - case "user_follows_edit": - return AuthScopes.User_Follows_Edit; - case "channel_read": - return AuthScopes.Channel_Read; - case "channel_commercial": - return AuthScopes.Channel_Commercial; - case "channel_stream": - return AuthScopes.Channel_Subscriptions; - case "channel_subscriptions": - return AuthScopes.Channel_Subscriptions; - case "user_subscriptions": - return AuthScopes.User_Subscriptions; - case "channel_check_subscription": - return AuthScopes.Channel_Check_Subscription; - case "chat:read": - return AuthScopes.Chat_Read; - case "chat:edit": - return AuthScopes.Chat_Edit; - case "chat:moderate": - return AuthScopes.Channel_Moderate; - case "channel_editor": - return AuthScopes.Channel_Editor; - case "channel_feed_read": - return AuthScopes.Channel_Feed_Read; - case "channel_feed_edit": - return AuthScopes.Channel_Feed_Edit; - case "collections_edit": - return AuthScopes.Collections_Edit; - case "communities_edit": - return AuthScopes.Communities_Edit; - case "communities_moderate": - return AuthScopes.Communities_Moderate; - case "viewing_activity_read": - return AuthScopes.Viewing_Activity_Read; - case "user:edit": - return AuthScopes.Helix_User_Edit; - case "user:read:email": - return AuthScopes.Helix_User_Read_Email; - case "clips:edit": - return AuthScopes.Helix_Clips_Edit; - case "analytics:read:games": - return AuthScopes.Helix_Analytics_Read_Games; - case "bits:read": - return AuthScopes.Helix_Bits_Read; - case "channel:read:subscriptions": - return AuthScopes.Helix_Channel_Read_Subscriptions; - case "channel:read:hype_train": - return AuthScopes.Helix_Channel_Read_Hype_Train; - case "channel:manage:redemptions": - return AuthScopes.Helix_Channel_Manage_Redemptions; - case "channel:edit:commercial": - return AuthScopes.Helix_Channel_Edit_Commercial; - case "channel:read:stream_key": - return AuthScopes.Helix_Channel_Read_Stream_Key; - case "channel:read:editors": - return AuthScopes.Helix_Channel_Read_Editors; - case "channel:manage:videos": - return AuthScopes.Helix_Channel_Manage_Videos; - case "user:read:blocked_users": - return AuthScopes.Helix_User_Read_BlockedUsers; - case "user:manage:blocked_users": - return AuthScopes.Helix_User_Manage_BlockedUsers; - case "user:read:subscriptions": - return AuthScopes.Helix_User_Read_Subscriptions; - case "channel:manage:polls": - return AuthScopes.Helix_Channel_Manage_Polls; - case "channel:manage:predictions": - return AuthScopes.Helix_Channel_Manage_Predictions; - case "channel:read:polls": - return AuthScopes.Helix_Channel_Read_Polls; - case "channel:read:predictions": - return AuthScopes.Helix_Channel_Read_Predictions; - case "moderator:manage:automod": - return AuthScopes.Helix_Moderator_Manage_Automod; - case "moderator:read:chatters": - return AuthScopes.Helix_Moderator_Read_Chatters; - case "": - return AuthScopes.None; - default: - throw new Exception("Unknown scope"); - } - } - } } From fa8567a08fdd0dd4205ab4c12b82a2e9e93af769 Mon Sep 17 00:00:00 2001 From: Bukk94 Date: Fri, 7 Jul 2023 10:48:37 +0200 Subject: [PATCH 15/55] Updated Switch statements to switch expressions, updated all projects to C# language latest --- .../TwitchLib.Api.Core.Enums.csproj | 1 + .../TwitchLib.Api.Core.Interfaces.csproj | 1 + .../TwitchLib.Api.Core.Models.csproj | 1 + TwitchLib.Api.Core/Common/Helpers.cs | 387 ++++++------------ TwitchLib.Api.Core/TwitchLib.Api.Core.csproj | 1 + .../TwitchLib.Api.Helix.Models.csproj | 1 + .../TwitchLib.Api.Helix.csproj | 1 + TwitchLib.Api.Test/TwitchLib.Api.Test.csproj | 2 + TwitchLib.Api/TwitchLib.Api.csproj | 1 + 9 files changed, 140 insertions(+), 256 deletions(-) diff --git a/TwitchLib.Api.Core.Enums/TwitchLib.Api.Core.Enums.csproj b/TwitchLib.Api.Core.Enums/TwitchLib.Api.Core.Enums.csproj index 221cab33..cd8aeef6 100644 --- a/TwitchLib.Api.Core.Enums/TwitchLib.Api.Core.Enums.csproj +++ b/TwitchLib.Api.Core.Enums/TwitchLib.Api.Core.Enums.csproj @@ -21,6 +21,7 @@ 3.10.0 3.10.0 True + latest diff --git a/TwitchLib.Api.Core.Interfaces/TwitchLib.Api.Core.Interfaces.csproj b/TwitchLib.Api.Core.Interfaces/TwitchLib.Api.Core.Interfaces.csproj index fe55d227..dc9ba4d8 100644 --- a/TwitchLib.Api.Core.Interfaces/TwitchLib.Api.Core.Interfaces.csproj +++ b/TwitchLib.Api.Core.Interfaces/TwitchLib.Api.Core.Interfaces.csproj @@ -21,6 +21,7 @@ 3.10.0 3.10.0 True + latest diff --git a/TwitchLib.Api.Core.Models/TwitchLib.Api.Core.Models.csproj b/TwitchLib.Api.Core.Models/TwitchLib.Api.Core.Models.csproj index 2a709f73..50d66baa 100644 --- a/TwitchLib.Api.Core.Models/TwitchLib.Api.Core.Models.csproj +++ b/TwitchLib.Api.Core.Models/TwitchLib.Api.Core.Models.csproj @@ -21,6 +21,7 @@ 3.10.0 3.10.0 True + latest diff --git a/TwitchLib.Api.Core/Common/Helpers.cs b/TwitchLib.Api.Core/Common/Helpers.cs index 8a6dc3f7..7d6f62fc 100644 --- a/TwitchLib.Api.Core/Common/Helpers.cs +++ b/TwitchLib.Api.Core/Common/Helpers.cs @@ -24,135 +24,73 @@ public static string FormatOAuth(string token) /// Twitch scope string public static string AuthScopesToString(AuthScopes scope) { - switch (scope) + return scope switch { - case AuthScopes.Chat_Read: - return "chat:read"; - case AuthScopes.Channel_Moderate: - return "channel:moderate"; - case AuthScopes.Chat_Edit: - return "chat:edit"; - case AuthScopes.Whisper_Read: - return "whispers:read"; - case AuthScopes.Whisper_Edit: - return "whispers:edit"; - case AuthScopes.Analytics_Read_Extensions: - return "analytics:read:extensions"; - case AuthScopes.Analytics_Read_Games: - return "analytics:read:games"; - case AuthScopes.Bits_Read: - return "bits:read"; - case AuthScopes.Channel_Edit_Commercial: - return "channel:edit:commercial"; - case AuthScopes.Channel_Manage_Broadcast: - return "channel:manage:broadcast"; - case AuthScopes.Channel_Manage_Extensions: - return "channel:manage:extensions"; - case AuthScopes.Channel_Manage_Moderators: - return "channel:manage:moderators"; - case AuthScopes.Channel_Manage_Redemptions: - return "channel:manage:redemptions"; - case AuthScopes.Channel_Manage_Polls: - return "channel:manage:polls"; - case AuthScopes.Channel_Manage_Predictions: - return "channel:manage:predictions"; - case AuthScopes.Channel_Manage_Schedule: - return "channel:manage:schedule"; - case AuthScopes.Channel_Manage_Videos: - return "channel:manage:videos"; - case AuthScopes.Channel_Manage_VIPs: - return "channel:manage:vips"; - case AuthScopes.Channel_Manage_Guest_Star: - return "channel:manage:guest_star"; - case AuthScopes.Channel_Manage_Raids: - return "channel:manage:raids"; - case AuthScopes.Channel_Read_Charity: - return "channel:read:charity"; - case AuthScopes.Channel_Read_Editors: - return "channel:read:editors"; - case AuthScopes.Channel_Read_Goals: - return "channel:read:goals"; - case AuthScopes.Channel_Read_Hype_Train: - return "channel:read:hype_train"; - case AuthScopes.Channel_Read_Polls: - return "channel:read:polls"; - case AuthScopes.Channel_Read_Predictions: - return "channel:read:predictions"; - case AuthScopes.Channel_Read_Redemptions: - return "channel:read:redemptions"; - case AuthScopes.Channel_Read_Stream_Key: - return "channel:read:stream_key"; - case AuthScopes.Channel_Read_Subscriptions: - return "channel:read:subscriptions"; - case AuthScopes.Channel_Read_VIPs: - return "channel:read:vips"; - case AuthScopes.Channel_Read_Guest_Star: - return "channel:read:guest_star"; - case AuthScopes.Clips_Edit: - return "clips:edit"; - case AuthScopes.Moderation_Read: - return "moderation:read"; - case AuthScopes.User_Edit: - return "user:edit"; - case AuthScopes.User_Edit_Follows: - return "user:edit:follows"; - case AuthScopes.User_Read_BlockedUsers: - return "user:read:blocked_users"; - case AuthScopes.User_Read_Broadcast: - return "user:read:broadcast"; - case AuthScopes.User_Read_Email: - return "user:read:email"; - case AuthScopes.User_Read_Follows: - return "user:read:follows"; - case AuthScopes.User_Read_Subscriptions: - return "user:read:subscriptions"; - case AuthScopes.User_Manage_BlockedUsers: - return "user:manage:blocked_users"; - case AuthScopes.User_Manage_Chat_Color: - return "user:manage:chat_color"; - case AuthScopes.User_Manage_Whispers: - return "user:manage:whispers"; - case AuthScopes.Moderator_Manage_Announcements: - return "moderator:manage:announcements"; - case AuthScopes.Moderator_Manage_Automod: - return "moderator:manage:automod"; - case AuthScopes.Moderator_Manage_Automod_Settings: - return "moderator:manage:automod_settings"; - case AuthScopes.Moderator_Manage_Banned_Users: - return "moderator:manage:banned_users"; - case AuthScopes.Moderator_Manage_Blocked_Terms: - return "moderator:manage:blocked_terms"; - case AuthScopes.Moderator_Manage_Chat_Messages: - return "moderator:manage:chat_messages"; - case AuthScopes.Moderator_Manage_Chat_Settings: - return "moderator:manage:chat_settings"; - case AuthScopes.Moderator_Read_Automod_Settings: - return "moderator:read:automod_settings"; - case AuthScopes.Moderator_Read_Blocked_Terms: - return "moderator:read:blocked_terms"; - case AuthScopes.Moderator_Read_Chat_Settings: - return "moderator:read:chat_settings"; - case AuthScopes.Moderator_Read_Chatters: - return "moderator:read:chatters"; - case AuthScopes.Moderator_Read_Followers: - return "moderator:read:followers"; - case AuthScopes.Moderator_Read_Guest_Star: - return "moderator:read:guest_star"; - case AuthScopes.Moderator_Read_Shield_Mode: - return "moderator:read:shield_mode"; - case AuthScopes.Moderator_Read_Shoutouts: - return "moderator:read:shoutouts"; - case AuthScopes.Moderator_Manage_Guest_Star: - return "moderator:manage:guest_star"; - case AuthScopes.Moderator_Manage_Shield_Mode: - return "moderator:manage:shield_mode"; - case AuthScopes.Moderator_Manage_Shoutouts: - return "moderator:manage:shoutouts"; - case AuthScopes.Any: - case AuthScopes.None: - default: - return string.Empty; - } + AuthScopes.Chat_Read => "chat:read", + AuthScopes.Channel_Moderate => "channel:moderate", + AuthScopes.Chat_Edit => "chat:edit", + AuthScopes.Whisper_Read => "whispers:read", + AuthScopes.Whisper_Edit => "whispers:edit", + AuthScopes.Analytics_Read_Extensions => "analytics:read:extensions", + AuthScopes.Analytics_Read_Games => "analytics:read:games", + AuthScopes.Bits_Read => "bits:read", + AuthScopes.Channel_Edit_Commercial => "channel:edit:commercial", + AuthScopes.Channel_Manage_Broadcast => "channel:manage:broadcast", + AuthScopes.Channel_Manage_Extensions => "channel:manage:extensions", + AuthScopes.Channel_Manage_Moderators => "channel:manage:moderators", + AuthScopes.Channel_Manage_Redemptions => "channel:manage:redemptions", + AuthScopes.Channel_Manage_Polls => "channel:manage:polls", + AuthScopes.Channel_Manage_Predictions => "channel:manage:predictions", + AuthScopes.Channel_Manage_Schedule => "channel:manage:schedule", + AuthScopes.Channel_Manage_Videos => "channel:manage:videos", + AuthScopes.Channel_Manage_VIPs => "channel:manage:vips", + AuthScopes.Channel_Manage_Guest_Star => "channel:manage:guest_star", + AuthScopes.Channel_Manage_Raids => "channel:manage:raids", + AuthScopes.Channel_Read_Charity => "channel:read:charity", + AuthScopes.Channel_Read_Editors => "channel:read:editors", + AuthScopes.Channel_Read_Goals => "channel:read:goals", + AuthScopes.Channel_Read_Hype_Train => "channel:read:hype_train", + AuthScopes.Channel_Read_Polls => "channel:read:polls", + AuthScopes.Channel_Read_Predictions => "channel:read:predictions", + AuthScopes.Channel_Read_Redemptions => "channel:read:redemptions", + AuthScopes.Channel_Read_Stream_Key => "channel:read:stream_key", + AuthScopes.Channel_Read_Subscriptions => "channel:read:subscriptions", + AuthScopes.Channel_Read_VIPs => "channel:read:vips", + AuthScopes.Channel_Read_Guest_Star => "channel:read:guest_star", + AuthScopes.Clips_Edit => "clips:edit", + AuthScopes.Moderation_Read => "moderation:read", + AuthScopes.User_Edit => "user:edit", + AuthScopes.User_Edit_Follows => "user:edit:follows", + AuthScopes.User_Read_BlockedUsers => "user:read:blocked_users", + AuthScopes.User_Read_Broadcast => "user:read:broadcast", + AuthScopes.User_Read_Email => "user:read:email", + AuthScopes.User_Read_Follows => "user:read:follows", + AuthScopes.User_Read_Subscriptions => "user:read:subscriptions", + AuthScopes.User_Manage_BlockedUsers => "user:manage:blocked_users", + AuthScopes.User_Manage_Chat_Color => "user:manage:chat_color", + AuthScopes.User_Manage_Whispers => "user:manage:whispers", + AuthScopes.Moderator_Manage_Announcements => "moderator:manage:announcements", + AuthScopes.Moderator_Manage_Automod => "moderator:manage:automod", + AuthScopes.Moderator_Manage_Automod_Settings => "moderator:manage:automod_settings", + AuthScopes.Moderator_Manage_Banned_Users => "moderator:manage:banned_users", + AuthScopes.Moderator_Manage_Blocked_Terms => "moderator:manage:blocked_terms", + AuthScopes.Moderator_Manage_Chat_Messages => "moderator:manage:chat_messages", + AuthScopes.Moderator_Manage_Chat_Settings => "moderator:manage:chat_settings", + AuthScopes.Moderator_Read_Automod_Settings => "moderator:read:automod_settings", + AuthScopes.Moderator_Read_Blocked_Terms => "moderator:read:blocked_terms", + AuthScopes.Moderator_Read_Chat_Settings => "moderator:read:chat_settings", + AuthScopes.Moderator_Read_Chatters => "moderator:read:chatters", + AuthScopes.Moderator_Read_Followers => "moderator:read:followers", + AuthScopes.Moderator_Read_Guest_Star => "moderator:read:guest_star", + AuthScopes.Moderator_Read_Shield_Mode => "moderator:read:shield_mode", + AuthScopes.Moderator_Read_Shoutouts => "moderator:read:shoutouts", + AuthScopes.Moderator_Manage_Guest_Star => "moderator:manage:guest_star", + AuthScopes.Moderator_Manage_Shield_Mode => "moderator:manage:shield_mode", + AuthScopes.Moderator_Manage_Shoutouts => "moderator:manage:shoutouts", + AuthScopes.Any => string.Empty, + AuthScopes.None => string.Empty, + _ => string.Empty + }; } /// @@ -162,135 +100,72 @@ public static string AuthScopesToString(AuthScopes scope) /// Twitch scope as AuthScope public static AuthScopes StringToScope(string scope) { - switch (scope) + return scope switch { - case "chat:read": - return AuthScopes.Chat_Read; - case "channel:moderate": - return AuthScopes.Channel_Moderate; - case "chat:edit": - return AuthScopes.Chat_Edit; - case "whispers:read": - return AuthScopes.Whisper_Read; - case "whispers:edit": - return AuthScopes.Whisper_Edit; - case "analytics:read:extensions": - return AuthScopes.Analytics_Read_Extensions; - case "analytics:read:games": - return AuthScopes.Analytics_Read_Games; - case "bits:read": - return AuthScopes.Bits_Read; - case "channel:edit:commercial": - return AuthScopes.Channel_Edit_Commercial; - case "channel:manage:broadcast": - return AuthScopes.Channel_Manage_Broadcast; - case "channel:manage:extensions": - return AuthScopes.Channel_Manage_Extensions; - case "channel:manage:moderators": - return AuthScopes.Channel_Manage_Moderators; - case "channel:manage:redemptions": - return AuthScopes.Channel_Manage_Redemptions; - case "channel:manage:polls": - return AuthScopes.Channel_Manage_Polls; - case "channel:manage:predictions": - return AuthScopes.Channel_Manage_Predictions; - case "channel:manage:schedule": - return AuthScopes.Channel_Manage_Schedule; - case "channel:manage:videos": - return AuthScopes.Channel_Manage_Videos; - case "channel:manage:vips": - return AuthScopes.Channel_Manage_VIPs; - case "channel:manage:guest_star": - return AuthScopes.Channel_Manage_Guest_Star; - case "channel:manage:raids": - return AuthScopes.Channel_Manage_Raids; - case "channel:read:charity": - return AuthScopes.Channel_Read_Charity; - case "channel:read:editors": - return AuthScopes.Channel_Read_Editors; - case "channel:read:goals": - return AuthScopes.Channel_Read_Goals; - case "channel:read:hype_train": - return AuthScopes.Channel_Read_Hype_Train; - case "channel:read:polls": - return AuthScopes.Channel_Read_Polls; - case "channel:read:predictions": - return AuthScopes.Channel_Read_Predictions; - case "channel:read:redemptions": - return AuthScopes.Channel_Read_Redemptions; - case "channel:read:stream_key": - return AuthScopes.Channel_Read_Stream_Key; - case "channel:read:subscriptions": - return AuthScopes.Channel_Read_Subscriptions; - case "channel:read:vips": - return AuthScopes.Channel_Read_VIPs; - case "channel:read:guest_star": - return AuthScopes.Channel_Read_Guest_Star; - case "clips:edit": - return AuthScopes.Clips_Edit; - case "moderation:read": - return AuthScopes.Moderation_Read; - case "user:edit": - return AuthScopes.User_Edit; - case "user:edit:follows": - return AuthScopes.User_Edit_Follows; - case "user:read:blocked_users": - return AuthScopes.User_Read_BlockedUsers; - case "user:read:broadcast": - return AuthScopes.User_Read_Broadcast; - case "user:read:email": - return AuthScopes.User_Read_Email; - case "user:read:follows": - return AuthScopes.User_Read_Follows; - case "user:read:subscriptions": - return AuthScopes.User_Read_Subscriptions; - case "user:manage:blocked_users": - return AuthScopes.User_Manage_BlockedUsers; - case "user:manage:chat_color": - return AuthScopes.User_Manage_Chat_Color; - case "user:manage:whispers": - return AuthScopes.User_Manage_Whispers; - case "moderator:manage:announcements": - return AuthScopes.Moderator_Manage_Announcements; - case "moderator:manage:automod": - return AuthScopes.Moderator_Manage_Automod; - case "moderator:manage:automod_settings": - return AuthScopes.Moderator_Manage_Automod_Settings; - case "moderator:manage:banned_users": - return AuthScopes.Moderator_Manage_Banned_Users; - case "moderator:manage:blocked_terms": - return AuthScopes.Moderator_Manage_Blocked_Terms; - case "moderator:manage:chat_messages": - return AuthScopes.Moderator_Manage_Chat_Messages; - case "moderator:manage:chat_settings": - return AuthScopes.Moderator_Manage_Chat_Settings; - case "moderator:manage:guest_star": - return AuthScopes.Moderator_Manage_Guest_Star; - case "moderator:manage:shield_mode": - return AuthScopes.Moderator_Manage_Shield_Mode; - case "moderator:manage:shoutouts": - return AuthScopes.Moderator_Manage_Shoutouts; - case "moderator:read:automod_settings": - return AuthScopes.Moderator_Read_Automod_Settings; - case "moderator:read:blocked_terms": - return AuthScopes.Moderator_Read_Blocked_Terms; - case "moderator:read:chat_settings": - return AuthScopes.Moderator_Read_Chat_Settings; - case "moderator:read:chatters": - return AuthScopes.Moderator_Read_Chatters; - case "moderator:read:followers": - return AuthScopes.Moderator_Read_Followers; - case "moderator:read:guest_star": - return AuthScopes.Moderator_Read_Guest_Star; - case "moderator:read:shield_mode": - return AuthScopes.Moderator_Read_Shield_Mode; - case "moderator:read:shoutouts": - return AuthScopes.Moderator_Read_Shoutouts; - case "": - return AuthScopes.None; - default: - throw new Exception("Unknown scope"); - } + "chat:read" => AuthScopes.Chat_Read, + "channel:moderate" => AuthScopes.Channel_Moderate, + "chat:edit" => AuthScopes.Chat_Edit, + "whispers:read" => AuthScopes.Whisper_Read, + "whispers:edit" => AuthScopes.Whisper_Edit, + "analytics:read:extensions" => AuthScopes.Analytics_Read_Extensions, + "analytics:read:games" => AuthScopes.Analytics_Read_Games, + "bits:read" => AuthScopes.Bits_Read, + "channel:edit:commercial" => AuthScopes.Channel_Edit_Commercial, + "channel:manage:broadcast" => AuthScopes.Channel_Manage_Broadcast, + "channel:manage:extensions" => AuthScopes.Channel_Manage_Extensions, + "channel:manage:moderators" => AuthScopes.Channel_Manage_Moderators, + "channel:manage:redemptions" => AuthScopes.Channel_Manage_Redemptions, + "channel:manage:polls" => AuthScopes.Channel_Manage_Polls, + "channel:manage:predictions" => AuthScopes.Channel_Manage_Predictions, + "channel:manage:schedule" => AuthScopes.Channel_Manage_Schedule, + "channel:manage:videos" => AuthScopes.Channel_Manage_Videos, + "channel:manage:vips" => AuthScopes.Channel_Manage_VIPs, + "channel:manage:guest_star" => AuthScopes.Channel_Manage_Guest_Star, + "channel:manage:raids" => AuthScopes.Channel_Manage_Raids, + "channel:read:charity" => AuthScopes.Channel_Read_Charity, + "channel:read:editors" => AuthScopes.Channel_Read_Editors, + "channel:read:goals" => AuthScopes.Channel_Read_Goals, + "channel:read:hype_train" => AuthScopes.Channel_Read_Hype_Train, + "channel:read:polls" => AuthScopes.Channel_Read_Polls, + "channel:read:predictions" => AuthScopes.Channel_Read_Predictions, + "channel:read:redemptions" => AuthScopes.Channel_Read_Redemptions, + "channel:read:stream_key" => AuthScopes.Channel_Read_Stream_Key, + "channel:read:subscriptions" => AuthScopes.Channel_Read_Subscriptions, + "channel:read:vips" => AuthScopes.Channel_Read_VIPs, + "channel:read:guest_star" => AuthScopes.Channel_Read_Guest_Star, + "clips:edit" => AuthScopes.Clips_Edit, + "moderation:read" => AuthScopes.Moderation_Read, + "user:edit" => AuthScopes.User_Edit, + "user:edit:follows" => AuthScopes.User_Edit_Follows, + "user:read:blocked_users" => AuthScopes.User_Read_BlockedUsers, + "user:read:broadcast" => AuthScopes.User_Read_Broadcast, + "user:read:email" => AuthScopes.User_Read_Email, + "user:read:follows" => AuthScopes.User_Read_Follows, + "user:read:subscriptions" => AuthScopes.User_Read_Subscriptions, + "user:manage:blocked_users" => AuthScopes.User_Manage_BlockedUsers, + "user:manage:chat_color" => AuthScopes.User_Manage_Chat_Color, + "user:manage:whispers" => AuthScopes.User_Manage_Whispers, + "moderator:manage:announcements" => AuthScopes.Moderator_Manage_Announcements, + "moderator:manage:automod" => AuthScopes.Moderator_Manage_Automod, + "moderator:manage:automod_settings" => AuthScopes.Moderator_Manage_Automod_Settings, + "moderator:manage:banned_users" => AuthScopes.Moderator_Manage_Banned_Users, + "moderator:manage:blocked_terms" => AuthScopes.Moderator_Manage_Blocked_Terms, + "moderator:manage:chat_messages" => AuthScopes.Moderator_Manage_Chat_Messages, + "moderator:manage:chat_settings" => AuthScopes.Moderator_Manage_Chat_Settings, + "moderator:manage:guest_star" => AuthScopes.Moderator_Manage_Guest_Star, + "moderator:manage:shield_mode" => AuthScopes.Moderator_Manage_Shield_Mode, + "moderator:manage:shoutouts" => AuthScopes.Moderator_Manage_Shoutouts, + "moderator:read:automod_settings" => AuthScopes.Moderator_Read_Automod_Settings, + "moderator:read:blocked_terms" => AuthScopes.Moderator_Read_Blocked_Terms, + "moderator:read:chat_settings" => AuthScopes.Moderator_Read_Chat_Settings, + "moderator:read:chatters" => AuthScopes.Moderator_Read_Chatters, + "moderator:read:followers" => AuthScopes.Moderator_Read_Followers, + "moderator:read:guest_star" => AuthScopes.Moderator_Read_Guest_Star, + "moderator:read:shield_mode" => AuthScopes.Moderator_Read_Shield_Mode, + "moderator:read:shoutouts" => AuthScopes.Moderator_Read_Shoutouts, + "" => AuthScopes.None, + _ => throw new Exception("Unknown scope") + }; } /// diff --git a/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj b/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj index f1c11827..47f9158e 100644 --- a/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj +++ b/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj @@ -21,6 +21,7 @@ 3.10.0 3.10.0 True + latest diff --git a/TwitchLib.Api.Helix.Models/TwitchLib.Api.Helix.Models.csproj b/TwitchLib.Api.Helix.Models/TwitchLib.Api.Helix.Models.csproj index 4a11874e..d05b2844 100644 --- a/TwitchLib.Api.Helix.Models/TwitchLib.Api.Helix.Models.csproj +++ b/TwitchLib.Api.Helix.Models/TwitchLib.Api.Helix.Models.csproj @@ -21,6 +21,7 @@ 3.10.0 3.10.0 True + latest diff --git a/TwitchLib.Api.Helix/TwitchLib.Api.Helix.csproj b/TwitchLib.Api.Helix/TwitchLib.Api.Helix.csproj index f7fed3d9..0c5fb04a 100644 --- a/TwitchLib.Api.Helix/TwitchLib.Api.Helix.csproj +++ b/TwitchLib.Api.Helix/TwitchLib.Api.Helix.csproj @@ -21,6 +21,7 @@ 3.10.0 3.10.0 True + latest diff --git a/TwitchLib.Api.Test/TwitchLib.Api.Test.csproj b/TwitchLib.Api.Test/TwitchLib.Api.Test.csproj index 01df07a8..260e57e7 100644 --- a/TwitchLib.Api.Test/TwitchLib.Api.Test.csproj +++ b/TwitchLib.Api.Test/TwitchLib.Api.Test.csproj @@ -6,6 +6,8 @@ false True + + latest diff --git a/TwitchLib.Api/TwitchLib.Api.csproj b/TwitchLib.Api/TwitchLib.Api.csproj index f86c442f..b177d133 100644 --- a/TwitchLib.Api/TwitchLib.Api.csproj +++ b/TwitchLib.Api/TwitchLib.Api.csproj @@ -21,6 +21,7 @@ 3.10.0 3.10.0 True + latest From f8abb3884f608fbdf54589132865ac8d812967d7 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Wed, 19 Jul 2023 13:51:16 +0100 Subject: [PATCH 16/55] - Added summaries to Ad Models --- .../Ads/StartCommercialRequest.cs | 29 ++++++++++++---- .../Ads/StartCommercialResponse.cs | 33 ++++++++++++++----- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Ads/StartCommercialRequest.cs b/TwitchLib.Api.Helix.Models/Ads/StartCommercialRequest.cs index 054e4d36..224c9261 100644 --- a/TwitchLib.Api.Helix.Models/Ads/StartCommercialRequest.cs +++ b/TwitchLib.Api.Helix.Models/Ads/StartCommercialRequest.cs @@ -2,11 +2,26 @@ namespace TwitchLib.Api.Helix.Models.Ads { - public class StartCommercialRequest - { - [JsonProperty(PropertyName = "broadcaster_id")] - public string BroadcasterId { get; set; } - [JsonProperty(PropertyName = "length")] - public int Length { get; set; } - } + /// + /// Starts a commercial on the specified channel. + /// Only partners and affiliates may run commercials and they must be streaming live at the time. + /// Only the broadcaster may start a commercial; the broadcaster’s editors and moderators may not start commercials on behalf of the broadcaster. + /// + public class StartCommercialRequest + { + /// + /// The ID of the partner or affiliate broadcaster that wants to run the commercial. + /// This ID must match the user ID found in the OAuth token. + /// + [JsonProperty(PropertyName = "broadcaster_id")] + public string BroadcasterId { get; set; } + + /// + /// The length of the commercial to run, in seconds. + /// Twitch tries to serve a commercial that’s the requested length, but it may be shorter or longer. + /// The maximum length you should request is 180 seconds. + /// + [JsonProperty(PropertyName = "length")] + public int Length { get; set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Ads/StartCommercialResponse.cs b/TwitchLib.Api.Helix.Models/Ads/StartCommercialResponse.cs index c456649f..582b1b42 100644 --- a/TwitchLib.Api.Helix.Models/Ads/StartCommercialResponse.cs +++ b/TwitchLib.Api.Helix.Models/Ads/StartCommercialResponse.cs @@ -2,13 +2,28 @@ namespace TwitchLib.Api.Helix.Models.Ads { - public class StartCommercialResponse - { - [JsonProperty(PropertyName = "length")] - public int Length { get; protected set; } - [JsonProperty(PropertyName = "message")] - public string Message { get; protected set; } - [JsonProperty(PropertyName = "retry_after")] - public int RetryAfter { get; protected set; } - } + /// + /// The response for starting a commercial on a specified channel. + /// + public class StartCommercialResponse + { + /// + /// The length of the commercial you requested. + /// If you request a commercial that’s longer than 180 seconds, the API uses 180 seconds. + /// + [JsonProperty(PropertyName = "length")] + public int Length { get; protected set; } + + /// + /// A message that indicates whether Twitch was able to serve an ad. + /// + [JsonProperty(PropertyName = "message")] + public string Message { get; protected set; } + + /// + /// The number of seconds you must wait before running another commercial. + /// + [JsonProperty(PropertyName = "retry_after")] + public int RetryAfter { get; protected set; } + } } From 09a6630ee086775ac8016075163349eb23b7a2c6 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Wed, 19 Jul 2023 15:22:52 +0100 Subject: [PATCH 17/55] - Added summaries to GetCheermote models --- TwitchLib.Api.Helix.Models/Bits/Cheermote.cs | 76 ++++++++++++++----- .../Bits/GetCheermotesResponse.cs | 16 ++-- TwitchLib.Api.Helix.Models/Bits/ImageList.cs | 30 ++++++-- TwitchLib.Api.Helix.Models/Bits/Images.cs | 30 ++++++-- TwitchLib.Api.Helix.Models/Bits/Tier.cs | 66 ++++++++++++---- 5 files changed, 165 insertions(+), 53 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Bits/Cheermote.cs b/TwitchLib.Api.Helix.Models/Bits/Cheermote.cs index 01b9939d..ef7397fc 100644 --- a/TwitchLib.Api.Helix.Models/Bits/Cheermote.cs +++ b/TwitchLib.Api.Helix.Models/Bits/Cheermote.cs @@ -1,21 +1,61 @@ -using System; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System; namespace TwitchLib.Api.Helix.Models.Bits -{ - public class Cheermote - { - [JsonProperty(PropertyName = "prefix")] - public string Prefix { get; protected set; } - [JsonProperty(PropertyName = "tiers")] - public Tier[] Tiers { get; protected set; } - [JsonProperty(PropertyName = "type")] - public string Type { get; protected set; } - [JsonProperty(PropertyName = "order")] - public int Order { get; protected set; } - [JsonProperty(PropertyName = "last_updated")] - public DateTime LastUpdated { get; protected set; } - [JsonProperty(PropertyName = "is_charitable")] - public bool IsCharitable { get; protected set; } - } +{ /// + /// Cheermotes are animated emotes that viewers can assign Bits to and can be used in any Bits-enabled channel’s chat room. + /// + public class Cheermote + { + /// + /// The name portion of the Cheermote string that you use in chat to cheer Bits. + /// The full Cheermote string is the concatenation of {prefix} + {number of Bits}. + /// For example, if the prefix is “Cheer” and you want to cheer 100 Bits, the full Cheermote string is Cheer100. + /// When the Cheermote string is entered in chat, Twitch converts it to the image associated with the Bits tier that was cheered. + /// + [JsonProperty(PropertyName = "prefix")] + public string Prefix { get; protected set; } + + /// + /// A list of tier levels that the Cheermote supports. + /// Each tier identifies the range of Bits that you can cheer at that tier level and an image that graphically identifies the tier level. + /// + [JsonProperty(PropertyName = "tiers")] + public Tier[] Tiers { get; protected set; } + + /// + /// The type of Cheermote. Possible values are: + /// global_first_party - A Twitch-defined Cheermote that is shown in the Bits card. + /// global_third_party - A Twitch-defined Cheermote that is not shown in the Bits card. + /// channel_custom - A broadcaster-defined Cheermote. + /// display_only - Do not use; for internal use only. + /// sponsored - A sponsor-defined Cheermote. + /// When used, the sponsor adds additional Bits to the amount that the user cheered. + /// For example, if the user cheered Terminator100, the broadcaster might receive 110 Bits, which includes the sponsor's 10 Bits contribution. + /// + [JsonProperty(PropertyName = "type")] + public string Type { get; protected set; } + + /// + /// The order that the Cheermotes are shown in the Bits card. + /// The numbers may not be consecutive. + /// For example, the numbers may jump from 1 to 7 to 13. + /// The order numbers are unique within a Cheermote type (for example, global_first_party) + /// but may not be unique amongst all Cheermotes in the response. + /// + [JsonProperty(PropertyName = "order")] + public int Order { get; protected set; } + + /// + /// The date and time when this Cheermote was last updated. + /// + [JsonProperty(PropertyName = "last_updated")] + public DateTime LastUpdated { get; protected set; } + + /// + /// A Boolean value that indicates whether this Cheermote provides a charitable contribution match during charity campaigns. + /// + [JsonProperty(PropertyName = "is_charitable")] + public bool IsCharitable { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Bits/GetCheermotesResponse.cs b/TwitchLib.Api.Helix.Models/Bits/GetCheermotesResponse.cs index 359eac82..6aeb4165 100644 --- a/TwitchLib.Api.Helix.Models/Bits/GetCheermotesResponse.cs +++ b/TwitchLib.Api.Helix.Models/Bits/GetCheermotesResponse.cs @@ -2,9 +2,15 @@ namespace TwitchLib.Api.Helix.Models.Bits { - public class GetCheermotesResponse - { - [JsonProperty(PropertyName = "data")] - public Cheermote[] Listings { get; protected set; } - } + /// + /// Response from GetCheermotes which gets a list of Cheermotes that users can use to cheer Bits in any Bits-enabled channel’s chat room. + /// + public class GetCheermotesResponse + { + /// + /// The list of Cheermotes. The list is in ascending order by the order field’s value. + /// + [JsonProperty(PropertyName = "data")] + public Cheermote[] Listings { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Bits/ImageList.cs b/TwitchLib.Api.Helix.Models/Bits/ImageList.cs index 62106014..7bd634bb 100644 --- a/TwitchLib.Api.Helix.Models/Bits/ImageList.cs +++ b/TwitchLib.Api.Helix.Models/Bits/ImageList.cs @@ -1,13 +1,27 @@ -using System.Collections.Generic; using Newtonsoft.Json; +using System.Collections.Generic; namespace TwitchLib.Api.Helix.Models.Bits { - public class ImageList - { - [JsonProperty(PropertyName = "animated")] - public Dictionary Animated { get; protected set; } - [JsonProperty(PropertyName = "static")] - public Dictionary Static { get; protected set; } - } + /// + /// Animated and static image sets for a Cheermote. + /// Each set is a dictionary with the following sizes: 1, 1.5, 2, 3, and 4. + /// The value of each size contains the URL to the image. + /// + public class ImageList + { + /// + /// Animated image set for a Cheermote and include the following sizes: 1, 1.5, 2, 3, and 4 + /// The value of each size contains the URL to the image. + /// + [JsonProperty(PropertyName = "animated")] + public Dictionary Animated { get; protected set; } + + /// + /// Static image set for a Cheermote and include the following sizes: 1, 1.5, 2, 3, and 4 + /// The value of each size contains the URL to the image. + /// + [JsonProperty(PropertyName = "static")] + public Dictionary Static { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Bits/Images.cs b/TwitchLib.Api.Helix.Models/Bits/Images.cs index 54e8f017..1ac2feb2 100644 --- a/TwitchLib.Api.Helix.Models/Bits/Images.cs +++ b/TwitchLib.Api.Helix.Models/Bits/Images.cs @@ -2,11 +2,27 @@ namespace TwitchLib.Api.Helix.Models.Bits { - public class Images - { - [JsonProperty(PropertyName = "dark")] - public ImageList Dark { get; protected set; } - [JsonProperty(PropertyName = "light")] - public ImageList Light { get; protected set; } - } + /// + /// The dark and light themes of a Cheermote. + /// Each theme has static and animated formats of the Cheermote. Each format has a dictionary + /// containing multiple image sizes and associated image URLs. + /// + public class Images + { + /// + /// Dark theme key for a Cheermote. + /// Contains the static and animated formats for the Cheermote. + /// Each format has a dictionary containing multiple image sizes and associated image URLs. + /// + [JsonProperty(PropertyName = "dark")] + public ImageList Dark { get; protected set; } + + /// + /// Light theme key for a Cheermote. + /// Contains the static and animated formats for the Cheermote. + /// Each format has a dictionary containing multiple image sizes and associated image URLs. + /// + [JsonProperty(PropertyName = "light")] + public ImageList Light { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Bits/Tier.cs b/TwitchLib.Api.Helix.Models/Bits/Tier.cs index 362ff5c7..52ba82d2 100644 --- a/TwitchLib.Api.Helix.Models/Bits/Tier.cs +++ b/TwitchLib.Api.Helix.Models/Bits/Tier.cs @@ -2,19 +2,55 @@ namespace TwitchLib.Api.Helix.Models.Bits { - public class Tier - { - [JsonProperty(PropertyName = "min_bits")] - public int MinBits { get; protected set; } - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - [JsonProperty(PropertyName = "color")] - public string Color { get; protected set; } - [JsonProperty(PropertyName = "images")] - public Images Images { get; protected set; } - [JsonProperty(PropertyName = "can_cheer")] - public bool CanCheer { get; protected set; } - [JsonProperty(PropertyName = "show_in_bits_card")] - public bool ShowInBitsCard { get; protected set; } - } + /// + /// A list of tier levels that the Cheermote supports. + /// Each tier identifies the range of Bits that you can cheer at that tier level and an image that graphically identifies the tier level. + /// + public class Tier + { + /// + /// The minimum number of Bits that you must cheer at this tier level. + /// The maximum number of Bits that you can cheer at this level is determined by the required minimum Bits of the next tier level minus 1. + /// For example, if min_bits is 1 and min_bits for the next tier is 100, the Bits range for this tier level is 1 through 99. + /// The minimum Bits value of the last tier is the maximum number of Bits you can cheer using this Cheermote. For example, 10000. + /// + [JsonProperty(PropertyName = "min_bits")] + public int MinBits { get; protected set; } + + /// + /// The tier level. Possible tiers are:
+ /// 1 | 100 | 500 | 1,000 | 5,000 | 10,000 | 100,000 + ///
+ [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } + + /// + /// The hex code of the color associated with this tier level (for example, #979797). + /// + [JsonProperty(PropertyName = "color")] + public string Color { get; protected set; } + + /// + /// The animated and static image sets for the Cheermote - organized by theme, format, and size. + /// The theme keys are dark and light.
+ /// Each theme is a dictionary of formats: animated and static.
+ /// Each format is a dictionary with the following sizes: 1, 1.5, 2, 3, and 4.
+ /// The value of each size contains the URL to the image. + ///
+ [JsonProperty(PropertyName = "images")] + public Images Images { get; protected set; } + + /// + /// A Boolean value that determines whether users can cheer at this tier level. + /// + [JsonProperty(PropertyName = "can_cheer")] + public bool CanCheer { get; protected set; } + + /// + /// A Boolean value that determines whether this tier level is shown in the Bits card. + /// Is true if this tier level is shown in the Bits card. + /// + [JsonProperty(PropertyName = "show_in_bits_card")] + public bool ShowInBitsCard { get; protected set; } + } } From 6894abb5a07a494771f846dc3c61426734fc167e Mon Sep 17 00:00:00 2001 From: koishibuh Date: Wed, 19 Jul 2023 15:39:26 +0100 Subject: [PATCH 18/55] - Added summaries to CreateClip models --- .../Clips/CreateClip/CreatedClip.cs | 25 +++++++++++++------ .../Clips/CreateClip/CreatedClipResponse.cs | 16 ++++++++---- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClip.cs b/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClip.cs index 2b2fbdc7..cb0f472e 100644 --- a/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClip.cs +++ b/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClip.cs @@ -2,11 +2,22 @@ namespace TwitchLib.Api.Helix.Models.Clips.CreateClip { - public class CreatedClip - { - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - [JsonProperty(PropertyName = "edit_url")] - public string EditUrl { get; protected set; } - } + /// + /// A Twitch clip created from CreateClip + /// + public class CreatedClip + { + /// + /// An ID that uniquely identifies the clip. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } + + /// + /// A URL that you can use to edit the clip’s title, identify the part of the clip to publish, and publish the clip. + /// The URL is valid for up to 24 hours or until the clip is published, whichever comes first. + /// + [JsonProperty(PropertyName = "edit_url")] + public string EditUrl { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClipResponse.cs b/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClipResponse.cs index 9b2725e6..8dd540e1 100644 --- a/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClipResponse.cs +++ b/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClipResponse.cs @@ -2,9 +2,15 @@ namespace TwitchLib.Api.Helix.Models.Clips.CreateClip { - public class CreatedClipResponse - { - [JsonProperty(PropertyName = "data")] - public CreatedClip[] CreatedClips { get; protected set; } - } + /// + /// Response for CreateClip which creates a clip from the broadcaster's stream. + /// + public class CreatedClipResponse + { + /// + /// Contains clip's ID and edit_URL that can be used to edit the clip's title, identify the part of the clip to publish, and publish the clip. + /// + [JsonProperty(PropertyName = "data")] + public CreatedClip[] CreatedClips { get; protected set; } + } } From 6800786dbb320d953f2842bc57dfe8895f4c5974 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Wed, 19 Jul 2023 15:40:16 +0100 Subject: [PATCH 19/55] - Rearranged CreatedClip model properties to match Twitch API docs for easier comparison --- .../Clips/CreateClip/CreatedClip.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClip.cs b/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClip.cs index cb0f472e..46edc37c 100644 --- a/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClip.cs +++ b/TwitchLib.Api.Helix.Models/Clips/CreateClip/CreatedClip.cs @@ -7,17 +7,17 @@ namespace TwitchLib.Api.Helix.Models.Clips.CreateClip ///
public class CreatedClip { - /// - /// An ID that uniquely identifies the clip. - /// - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - /// /// A URL that you can use to edit the clip’s title, identify the part of the clip to publish, and publish the clip. /// The URL is valid for up to 24 hours or until the clip is published, whichever comes first. /// [JsonProperty(PropertyName = "edit_url")] public string EditUrl { get; protected set; } + + /// + /// An ID that uniquely identifies the clip. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } } } From 152762365ffc11a55d66b049c713ecc52b23be5b Mon Sep 17 00:00:00 2001 From: koishibuh Date: Wed, 19 Jul 2023 15:53:27 +0100 Subject: [PATCH 20/55] - Added summaries for GetClips models --- .../Clips/GetClips/Clip.cs | 140 +++++++++++++----- .../Clips/GetClips/GetClipsResponse.cs | 27 +++- 2 files changed, 125 insertions(+), 42 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Clips/GetClips/Clip.cs b/TwitchLib.Api.Helix.Models/Clips/GetClips/Clip.cs index dc7b7b35..3fbc9569 100644 --- a/TwitchLib.Api.Helix.Models/Clips/GetClips/Clip.cs +++ b/TwitchLib.Api.Helix.Models/Clips/GetClips/Clip.cs @@ -2,39 +2,109 @@ namespace TwitchLib.Api.Helix.Models.Clips.GetClips { - public class Clip - { - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - [JsonProperty(PropertyName = "url")] - public string Url { get; protected set; } - [JsonProperty(PropertyName = "embed_url")] - public string EmbedUrl { get; protected set; } - [JsonProperty(PropertyName = "broadcaster_id")] - public string BroadcasterId { get; protected set; } - [JsonProperty(PropertyName = "broadcaster_name")] - public string BroadcasterName { get; protected set; } - [JsonProperty(PropertyName = "creator_id")] - public string CreatorId { get; protected set; } - [JsonProperty(PropertyName = "creator_name")] - public string CreatorName { get; protected set; } - [JsonProperty(PropertyName = "video_id")] - public string VideoId { get; protected set; } - [JsonProperty(PropertyName = "game_id")] - public string GameId { get; protected set; } - [JsonProperty(PropertyName = "language")] - public string Language { get; protected set; } - [JsonProperty(PropertyName = "title")] - public string Title { get; protected set; } - [JsonProperty(PropertyName = "view_count")] - public int ViewCount { get; protected set; } - [JsonProperty(PropertyName = "created_at")] - public string CreatedAt { get; protected set; } - [JsonProperty(PropertyName = "thumbnail_url")] - public string ThumbnailUrl { get; protected set; } - [JsonProperty(PropertyName = "duration")] - public float Duration { get; protected set; } - [JsonProperty(PropertyName = "vod_offset")] - public int VodOffset { get; protected set; } - } + /// + /// A clip that was created from a broadcaster's stream. + /// + public class Clip + { + /// + /// An ID that uniquely identifies the clip. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } + + /// + /// A URL to the clip. + /// + [JsonProperty(PropertyName = "url")] + public string Url { get; protected set; } + + /// + /// A URL that you can use in an iframe to embed the clip. + /// + [JsonProperty(PropertyName = "embed_url")] + public string EmbedUrl { get; protected set; } + + /// + /// An ID that identifies the broadcaster that the video was clipped from. + /// + [JsonProperty(PropertyName = "broadcaster_id")] + public string BroadcasterId { get; protected set; } + + /// + /// The broadcaster’s display name. + /// + [JsonProperty(PropertyName = "broadcaster_name")] + public string BroadcasterName { get; protected set; } + + /// + /// An ID that identifies the user that created the clip. + /// + [JsonProperty(PropertyName = "creator_id")] + public string CreatorId { get; protected set; } + + /// + /// The display name of the user that created the clip. + /// + [JsonProperty(PropertyName = "creator_name")] + public string CreatorName { get; protected set; } + + /// + /// An ID that identifies the video that the clip came from. + /// This field contains an empty string if the video is not available. + /// + [JsonProperty(PropertyName = "video_id")] + public string VideoId { get; protected set; } + + /// + /// The ID of the game that was being played when the clip was created. + /// + [JsonProperty(PropertyName = "game_id")] + public string GameId { get; protected set; } + + /// + /// The ISO 639-1 two-letter language code that the broadcaster broadcasts in. For example, en for English. + /// The value is other if the broadcaster uses a language that Twitch doesn’t support. + /// + [JsonProperty(PropertyName = "language")] + public string Language { get; protected set; } + + /// + /// The title of the clip. + /// + [JsonProperty(PropertyName = "title")] + public string Title { get; protected set; } + + /// + /// The number of times the clip has been viewed. + /// + [JsonProperty(PropertyName = "view_count")] + public int ViewCount { get; protected set; } + + /// + /// The date and time of when the clip was created. The date and time is in RFC3339 format. + /// + [JsonProperty(PropertyName = "created_at")] + public string CreatedAt { get; protected set; } + + /// + /// A URL to a thumbnail image of the clip. + /// + [JsonProperty(PropertyName = "thumbnail_url")] + public string ThumbnailUrl { get; protected set; } + + /// + /// The length of the clip, in seconds. Precision is 0.1. + /// + [JsonProperty(PropertyName = "duration")] + public float Duration { get; protected set; } + + /// + /// The zero-based offset, in seconds, to where the clip starts in the video (VOD). + /// Is null if the video is not available or hasn’t been created yet from the live stream (see video_id). + /// Note that there’s a delay between when a clip is created during a broadcast and when the offset is set. During the delay period, vod_offset is null. The delay is indeterminant but is typically minutes long. + /// + [JsonProperty(PropertyName = "vod_offset")] + public int VodOffset { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Clips/GetClips/GetClipsResponse.cs b/TwitchLib.Api.Helix.Models/Clips/GetClips/GetClipsResponse.cs index 8012abf4..0d0c9983 100644 --- a/TwitchLib.Api.Helix.Models/Clips/GetClips/GetClipsResponse.cs +++ b/TwitchLib.Api.Helix.Models/Clips/GetClips/GetClipsResponse.cs @@ -3,11 +3,24 @@ namespace TwitchLib.Api.Helix.Models.Clips.GetClips { - public class GetClipsResponse - { - [JsonProperty(PropertyName = "data")] - public Clip[] Clips { get; protected set; } - [JsonProperty(PropertyName = "pagination")] - public Pagination Pagination { get; protected set; } - } + /// + /// Response for GetClips which returns one or more video clips that were captured from streams. + /// + public class GetClipsResponse + { + /// + /// The list of video clips. + /// For clips returned by game_id or broadcaster_id, the list is in descending order by view count. + /// For lists returned by id, the list is in the same order as the input IDs. + /// + [JsonProperty(PropertyName = "data")] + public Clip[] Clips { get; protected set; } + + /// + /// The information used to page through the list of results.
+ /// The object is empty if there are no more pages left to page through.
+ ///
+ [JsonProperty(PropertyName = "pagination")] + public Pagination Pagination { get; protected set; } + } } From 8a247bd81fd1143bf245b099edc26c1b30579606 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 20 Jul 2023 14:10:18 +0100 Subject: [PATCH 21/55] - Added summaries to GetChannelEditors Models --- .../GetChannelEditors/ChannelEditor.cs | 36 +++++++++++++------ .../GetChannelEditorsResponse.cs | 17 ++++++--- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Channels/GetChannelEditors/ChannelEditor.cs b/TwitchLib.Api.Helix.Models/Channels/GetChannelEditors/ChannelEditor.cs index 6db60aee..d27815cf 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetChannelEditors/ChannelEditor.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetChannelEditors/ChannelEditor.cs @@ -1,15 +1,29 @@ -using System; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System; namespace TwitchLib.Api.Helix.Models.Channels.GetChannelEditors { - public class ChannelEditor - { - [JsonProperty(PropertyName = "user_id")] - public string UserId { get; protected set; } - [JsonProperty(PropertyName = "user_name")] - public string UserName { get; protected set; } - [JsonProperty(PropertyName = "created_at")] - public DateTime CreatedAt { get; protected set; } - } + /// + /// A user that is a channel editor for the broadcaster. + /// + public class ChannelEditor + { + /// + /// An ID that uniquely identifies a user with editor permissions. + /// + [JsonProperty(PropertyName = "user_id")] + public string UserId { get; protected set; } + + /// + /// The user’s display name. + /// + [JsonProperty(PropertyName = "user_name")] + public string UserName { get; protected set; } + + /// + /// The date and time when the user became one of the broadcaster’s editors. + /// + [JsonProperty(PropertyName = "created_at")] + public DateTime CreatedAt { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Channels/GetChannelEditors/GetChannelEditorsResponse.cs b/TwitchLib.Api.Helix.Models/Channels/GetChannelEditors/GetChannelEditorsResponse.cs index e646e532..ac9d9654 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetChannelEditors/GetChannelEditorsResponse.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetChannelEditors/GetChannelEditorsResponse.cs @@ -2,9 +2,16 @@ namespace TwitchLib.Api.Helix.Models.Channels.GetChannelEditors { - public class GetChannelEditorsResponse - { - [JsonProperty(PropertyName = "data")] - public ChannelEditor[] Data { get; protected set; } - } + /// + /// Response for GetChannelEditors that returns a list of the broadcaster's channels editors. + /// + public class GetChannelEditorsResponse + { + /// + /// A list of users that are editors for the specified broadcaster. + /// The list is empty if the broadcaster doesn’t have editors. + /// + [JsonProperty(PropertyName = "data")] + public ChannelEditor[] Data { get; protected set; } + } } From baac0cf6a0aad387de15334e2efb07e7b2f64c55 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 20 Jul 2023 14:54:07 +0100 Subject: [PATCH 22/55] - Added summaries to GetChannelInformation models --- .../ChannelInformation.cs | 85 ++++++++++++++----- .../GetChannelInformationResponse.cs | 17 ++-- 2 files changed, 76 insertions(+), 26 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs b/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs index 9e576376..9b864708 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs @@ -2,25 +2,68 @@ namespace TwitchLib.Api.Helix.Models.Channels.GetChannelInformation { - public class ChannelInformation - { - [JsonProperty(PropertyName = "broadcaster_id")] - public string BroadcasterId { get; protected set; } - [JsonProperty(PropertyName = "broadcaster_login")] - public string BroadcasterLogin { get; protected set; } - [JsonProperty(PropertyName = "broadcaster_name")] - public string BroadcasterName { get; protected set; } - [JsonProperty(PropertyName = "broadcaster_language")] - public string BroadcasterLanguage { get; protected set; } - [JsonProperty(PropertyName = "game_id")] - public string GameId { get; protected set; } - [JsonProperty(PropertyName = "game_name")] - public string GameName { get; protected set; } - [JsonProperty(PropertyName = "title")] - public string Title { get; protected set; } - [JsonProperty(PropertyName = "delay")] - public int Delay { get; protected set; } - [JsonProperty(PropertyName = "tags")] - public string[] Tags{get; protected set;} - } + /// + /// Information about a channel + /// + public class ChannelInformation + { + /// + /// An ID that uniquely identifies the broadcaster. + /// + [JsonProperty(PropertyName = "broadcaster_id")] + public string BroadcasterId { get; protected set; } + + /// + /// The broadcaster’s login name. + /// + [JsonProperty(PropertyName = "broadcaster_login")] + public string BroadcasterLogin { get; protected set; } + + /// + /// The broadcaster’s display name. + /// + [JsonProperty(PropertyName = "broadcaster_name")] + public string BroadcasterName { get; protected set; } + + /// + /// The broadcaster’s preferred language. + /// The value is an ISO 639-1 two-letter language code (for example, en for English). The value is set to “other” if the language is not a Twitch supported language. + /// + [JsonProperty(PropertyName = "broadcaster_language")] + public string BroadcasterLanguage { get; protected set; } + + /// + /// An ID that uniquely identifies the game that the broadcaster is playing or last played. + /// The value is an empty string if the broadcaster has never played a game. + /// + [JsonProperty(PropertyName = "game_id")] + public string GameId { get; protected set; } + + /// + /// The name of the game that the broadcaster is playing or last played. + /// The value is an empty string if the broadcaster has never played a game. + /// + [JsonProperty(PropertyName = "game_name")] + public string GameName { get; protected set; } + + /// + /// The title of the stream that the broadcaster is currently streaming or last streamed. + /// The value is an empty string if the broadcaster has never streamed. + /// + [JsonProperty(PropertyName = "title")] + public string Title { get; protected set; } + + /// + /// The value of the broadcaster’s stream delay setting, in seconds. + /// This field’s value defaults to zero unless 1) the request specifies a user access token, 2) the ID in the broadcaster_id query parameter matches the user ID in the access token, and 3) the broadcaster has partner status and they set a non-zero stream delay value. + /// + [JsonProperty(PropertyName = "delay")] + public int Delay { get; protected set; } + + /// + /// The tags applied to the channel. + /// + [JsonProperty(PropertyName = "tags")] + public string[] Tags { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/GetChannelInformationResponse.cs b/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/GetChannelInformationResponse.cs index 679d2654..f90023a3 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/GetChannelInformationResponse.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/GetChannelInformationResponse.cs @@ -2,9 +2,16 @@ namespace TwitchLib.Api.Helix.Models.Channels.GetChannelInformation { - public class GetChannelInformationResponse - { - [JsonProperty(PropertyName = "data")] - public ChannelInformation[] Data { get; protected set; } - } + /// + /// Response for GetChannelInformation which returns information about one or more channels. + /// + public class GetChannelInformationResponse + { + /// + /// A list that contains information about the specified channels. + /// The list is empty if the specified channels weren’t found. + /// + [JsonProperty(PropertyName = "data")] + public ChannelInformation[] Data { get; protected set; } + } } From 31c16a7d408e5bc58245c74e0d7553d9da61cec5 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 20 Jul 2023 14:56:14 +0100 Subject: [PATCH 23/55] - Rerranged ChannelInformation properties to match TwitchAPI documentation --- .../GetChannelInformation/ChannelInformation.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs b/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs index 9b864708..7576587c 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs @@ -25,13 +25,6 @@ public class ChannelInformation [JsonProperty(PropertyName = "broadcaster_name")] public string BroadcasterName { get; protected set; } - /// - /// The broadcaster’s preferred language. - /// The value is an ISO 639-1 two-letter language code (for example, en for English). The value is set to “other” if the language is not a Twitch supported language. - /// - [JsonProperty(PropertyName = "broadcaster_language")] - public string BroadcasterLanguage { get; protected set; } - /// /// An ID that uniquely identifies the game that the broadcaster is playing or last played. /// The value is an empty string if the broadcaster has never played a game. @@ -39,6 +32,13 @@ public class ChannelInformation [JsonProperty(PropertyName = "game_id")] public string GameId { get; protected set; } + /// + /// The broadcaster’s preferred language. + /// The value is an ISO 639-1 two-letter language code (for example, en for English). The value is set to “other” if the language is not a Twitch supported language. + /// + [JsonProperty(PropertyName = "broadcaster_language")] + public string BroadcasterLanguage { get; protected set; } + /// /// The name of the game that the broadcaster is playing or last played. /// The value is an empty string if the broadcaster has never played a game. From 3dea346ded8404543ebbf5cbc12280292ded3861 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 20 Jul 2023 15:00:52 +0100 Subject: [PATCH 24/55] - Added new ContentClassificationLabel & IsBrandedContent properties to ChannelInformation model --- .../GetChannelInformation/ChannelInformation.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs b/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs index 7576587c..b186eab7 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetChannelInformation/ChannelInformation.cs @@ -65,5 +65,17 @@ public class ChannelInformation /// [JsonProperty(PropertyName = "tags")] public string[] Tags { get; protected set; } + + /// + /// The Content Classification Labels (CCL) applied to the channel. + /// + [JsonProperty(PropertyName = "content_classification_labels")] + public string[] ContentClassificationLabels { get; protected set; } + + /// + /// Boolean flag indicating if the channel has branded content. + /// + [JsonProperty(PropertyName = "is_branded_content")] + public bool IsBrandedContent { get; protected set; } } } From 14574362d630587d6fc1461ce4c3069822900999 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 20 Jul 2023 15:49:17 +0100 Subject: [PATCH 25/55] - Updated the GetChannelVIPs models --- .../ChannelVIPsResponseModel.cs | 39 ++++++++++--------- .../GetChannelVIPs/GetChannelVIPsResponse.cs | 31 ++++++++------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Channels/GetChannelVIPs/ChannelVIPsResponseModel.cs b/TwitchLib.Api.Helix.Models/Channels/GetChannelVIPs/ChannelVIPsResponseModel.cs index 7a3265e4..4faaa420 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetChannelVIPs/ChannelVIPsResponseModel.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetChannelVIPs/ChannelVIPsResponseModel.cs @@ -2,22 +2,25 @@ namespace TwitchLib.Api.Helix.Models.Channels.GetChannelVIPs { - public class ChannelVIPsResponseModel - { - /// - /// An ID that uniquely identifies the VIP user. - /// - [JsonProperty(PropertyName = "user_id")] - public string UserId { get; protected set; } - /// - /// The user’s display name. - /// - [JsonProperty(PropertyName = "user_name")] - public string UserName { get; protected set; } - /// - /// The user’s login name. - /// - [JsonProperty(PropertyName = "user_login")] - public string UserLogin { get; protected set; } - } + /// + /// A user that is a VIP in a broadcaster's channel. + /// + public class ChannelVIPsResponseModel + { + /// + /// An ID that uniquely identifies the VIP user. + /// + [JsonProperty(PropertyName = "user_id")] + public string UserId { get; protected set; } + /// + /// The user’s display name. (Name has capitalization) + /// + [JsonProperty(PropertyName = "user_name")] + public string UserName { get; protected set; } + /// + /// The user’s login name. (Name is lowercase) + /// + [JsonProperty(PropertyName = "user_login")] + public string UserLogin { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Channels/GetChannelVIPs/GetChannelVIPsResponse.cs b/TwitchLib.Api.Helix.Models/Channels/GetChannelVIPs/GetChannelVIPsResponse.cs index 4fea7dc3..4334c4da 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetChannelVIPs/GetChannelVIPsResponse.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetChannelVIPs/GetChannelVIPsResponse.cs @@ -3,17 +3,22 @@ namespace TwitchLib.Api.Helix.Models.Channels.GetChannelVIPs { - public class GetChannelVIPsResponse - { - /// - /// The list of VIPs. The list is empty if the channel doesn’t have VIP users. The list does not include the broadcaster. - /// - [JsonProperty(PropertyName = "data")] - public ChannelVIPsResponseModel[] Data { get; protected set; } - /// - /// Contains the information used to page through the list of results. - /// - [JsonProperty(PropertyName = "pagination")] - public Pagination Pagination { get; protected set; } - } + /// + /// Response for GetVIPs that returns a list of the broadcaster's VIPs. + /// + public class GetChannelVIPsResponse + { + /// + /// The list of VIPs. + /// The list is empty if the channel doesn’t have VIP users. The list does not include the broadcaster. + /// + [JsonProperty(PropertyName = "data")] + public ChannelVIPsResponseModel[] Data { get; protected set; } + + /// + /// Contains the information used to page through the list of results. + /// + [JsonProperty(PropertyName = "pagination")] + public Pagination Pagination { get; protected set; } + } } From 7cccadbf5f5fd7d9103d90d91688d959da374822 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 20 Jul 2023 16:07:38 +0100 Subject: [PATCH 26/55] - Updated the GetFollowedChannel models --- .../GetFollowedChannels/FollowedChannel.cs | 55 ++++++++++--------- .../GetFollowedChannelsResponse.cs | 50 +++++++++-------- 2 files changed, 57 insertions(+), 48 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Channels/GetFollowedChannels/FollowedChannel.cs b/TwitchLib.Api.Helix.Models/Channels/GetFollowedChannels/FollowedChannel.cs index 9cb5a08b..862bf899 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetFollowedChannels/FollowedChannel.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetFollowedChannels/FollowedChannel.cs @@ -2,30 +2,33 @@ namespace TwitchLib.Api.Helix.Models.Channels.GetFollowedChannels { - public class FollowedChannel - { - /// - /// An ID that uniquely identifies the broadcaster that this user is following. - /// - [JsonProperty(PropertyName = "broadcaster_id")] - public string BroadcasterId { get; protected set; } - - /// - /// The broadcaster’s login name. - /// - [JsonProperty(PropertyName = "broadcaster_login")] - public string BroadcasterLogin { get; protected set; } - - /// - /// The broadcaster’s display name. - /// - [JsonProperty(PropertyName = "broadcaster_name")] - public string BroadcasterName { get; protected set; } - - /// - /// The UTC timestamp when the user started following the broadcaster. - /// - [JsonProperty(PropertyName = "followed_at")] - public string FollowedAt { get; protected set; } - } + /// + /// The broadcaster a user is following. + /// + public class FollowedChannel + { + /// + /// An ID that uniquely identifies the broadcaster that this user is following. + /// + [JsonProperty(PropertyName = "broadcaster_id")] + public string BroadcasterId { get; protected set; } + + /// + /// The broadcaster’s login name. (Name is lowercase) + /// + [JsonProperty(PropertyName = "broadcaster_login")] + public string BroadcasterLogin { get; protected set; } + + /// + /// The broadcaster’s display name. (Name has capitalization) + /// + [JsonProperty(PropertyName = "broadcaster_name")] + public string BroadcasterName { get; protected set; } + + /// + /// The UTC timestamp when the user started following the broadcaster. + /// + [JsonProperty(PropertyName = "followed_at")] + public string FollowedAt { get; protected set; } + } } \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/Channels/GetFollowedChannels/GetFollowedChannelsResponse.cs b/TwitchLib.Api.Helix.Models/Channels/GetFollowedChannels/GetFollowedChannelsResponse.cs index b4a23263..679bfdb0 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetFollowedChannels/GetFollowedChannelsResponse.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetFollowedChannels/GetFollowedChannelsResponse.cs @@ -3,26 +3,32 @@ namespace TwitchLib.Api.Helix.Models.Channels.GetFollowedChannels { - public class GetFollowedChannelsResponse - { - /// - /// The list of broadcasters that the user follows. - /// The list is in descending order by followed_at (with the most recently followed broadcaster first). - /// The list is empty if the user doesn’t follow anyone. - /// - [JsonProperty(PropertyName = "data")] - public FollowedChannel[] Data { get; protected set; } - - /// - /// Contains the information used to page through the list of results. The object is empty if there are no more pages left to page through. - /// - [JsonProperty(PropertyName = "pagination")] - public Pagination Pagination { get; protected set; } - - /// - /// The total number of broadcasters that the user follows. As someone pages through the list, the number may change as the user follows or unfollows broadcasters. - /// - [JsonProperty(PropertyName = "total")] - public int Total { get; protected set; } - } + /// + /// The response for GetFollowedChannels that returns a list of broadcasters that the specified user follows. + /// This can also return whether a user follows a specific broadcaster. + /// + public class GetFollowedChannelsResponse + { + /// + /// The list of broadcasters that the user follows. + /// The list is in descending order by followed_at, with the most recently followed broadcaster first. + /// The list is empty if the user doesn’t follow anyone. + /// + [JsonProperty(PropertyName = "data")] + public FollowedChannel[] Data { get; protected set; } + + /// + /// Contains the information used to page through the list of results. + /// The object is empty if there are no more pages left to page through. + /// + [JsonProperty(PropertyName = "pagination")] + public Pagination Pagination { get; protected set; } + + /// + /// The total number of broadcasters that the user follows. + /// As someone pages through the list, the number may change as the user follows or unfollows broadcasters. + /// + [JsonProperty(PropertyName = "total")] + public int Total { get; protected set; } + } } \ No newline at end of file From 0947954bb890c9c7617b3b23a98c72c8da3ea57c Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 20 Jul 2023 16:55:41 +0100 Subject: [PATCH 27/55] - Added summary to ModifyChannelInformation model --- .../ModifyChannelInformationRequest.cs | 61 ++++++++++++++----- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs b/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs index e807e776..51f10750 100644 --- a/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs +++ b/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs @@ -2,18 +2,51 @@ namespace TwitchLib.Api.Helix.Models.Channels.ModifyChannelInformation { - [JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)] - public class ModifyChannelInformationRequest - { - [JsonProperty(PropertyName = "game_id", NullValueHandling = NullValueHandling.Ignore)] - public string GameId { get; set; } - [JsonProperty(PropertyName = "title", NullValueHandling = NullValueHandling.Ignore)] - public string Title { get; set; } - [JsonProperty(PropertyName = "broadcaster_language", NullValueHandling = NullValueHandling.Ignore)] - public string BroadcasterLanguage { get; set; } - [JsonProperty(PropertyName = "delay", NullValueHandling = NullValueHandling.Ignore)] - public int? Delay { get; set; } - [JsonProperty(PropertyName = "tags", NullValueHandling = NullValueHandling.Ignore)] - public string[] Tags { get; set; } - } + /// + /// A request to update a channel's properties + /// All fields are optional but you must specify at least one field. + /// + [JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)] + public class ModifyChannelInformationRequest + { + /// + /// The ID of the game that the broadcaster will be playing. + /// The game will not updated if the ID is not a game ID that Twitch recognizes. + /// To unset this field, use “0” or “” (an empty string). + /// + [JsonProperty(PropertyName = "game_id", NullValueHandling = NullValueHandling.Ignore)] + public string GameId { get; set; } + + /// + /// The title of the broadcaster's stream. + /// You may not set this field to an empty string. + /// + [JsonProperty(PropertyName = "title", NullValueHandling = NullValueHandling.Ignore)] + public string Title { get; set; } + + /// + /// The broadcaster’s preferred language. + /// Set the value to an ISO 639-1 two-letter language code - for example, en for English. + /// Set the value to “other” if the broadcaster’s preferred language is not a Twitch supported language. + /// The language will not updated if the language code is not a Twitch supported language. + /// + [JsonProperty(PropertyName = "broadcaster_language", NullValueHandling = NullValueHandling.Ignore)] + public string BroadcasterLanguage { get; set; } + + /// + /// The number of seconds you want your broadcast buffered before streaming it live. The delay helps ensure fairness during competitive play. + /// The maximum delay is 900 seconds (15 minutes). + /// Only users with Partner status may set this field. + /// + [JsonProperty(PropertyName = "delay", NullValueHandling = NullValueHandling.Ignore)] + public int? Delay { get; set; } + + /// + /// A list of channel-defined tags to apply to the channel. Tags help identify the content that the channel streams. + /// A channel may specify a maximum of 10 tags. Each tag is limited to a maximum of 25 characters and may not be an empty string or contain spaces or special characters. Tags are case insensitive. For readability, consider using camelCasing or PascalCasing. + /// To remove all tags from the channel, set tags to an empty array. + /// + [JsonProperty(PropertyName = "tags", NullValueHandling = NullValueHandling.Ignore)] + public string[] Tags { get; set; } + } } From 86e485e20f8a1cc36f00c2b38bbcf11638668e36 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 20 Jul 2023 17:38:17 +0100 Subject: [PATCH 28/55] - Rearranged the ModifyChannelInformation model to match TwitchAPI docs --- .../ModifyChannelInformationRequest.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs b/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs index 51f10750..7ca2a849 100644 --- a/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs +++ b/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs @@ -17,13 +17,6 @@ public class ModifyChannelInformationRequest [JsonProperty(PropertyName = "game_id", NullValueHandling = NullValueHandling.Ignore)] public string GameId { get; set; } - /// - /// The title of the broadcaster's stream. - /// You may not set this field to an empty string. - /// - [JsonProperty(PropertyName = "title", NullValueHandling = NullValueHandling.Ignore)] - public string Title { get; set; } - /// /// The broadcaster’s preferred language. /// Set the value to an ISO 639-1 two-letter language code - for example, en for English. @@ -33,6 +26,13 @@ public class ModifyChannelInformationRequest [JsonProperty(PropertyName = "broadcaster_language", NullValueHandling = NullValueHandling.Ignore)] public string BroadcasterLanguage { get; set; } + /// + /// The title of the broadcaster's stream. + /// You may not set this field to an empty string. + /// + [JsonProperty(PropertyName = "title", NullValueHandling = NullValueHandling.Ignore)] + public string Title { get; set; } + /// /// The number of seconds you want your broadcast buffered before streaming it live. The delay helps ensure fairness during competitive play. /// The maximum delay is 900 seconds (15 minutes). From 0ef3e75efc16a0171728fc5010fc291eb1d9955f Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 20 Jul 2023 17:49:32 +0100 Subject: [PATCH 29/55] - Added the ContentClassificationLabel to the ModifyChannelInformation model - Created a ContentClassificationLabel enum - Created a ContentClassificationLabel class to use in the ModifyChannelInformation model --- .../ContentClassificationLabelEnum.cs | 38 +++++++++++++++++++ .../ContentClassificationLabel.cs | 25 ++++++++++++ .../ModifyChannelInformationRequest.cs | 12 ++++++ 3 files changed, 75 insertions(+) create mode 100644 TwitchLib.Api.Core.Enums/ContentClassificationLabelEnum.cs create mode 100644 TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ContentClassificationLabel.cs diff --git a/TwitchLib.Api.Core.Enums/ContentClassificationLabelEnum.cs b/TwitchLib.Api.Core.Enums/ContentClassificationLabelEnum.cs new file mode 100644 index 00000000..0bbe4efd --- /dev/null +++ b/TwitchLib.Api.Core.Enums/ContentClassificationLabelEnum.cs @@ -0,0 +1,38 @@ +namespace TwitchLib.Api.Core.Enums +{ + /// + /// Enum representing the Content Classification Labels. + /// + public enum ContentClassificationLabelEnum + { + /// + /// Content Classification Label for broadcasts with excessive tobacco glorification or promotion, + /// any marijuana consumption/use, legal drug and alcohol induced intoxication, discussions of illegal drugs. + /// + DrugsIntoxication, + + /// + /// Content Classification Label for broadcasts with content that focuses on + /// sexualized physical attributes and activities, sexual topics, or experiences. + /// + SexualThemes, + + /// + /// Content Classification Label for broadcasts with simulations and/or depictions + /// of realistic violence, gore, extreme injury, or death. + /// + ViolentGraphic, + + /// + /// Content Classification Label for broadcasts that participate in online or + /// in-person gambling, poker or fantasy sports, that involve the exchange of real money. + /// + Gambling, + + /// + /// Content Classification Label for broadcasts with prolonged, and repeated use + /// of obscenities, profanities, and vulgarities, especially as a regular part of speech. + /// + ProfanityVulgarity + } +} diff --git a/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ContentClassificationLabel.cs b/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ContentClassificationLabel.cs new file mode 100644 index 00000000..df98358a --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ContentClassificationLabel.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; +using TwitchLib.Api.Core.Enums; + +namespace TwitchLib.Api.Helix.Models.Channels.ModifyChannelInformation +{ + /// + /// Labels that can be set for the channel's Content Classification Labels + /// + public class ContentClassificationLabel + { + /// + /// ID of the Content Classification Labels that must be added/removed from the channel. + /// Can be one of the following values: + /// DrugsIntoxication, SexualThemes, ViolentGraphic, Gambling, ProfanityVulgarity + /// + [JsonProperty(PropertyName = "id")] + public ContentClassificationLabelEnum Id { get; set; } + + /// + /// Boolean flag indicating whether the label should be enabled (true) or disabled (false) for the channel. + /// + [JsonProperty(PropertyName = "is_enabled")] + public bool IsEnabled { get; set; } + } +} diff --git a/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs b/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs index 7ca2a849..793f67d9 100644 --- a/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs +++ b/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ModifyChannelInformationRequest.cs @@ -48,5 +48,17 @@ public class ModifyChannelInformationRequest /// [JsonProperty(PropertyName = "tags", NullValueHandling = NullValueHandling.Ignore)] public string[] Tags { get; set; } + + /// + /// List of labels that should be set as the Channel’s Content Classificiation Labels (CCL). + /// + [JsonProperty(PropertyName = "content_classification_labels", NullValueHandling = NullValueHandling.Ignore)] + public ContentClassificationLabel[] ContentClassificationLabels { get; set; } + + /// + /// Boolean flag indicating if the channel has branded content. + /// + [JsonProperty(PropertyName = "is_branded_content", NullValueHandling = NullValueHandling.Ignore)] + public bool IsBrandedContent { get; set; } } } From 43dc5b75011aa2d78c5df10759344a01a0029792 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Thu, 20 Jul 2023 18:51:06 +0100 Subject: [PATCH 30/55] - Updated summaries for GetCharityCampaign & GetCharityCampaignDonations --- TwitchLib.Api.Helix.Models/Charity/Amount.cs | 46 +++---- .../CharityCampaignResponseModel.cs | 112 +++++++++--------- .../GetCharityCampaignResponse.cs | 26 ++-- .../CharityCampaignDonationsResponseModel.cs | 72 +++++------ .../GetCharityCampaignDonationsResponse.cs | 39 +++--- 5 files changed, 152 insertions(+), 143 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Charity/Amount.cs b/TwitchLib.Api.Helix.Models/Charity/Amount.cs index b5fdb1aa..3b0796f3 100644 --- a/TwitchLib.Api.Helix.Models/Charity/Amount.cs +++ b/TwitchLib.Api.Helix.Models/Charity/Amount.cs @@ -2,28 +2,30 @@ namespace TwitchLib.Api.Helix.Models.Charity { - public class Amount - { - /// - /// The monetary amount. - /// The amount is specified in the currency’s minor unit. - /// For example, the minor units for USD is cents, so if the amount is $5.50 USD, value is set to 550. - /// - [JsonProperty(PropertyName = "value")] - public int? Value { get; protected set; } + /// + /// + /// + public class Amount + { + /// + /// The monetary amount specified in the currency’s minor unit. + /// For example, the minor units for USD is cents, so if the amount is $5.50 USD, value is set to 550. + /// + [JsonProperty(PropertyName = "value")] + public int? Value { get; protected set; } - /// - /// The number of decimal places used by the currency. - /// For example, USD uses two decimal places. - /// Use this number to translate value from minor units to major units by using the formula: value / 10^decimal_places - /// - [JsonProperty(PropertyName = "decimal_places")] - public int? DecimalPlaces { get; protected set; } + /// + /// The number of decimal places used by the currency.
+ /// For example, USD uses two decimal places.
+ /// Use this number to translate value from minor units to major units by using the formula: value / 10^decimal_places + ///
+ [JsonProperty(PropertyName = "decimal_places")] + public int? DecimalPlaces { get; protected set; } - /// - /// The ISO-4217 three-letter currency code that identifies the type of currency in value. - /// - [JsonProperty(PropertyName = "currency")] - public string Currency { get; protected set; } - } + /// + /// The ISO-4217 three-letter currency code that identifies the type of currency in value. + /// + [JsonProperty(PropertyName = "currency")] + public string Currency { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaign/CharityCampaignResponseModel.cs b/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaign/CharityCampaignResponseModel.cs index 39c105ad..3da2f504 100644 --- a/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaign/CharityCampaignResponseModel.cs +++ b/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaign/CharityCampaignResponseModel.cs @@ -2,67 +2,71 @@ namespace TwitchLib.Api.Helix.Models.Charity.GetCharityCampaign { - public class CharityCampaignResponseModel - { - /// - /// An ID that uniquely identifies the charity campaign. - /// - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } + /// + /// The charity campaign a broadcaster is raising money for through their channel. + /// + public class CharityCampaignResponseModel + { + /// + /// An ID that uniquely identifies the charity campaign. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } - /// - /// An ID that uniquely identifies the broadcaster that’s running the campaign. - /// - [JsonProperty(PropertyName = "broadcaster_id")] - public string BroadcasterId { get; protected set; } + /// + /// An ID that uniquely identifies the broadcaster that’s running the campaign. + /// + [JsonProperty(PropertyName = "broadcaster_id")] + public string BroadcasterId { get; protected set; } - /// - /// The broadcaster’s login name. - /// - [JsonProperty(PropertyName = "broadcaster_login")] - public string BroadcasterLogin { get; protected set; } + /// + /// The broadcaster’s login name. (Name is lowercase) + /// + [JsonProperty(PropertyName = "broadcaster_login")] + public string BroadcasterLogin { get; protected set; } - /// - /// The broadcaster’s display name. - /// - [JsonProperty(PropertyName = "broadcaster_name")] - public string BroadcasterName { get; protected set; } + /// + /// The broadcaster’s display name. (Name has capitalization) + /// + [JsonProperty(PropertyName = "broadcaster_name")] + public string BroadcasterName { get; protected set; } - /// - /// The charity’s name. - /// - [JsonProperty(PropertyName = "charity_name")] - public string CharityName { get; protected set; } + /// + /// The charity’s name. + /// + [JsonProperty(PropertyName = "charity_name")] + public string CharityName { get; protected set; } - /// - /// A description of the charity. - /// - [JsonProperty(PropertyName = "charity_description")] - public string CharityDescription { get; protected set; } + /// + /// A description of the charity. + /// + [JsonProperty(PropertyName = "charity_description")] + public string CharityDescription { get; protected set; } - /// - /// A URL to an image of the charity’s logo. The image’s type is PNG and its size is 100px X 100px. - /// - [JsonProperty(PropertyName = "charity_logo")] - public string CharityLogo { get; protected set; } + /// + /// A URL to an image of the charity’s logo.
+ /// The image’s type is PNG and its size is 100px X 100px.
+ ///
+ [JsonProperty(PropertyName = "charity_logo")] + public string CharityLogo { get; protected set; } - /// - /// A URL to the charity’s website. - /// - [JsonProperty(PropertyName = "charity_website")] - public string CharityWebsite { get; protected set; } + /// + /// A URL to the charity’s website. + /// + [JsonProperty(PropertyName = "charity_website")] + public string CharityWebsite { get; protected set; } - /// - /// An object that contains the current amount of donations that the campaign has received. - /// - [JsonProperty(PropertyName = "current_amount")] - public Amount CurrentAmount { get; protected set; } + /// + /// An object that contains the current amount of donations that the campaign has received. + /// + [JsonProperty(PropertyName = "current_amount")] + public Amount CurrentAmount { get; protected set; } - /// - /// An object that contains the amount of money that the campaign is trying to raise. - /// This field may be null if the broadcaster has not defined a target goal. - /// - [JsonProperty(PropertyName = "target_amount")] - public Amount TargetAmount { get; protected set; } - } + /// + /// An object that contains the amount of money that the campaign is trying to raise. + /// This field may be null if the broadcaster has not defined a target fundraising goal. + /// + [JsonProperty(PropertyName = "target_amount")] + public Amount TargetAmount { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaign/GetCharityCampaignResponse.cs b/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaign/GetCharityCampaignResponse.cs index ddff4041..ee5e1ba2 100644 --- a/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaign/GetCharityCampaignResponse.cs +++ b/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaign/GetCharityCampaignResponse.cs @@ -2,17 +2,17 @@ namespace TwitchLib.Api.Helix.Models.Charity.GetCharityCampaign { - public class GetCharityCampaignResponse - { - /// - /// A list that contains the charity campaign that the broadcaster is currently running. - /// The array is empty if the broadcaster is not running a charity campaign; - /// The campaign information is no longer available as soon as the campaign ends. - /// - [JsonProperty(PropertyName = "data")] - public CharityCampaignResponseModel[] Data { get; protected set; } - } + /// + /// The response for the GetCharityCampaign that returns information about the charity campaign that a broadcaster is running. + /// + public class GetCharityCampaignResponse + { + /// + /// A list that contains the charity campaign that the broadcaster is currently running. + /// The array is empty if the broadcaster is not running a charity campaign. + /// The campaign information is no longer available as soon as the campaign ends. + /// + [JsonProperty(PropertyName = "data")] + public CharityCampaignResponseModel[] Data { get; protected set; } + } } - - - diff --git a/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaignDonations/CharityCampaignDonationsResponseModel.cs b/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaignDonations/CharityCampaignDonationsResponseModel.cs index 225501a4..58619971 100644 --- a/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaignDonations/CharityCampaignDonationsResponseModel.cs +++ b/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaignDonations/CharityCampaignDonationsResponseModel.cs @@ -1,46 +1,46 @@ using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Text; namespace TwitchLib.Api.Helix.Models.Charity.GetCharityCampaignDonations { - public class CharityCampaignDonationsResponseModel - { - /// - /// An ID that identifies the donation. The ID is unique across campaigns. - /// - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } + /// + /// Donations that users have made to the broadcaster's active charity campaign. + /// + public class CharityCampaignDonationsResponseModel + { + /// + /// An ID that identifies the donation. The ID is unique across campaigns. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } - /// - /// An ID that identifies the charity campaign that the donation applies to. - /// - [JsonProperty(PropertyName = "campaign_id")] - public string CampaignId { get; protected set; } + /// + /// An ID that identifies the charity campaign that the donation applies to. + /// + [JsonProperty(PropertyName = "campaign_id")] + public string CampaignId { get; protected set; } - /// - /// An ID that identifies a user that donated money to the campaign. - /// - [JsonProperty(PropertyName = "user_id")] - public string UserId { get; protected set; } + /// + /// An ID that identifies a user that donated money to the campaign. + /// + [JsonProperty(PropertyName = "user_id")] + public string UserId { get; protected set; } - /// - /// The user’s login name. - /// - [JsonProperty(PropertyName = "user_login")] - public string UserLogin { get; protected set; } + /// + /// The user’s login name. (Name is lowercase) + /// + [JsonProperty(PropertyName = "user_login")] + public string UserLogin { get; protected set; } - /// - /// The user’s display name. - /// - [JsonProperty(PropertyName = "user_name")] - public string UserName { get; protected set; } + /// + /// The user’s display name. (Name has capitalization) + /// + [JsonProperty(PropertyName = "user_name")] + public string UserName { get; protected set; } - /// - /// An object that contains the amount of money that the user donated. - /// - [JsonProperty(PropertyName = "amount")] - public Amount Amount { get; protected set; } - } + /// + /// An object that contains the amount of money that the user donated. + /// + [JsonProperty(PropertyName = "amount")] + public Amount Amount { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaignDonations/GetCharityCampaignDonationsResponse.cs b/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaignDonations/GetCharityCampaignDonationsResponse.cs index 5c2104a3..bc7f30e8 100644 --- a/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaignDonations/GetCharityCampaignDonationsResponse.cs +++ b/TwitchLib.Api.Helix.Models/Charity/GetCharityCampaignDonations/GetCharityCampaignDonationsResponse.cs @@ -1,24 +1,27 @@ using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Text; using TwitchLib.Api.Helix.Models.Common; namespace TwitchLib.Api.Helix.Models.Charity.GetCharityCampaignDonations { - public class GetCharityCampaignDonationsResponse - { - /// - /// A list that contains the donations that users have made to the broadcaster’s charity campaign. - /// The list is empty if the broadcaster is not currently running a charity campaign; - /// The donation information is not available after the campaign ends. - /// - [JsonProperty(PropertyName = "data")] - public CharityCampaignDonationsResponseModel[] Data { get; protected set; } - /// - /// Contains the information used to page through the list of results. - /// - [JsonProperty(PropertyName = "pagination")] - public Pagination Pagination { get; protected set; } - } + /// + /// The response for GetCharityCampaignDonations that returns a list of donations that + /// users have made to the broadcaster's active charity campaign. + /// + public class GetCharityCampaignDonationsResponse + { + /// + /// A list that contains the donations that users have made to the broadcaster’s charity campaign. + /// The list is empty if the broadcaster is not currently running a charity campaign. + /// The donation information is not available after the campaign ends. + /// + [JsonProperty(PropertyName = "data")] + public CharityCampaignDonationsResponseModel[] Data { get; protected set; } + + /// + /// Contains the information used to page through the list of results. + /// The object is empty if there are no more pages left to page through. + /// + [JsonProperty(PropertyName = "pagination")] + public Pagination Pagination { get; protected set; } + } } From ceae85722120bc180a836fb5f921a1a5c7f28ea3 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Fri, 21 Jul 2023 14:27:17 +0100 Subject: [PATCH 31/55] - Added a string converter to the ContentClassificationLabel --- .../ModifyChannelInformation/ContentClassificationLabel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ContentClassificationLabel.cs b/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ContentClassificationLabel.cs index df98358a..84ec9d7a 100644 --- a/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ContentClassificationLabel.cs +++ b/TwitchLib.Api.Helix.Models/Channels/ModifyChannelInformation/ContentClassificationLabel.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using TwitchLib.Api.Core.Enums; namespace TwitchLib.Api.Helix.Models.Channels.ModifyChannelInformation @@ -13,6 +14,7 @@ public class ContentClassificationLabel /// Can be one of the following values: /// DrugsIntoxication, SexualThemes, ViolentGraphic, Gambling, ProfanityVulgarity ///
+ [JsonConverter(typeof(StringEnumConverter))] [JsonProperty(PropertyName = "id")] public ContentClassificationLabelEnum Id { get; set; } From 7b18ca2d7e5ee6bb1de6fe6d9b3cef4a6e2babf9 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Fri, 21 Jul 2023 16:51:38 +0100 Subject: [PATCH 32/55] - Added ContentClassificationLabel to the Helix class - Added ContentClassificationLabels class with GetContentClassificationAsync method - Added GetContentClassificationLabelsResponse with model --- .../ContentClassificationLabel.cs | 28 ++ .../GetContentClassificationLabelsResponse.cs | 16 + .../ContentClassificationLabels.cs | 47 +++ TwitchLib.Api.Helix/Helix.cs | 335 +++++++++--------- 4 files changed, 261 insertions(+), 165 deletions(-) create mode 100644 TwitchLib.Api.Helix.Models/ContentClassificationLabels/ContentClassificationLabel.cs create mode 100644 TwitchLib.Api.Helix.Models/ContentClassificationLabels/GetContentClassificationLabelsResponse.cs create mode 100644 TwitchLib.Api.Helix/ContentClassificationLabels.cs diff --git a/TwitchLib.Api.Helix.Models/ContentClassificationLabels/ContentClassificationLabel.cs b/TwitchLib.Api.Helix.Models/ContentClassificationLabels/ContentClassificationLabel.cs new file mode 100644 index 00000000..1a35973a --- /dev/null +++ b/TwitchLib.Api.Helix.Models/ContentClassificationLabels/ContentClassificationLabel.cs @@ -0,0 +1,28 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.ContentClassificationLabels +{ + /// + /// The list of Content Classification Labels available. + /// + public class ContentClassificationLabel + { + /// + /// Unique identifier for the Content Classification Labels. + /// + [JsonProperty(PropertyName = "id")] + public string ID { get; set; } + + /// + /// Localized description of the Content Classification Labels. + /// + [JsonProperty(PropertyName = "description")] + public string Description { get; set; } + + /// + /// Localized name of the Content Classification Labels. + /// + [JsonProperty(PropertyName = "name")] + public string Name { get; set; } + } +} diff --git a/TwitchLib.Api.Helix.Models/ContentClassificationLabels/GetContentClassificationLabelsResponse.cs b/TwitchLib.Api.Helix.Models/ContentClassificationLabels/GetContentClassificationLabelsResponse.cs new file mode 100644 index 00000000..8aecdd7f --- /dev/null +++ b/TwitchLib.Api.Helix.Models/ContentClassificationLabels/GetContentClassificationLabelsResponse.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.ContentClassificationLabels +{ + /// + /// Response from GetContentClassificationLabels which gets information about Twitch content classification labels. + /// + public class GetContentClassificationLabelsResponse + { + /// + /// A list that contains information about the available content classification labels. + /// + [JsonProperty(PropertyName = "data")] + public ContentClassificationLabel[] Data { get; protected set; } + } +} diff --git a/TwitchLib.Api.Helix/ContentClassificationLabels.cs b/TwitchLib.Api.Helix/ContentClassificationLabels.cs new file mode 100644 index 00000000..35285991 --- /dev/null +++ b/TwitchLib.Api.Helix/ContentClassificationLabels.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using TwitchLib.Api.Core; +using TwitchLib.Api.Core.Enums; +using TwitchLib.Api.Core.Interfaces; +using TwitchLib.Api.Helix.Models.ContentClassificationLabels; + +namespace TwitchLib.Api.Helix +{ + /// + /// ContentClassificationLabels related APIs + /// + public class ContentClassificationLabels : ApiBase + { + /// + /// + /// + /// + /// + /// + public ContentClassificationLabels(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandler http) : base(settings, rateLimiter, http) + {} + + #region GetContentClassificationLabels + /// + /// + /// TwitchAPI Docs: Get Content Classification Labels + /// Gets information about Twitch content classification labels. + /// Requires an app access token or user access token. + /// + /// + /// + /// + public Task GetContentClassificationLabelsAsync(string locale = null, string accessToken = null) + { + var getParams = new List>(); + + if (!string.IsNullOrWhiteSpace(locale)) + { + getParams.Add(new KeyValuePair("locale", locale)); + } + + return TwitchGetGenericAsync("/content_classification_labels", ApiVersion.Helix, getParams, accessToken); + } + #endregion + } +} diff --git a/TwitchLib.Api.Helix/Helix.cs b/TwitchLib.Api.Helix/Helix.cs index f1fe5dc1..6bb2a321 100644 --- a/TwitchLib.Api.Helix/Helix.cs +++ b/TwitchLib.Api.Helix/Helix.cs @@ -6,171 +6,176 @@ namespace TwitchLib.Api.Helix { - /// - /// Contains APIs under the /helix API namespace - /// - public class Helix - { - private readonly ILogger _logger; - /// - /// API Settings like the ClientId, Client Secret and so on - /// - public IApiSettings Settings { get; } - /// - /// Analytics related Helix APIs - /// - public Analytics Analytics { get; } - /// - /// Ads related Helix APIs - /// - public Ads Ads { get; } - /// - /// Bits related Helix APIs - /// - public Bits Bits { get; } - /// - /// Chat related Helix APIs - /// - public Chat Chat { get; } - /// - /// Channel related Helix APIs - /// - public Channels Channels { get; } - /// - /// Channel Points related Helix APIs - /// - public ChannelPoints ChannelPoints { get; } - /// - /// Charity related Helix APIs - /// - public Charity Charity { get; } - /// - /// Clips related Helix APIs - /// - public Clips Clips { get; } - /// - /// Entitlements related Helix APIs - /// - public Entitlements Entitlements { get; } - /// - /// EventSub related Helix APIs - /// - public EventSub EventSub { get; } - /// - /// Extensions related Helix APIs - /// - public Extensions Extensions { get; } - /// - /// Games related Helix APIs - /// - public Games Games { get; } - /// - /// Creator Goals related Helix APIs - /// - public Goals Goals { get; } - /// - /// HypeTrain related Helix APIs - /// - public HypeTrain HypeTrain { get; } - /// - /// Moderation related Helix APIs - /// - public Moderation Moderation { get; } - /// - /// Polls related Helix APIs - /// - public Polls Polls { get; } - /// - /// Prediction related Helix APIs - /// - public Predictions Predictions { get; } - /// - /// Raids related Helix APIs - /// - public Raids Raids { get; } - /// - /// Schedule related Helix APIs - /// - public Schedule Schedule { get; } - /// - /// Search related Helix APIs - /// - public Search Search { get; } - /// - /// Soundtrack related Helix APIs - /// - public Soundtrack Soundtrack { get; } - /// - /// Stream related Helix APIs - /// - public Streams Streams { get; } - /// - /// Subscription related Helix APIs - /// - public Subscriptions Subscriptions { get; } - /// - /// Tag related Helix APIs - /// - public Tags Tags { get; } - /// - /// Stream Team related Helix APIs - /// - public Teams Teams { get; } - /// - /// Video/VOD related Helix APIs - /// - public Videos Videos { get; } - /// - /// User related Helix APIs - /// - public Users Users { get; } - /// - /// Whisper related Helix APIs - /// - public Whispers Whispers { get; } + /// + /// Contains APIs under the /helix API namespace + /// + public class Helix + { + private readonly ILogger _logger; + /// + /// API Settings like the ClientId, Client Secret and so on + /// + public IApiSettings Settings { get; } + /// + /// Analytics related Helix APIs + /// + public Analytics Analytics { get; } + /// + /// Ads related Helix APIs + /// + public Ads Ads { get; } + /// + /// Bits related Helix APIs + /// + public Bits Bits { get; } + /// + /// Chat related Helix APIs + /// + public Chat Chat { get; } + /// + /// Channel related Helix APIs + /// + public Channels Channels { get; } + /// + /// Channel Points related Helix APIs + /// + public ChannelPoints ChannelPoints { get; } + /// + /// Charity related Helix APIs + /// + public Charity Charity { get; } + /// + /// Clips related Helix APIs + /// + public Clips Clips { get; } + /// + /// Entitlements related Helix APIs + /// + public Entitlements Entitlements { get; } + /// + /// ContentClassificationLabels related Helix APIs + /// + public ContentClassificationLabels ContentClassificationLabels { get; } + /// + /// EventSub related Helix APIs + /// + public EventSub EventSub { get; } + /// + /// Extensions related Helix APIs + /// + public Extensions Extensions { get; } + /// + /// Games related Helix APIs + /// + public Games Games { get; } + /// + /// Creator Goals related Helix APIs + /// + public Goals Goals { get; } + /// + /// HypeTrain related Helix APIs + /// + public HypeTrain HypeTrain { get; } + /// + /// Moderation related Helix APIs + /// + public Moderation Moderation { get; } + /// + /// Polls related Helix APIs + /// + public Polls Polls { get; } + /// + /// Prediction related Helix APIs + /// + public Predictions Predictions { get; } + /// + /// Raids related Helix APIs + /// + public Raids Raids { get; } + /// + /// Schedule related Helix APIs + /// + public Schedule Schedule { get; } + /// + /// Search related Helix APIs + /// + public Search Search { get; } + /// + /// Soundtrack related Helix APIs + /// + public Soundtrack Soundtrack { get; } + /// + /// Stream related Helix APIs + /// + public Streams Streams { get; } + /// + /// Subscription related Helix APIs + /// + public Subscriptions Subscriptions { get; } + /// + /// Tag related Helix APIs + /// + public Tags Tags { get; } + /// + /// Stream Team related Helix APIs + /// + public Teams Teams { get; } + /// + /// Video/VOD related Helix APIs + /// + public Videos Videos { get; } + /// + /// User related Helix APIs + /// + public Users Users { get; } + /// + /// Whisper related Helix APIs + /// + public Whispers Whispers { get; } - /// - /// Creates an Instance of the Helix Class. - /// - /// Instance Of LoggerFactory, otherwise no logging is used, - /// Instance Of RateLimiter, otherwise no ratelimiter is used. - /// Instance of ApiSettings, otherwise defaults used, can be changed later - /// Instance of HttpCallHandler, otherwise default handler used - public Helix(ILoggerFactory loggerFactory = null, IRateLimiter rateLimiter = null, IApiSettings settings = null, IHttpCallHandler http = null) - { - _logger = loggerFactory?.CreateLogger(); - rateLimiter = rateLimiter ?? BypassLimiter.CreateLimiterBypassInstance(); - http = http ?? new TwitchHttpClient(loggerFactory?.CreateLogger()); - Settings = settings ?? new ApiSettings(); + /// + /// Creates an Instance of the Helix Class. + /// + /// Instance Of LoggerFactory, otherwise no logging is used. + /// Instance Of RateLimiter, otherwise no ratelimiter is used. + /// Instance of ApiSettings, otherwise defaults used. (Can be changed later) + /// Instance of HttpCallHandler, otherwise default handler used. + public Helix(ILoggerFactory loggerFactory = null, IRateLimiter rateLimiter = null, IApiSettings settings = null, IHttpCallHandler http = null) + { + _logger = loggerFactory?.CreateLogger(); + rateLimiter = rateLimiter ?? BypassLimiter.CreateLimiterBypassInstance(); + http = http ?? new TwitchHttpClient(loggerFactory?.CreateLogger()); + Settings = settings ?? new ApiSettings(); - Analytics = new Analytics(Settings, rateLimiter, http); - Ads = new Ads(Settings, rateLimiter, http); - Bits = new Bits(Settings, rateLimiter, http); - Chat = new Chat(Settings, rateLimiter, http); - Channels = new Channels(Settings, rateLimiter, http); - ChannelPoints = new ChannelPoints(Settings, rateLimiter, http); - Charity = new Charity(Settings, rateLimiter, http); - Clips = new Clips(Settings, rateLimiter, http); - Entitlements = new Entitlements(Settings, rateLimiter, http); - EventSub = new EventSub(Settings, rateLimiter, http); - Extensions = new Extensions(Settings, rateLimiter, http); - Games = new Games(Settings, rateLimiter, http); - Goals = new Goals(settings, rateLimiter, http); - HypeTrain = new HypeTrain(Settings, rateLimiter, http); - Moderation = new Moderation(Settings, rateLimiter, http); - Polls = new Polls(Settings, rateLimiter, http); - Predictions = new Predictions(Settings, rateLimiter, http); - Raids = new Raids(settings, rateLimiter, http); - Schedule = new Schedule(Settings, rateLimiter, http); - Search = new Search(Settings, rateLimiter, http); - Soundtrack = new Soundtrack(Settings, rateLimiter, http); - Streams = new Streams(Settings, rateLimiter, http); - Subscriptions = new Subscriptions(Settings, rateLimiter, http); - Tags = new Tags(Settings, rateLimiter, http); - Teams = new Teams(Settings, rateLimiter, http); - Users = new Users(Settings, rateLimiter, http); - Videos = new Videos(Settings, rateLimiter, http); - Whispers = new Whispers(Settings, rateLimiter, http); - } - } + Analytics = new Analytics(Settings, rateLimiter, http); + Ads = new Ads(Settings, rateLimiter, http); + Bits = new Bits(Settings, rateLimiter, http); + Chat = new Chat(Settings, rateLimiter, http); + Channels = new Channels(Settings, rateLimiter, http); + ChannelPoints = new ChannelPoints(Settings, rateLimiter, http); + Charity = new Charity(Settings, rateLimiter, http); + Clips = new Clips(Settings, rateLimiter, http); + ContentClassificationLabels = new ContentClassificationLabels(Settings, rateLimiter, http); + Entitlements = new Entitlements(Settings, rateLimiter, http); + EventSub = new EventSub(Settings, rateLimiter, http); + Extensions = new Extensions(Settings, rateLimiter, http); + Games = new Games(Settings, rateLimiter, http); + Goals = new Goals(settings, rateLimiter, http); + HypeTrain = new HypeTrain(Settings, rateLimiter, http); + Moderation = new Moderation(Settings, rateLimiter, http); + Polls = new Polls(Settings, rateLimiter, http); + Predictions = new Predictions(Settings, rateLimiter, http); + Raids = new Raids(settings, rateLimiter, http); + Schedule = new Schedule(Settings, rateLimiter, http); + Search = new Search(Settings, rateLimiter, http); + Soundtrack = new Soundtrack(Settings, rateLimiter, http); + Streams = new Streams(Settings, rateLimiter, http); + Subscriptions = new Subscriptions(Settings, rateLimiter, http); + Tags = new Tags(Settings, rateLimiter, http); + Teams = new Teams(Settings, rateLimiter, http); + Users = new Users(Settings, rateLimiter, http); + Videos = new Videos(Settings, rateLimiter, http); + Whispers = new Whispers(Settings, rateLimiter, http); + } + } } From d3298240c7bc17577e0eafe97e533bce35a0c5f8 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Fri, 21 Jul 2023 17:51:48 +0100 Subject: [PATCH 33/55] - Updated Summary for Ad EndPoints & Ad model --- .../Ads/StartCommercialRequest.cs | 16 +++--- TwitchLib.Api.Helix/Ads.cs | 54 ++++++++++--------- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Ads/StartCommercialRequest.cs b/TwitchLib.Api.Helix.Models/Ads/StartCommercialRequest.cs index 224c9261..dc53cb9c 100644 --- a/TwitchLib.Api.Helix.Models/Ads/StartCommercialRequest.cs +++ b/TwitchLib.Api.Helix.Models/Ads/StartCommercialRequest.cs @@ -3,25 +3,23 @@ namespace TwitchLib.Api.Helix.Models.Ads { /// - /// Starts a commercial on the specified channel. - /// Only partners and affiliates may run commercials and they must be streaming live at the time. - /// Only the broadcaster may start a commercial; the broadcaster’s editors and moderators may not start commercials on behalf of the broadcaster. + /// Request Body for StartCommercial /// public class StartCommercialRequest { /// - /// The ID of the partner or affiliate broadcaster that wants to run the commercial. - /// This ID must match the user ID found in the OAuth token. + /// The ID of the partner or affiliate broadcaster that wants to run the commercial. + /// This ID must match the user ID found in the OAuth token. /// [JsonProperty(PropertyName = "broadcaster_id")] public string BroadcasterId { get; set; } /// - /// The length of the commercial to run, in seconds. - /// Twitch tries to serve a commercial that’s the requested length, but it may be shorter or longer. - /// The maximum length you should request is 180 seconds. + /// The length of the commercial to run, in seconds. + /// Twitch tries to serve a commercial that’s the requested length, but it may be shorter or longer. + /// The maximum length you should request is 180 seconds. /// [JsonProperty(PropertyName = "length")] public int Length { get; set; } } -} +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix/Ads.cs b/TwitchLib.Api.Helix/Ads.cs index 463ce9cb..9844a7c9 100644 --- a/TwitchLib.Api.Helix/Ads.cs +++ b/TwitchLib.Api.Helix/Ads.cs @@ -1,5 +1,5 @@ -using System.Threading.Tasks; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System.Threading.Tasks; using TwitchLib.Api.Core; using TwitchLib.Api.Core.Enums; using TwitchLib.Api.Core.Interfaces; @@ -7,27 +7,33 @@ namespace TwitchLib.Api.Helix { - /// - /// Ads related APIs - /// - public class Ads : ApiBase - { - public Ads(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandler http) : base(settings, rateLimiter, http) - { - } + /// + /// Ads related APIs + /// + public class Ads : ApiBase + { + public Ads(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandler http) : base(settings, rateLimiter, http) + { + } - #region StartCommercial - /// - /// Starts a commercial on a specified channel. - /// Required scope: channel:edit:commercial - /// - /// - /// optional access token to override the use of the stored one in the TwitchAPI instance - /// - public Task StartCommercialAsync(StartCommercialRequest request, string accessToken = null) - { - return TwitchPostGenericAsync("/channels/commercial", ApiVersion.Helix, JsonConvert.SerializeObject(request), null, accessToken); - } - #endregion - } + #region StartCommercial + + /// + /// + /// Twitch Docs: Start Commercial + /// Starts a commercial on the specified channel. + /// Only partners and affiliates may run commercials and they must be streaming live at the time. + /// Only the broadcaster may start a commercial - the broadcaster’s editors and moderators may not start commercials on behalf of the broadcaster. + /// Requires a user access token that includes the channel:edit:commercial scope. + /// + /// + /// Optional access token to override the use of the stored one in the TwitchAPI instance. + /// + public Task StartCommercialAsync(StartCommercialRequest request, string accessToken = null) + { + return TwitchPostGenericAsync("/channels/commercial", ApiVersion.Helix, JsonConvert.SerializeObject(request), null, accessToken); + } + + #endregion + } } From 93261001dbedac91da83b58a72a4441f938ff8c3 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Fri, 21 Jul 2023 19:33:38 +0100 Subject: [PATCH 34/55] - Added summary to Pagination model --- .../Common/Pagination.cs | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Common/Pagination.cs b/TwitchLib.Api.Helix.Models/Common/Pagination.cs index 38e32463..40f00698 100644 --- a/TwitchLib.Api.Helix.Models/Common/Pagination.cs +++ b/TwitchLib.Api.Helix.Models/Common/Pagination.cs @@ -2,9 +2,19 @@ namespace TwitchLib.Api.Helix.Models.Common { - public class Pagination - { - [JsonProperty(PropertyName = "cursor")] - public string Cursor { get; protected set; } - } + /// + /// + /// Twitch Docs: Pagination + /// Contains the cusor for the page. + /// The object is empty if there are no more pages left to page through. + /// + public class Pagination + { + /// + /// The cursor used to get the next page of results. + /// Use the cursor’s value to set the after or before query parameter depending on the direction you want to page. + /// + [JsonProperty(PropertyName = "cursor")] + public string Cursor { get; protected set; } + } } From b5ff96d3241c513257fcfa37388991c75f94e143 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Fri, 21 Jul 2023 21:17:32 +0100 Subject: [PATCH 35/55] - Update summary for Analytics - Fixed summary bug in Anayltics.GetExtensionAnalyticsAsync() that copied the incorrect startedAt & endedAt information - Added summary for ExtensionAnalytics - Added summary for GetExtensionResponse - Added summary for GameAnalytics - Added summary for GetGameAnalyticsResponse - Added summary for DateRange --- .../Analytics/ExtensionAnalytics.cs | 41 ++- .../Analytics/GameAnalytics.cs | 41 ++- .../GetExtensionAnalyticsResponse.cs | 20 +- .../Analytics/GetGameAnalyticsResponse.cs | 31 +- .../Common/DateRange.cs | 28 +- TwitchLib.Api.Helix/Analytics.cs | 326 ++++++++++-------- 6 files changed, 306 insertions(+), 181 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Analytics/ExtensionAnalytics.cs b/TwitchLib.Api.Helix.Models/Analytics/ExtensionAnalytics.cs index 446a426b..87100e74 100644 --- a/TwitchLib.Api.Helix.Models/Analytics/ExtensionAnalytics.cs +++ b/TwitchLib.Api.Helix.Models/Analytics/ExtensionAnalytics.cs @@ -3,15 +3,34 @@ namespace TwitchLib.Api.Helix.Models.Analytics { - public class ExtensionAnalytics - { - [JsonProperty(PropertyName = "extension_id")] - public string ExtensionId { get; protected set; } - [JsonProperty(PropertyName = "URL")] - public string Url { get; protected set; } - [JsonProperty(PropertyName = "type")] - public string Type { get; protected set; } - [JsonProperty(PropertyName = "date_range")] - public DateRange DateRange { get; protected set; } - } + /// + /// A analytic report for an extension. + /// + public class ExtensionAnalytics + { + /// + /// An ID that identifies the extension that the analytic report was generated for. + /// + [JsonProperty(PropertyName = "extension_id")] + public string ExtensionId { get; protected set; } + + /// + /// The URL that you use to download the analytic report. + /// The URL is valid for 5 minutes. + /// + [JsonProperty(PropertyName = "URL")] + public string Url { get; protected set; } + + /// + /// The type of analytic report. + /// + [JsonProperty(PropertyName = "type")] + public string Type { get; protected set; } + + /// + /// The reporting periods start and end dates. + /// + [JsonProperty(PropertyName = "date_range")] + public DateRange DateRange { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Analytics/GameAnalytics.cs b/TwitchLib.Api.Helix.Models/Analytics/GameAnalytics.cs index 38d01984..963311aa 100644 --- a/TwitchLib.Api.Helix.Models/Analytics/GameAnalytics.cs +++ b/TwitchLib.Api.Helix.Models/Analytics/GameAnalytics.cs @@ -3,15 +3,34 @@ namespace TwitchLib.Api.Helix.Models.Analytics { - public class GameAnalytics - { - [JsonProperty(PropertyName = "game_id")] - public string GameId { get; protected set; } - [JsonProperty(PropertyName = "URL")] - public string Url { get; protected set; } - [JsonProperty(PropertyName = "type")] - public string Type { get; protected set; } - [JsonProperty(PropertyName = "date_range")] - public DateRange DateRange { get; protected set; } - } + /// + /// + /// + public class GameAnalytics + { + /// + /// An ID that identifies the game that the analytic report was generated for. + /// + [JsonProperty(PropertyName = "game_id")] + public string GameId { get; protected set; } + + /// + /// The URL that you use to download the analytic report. + /// The URL is valid for 5 minutes. + /// + [JsonProperty(PropertyName = "URL")] + public string Url { get; protected set; } + + /// + /// The type of analytic report. + /// + [JsonProperty(PropertyName = "type")] + public string Type { get; protected set; } + + /// + /// The reporting period’s start and end dates. + /// + [JsonProperty(PropertyName = "date_range")] + public DateRange DateRange { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Analytics/GetExtensionAnalyticsResponse.cs b/TwitchLib.Api.Helix.Models/Analytics/GetExtensionAnalyticsResponse.cs index a34bd995..7ee47c44 100644 --- a/TwitchLib.Api.Helix.Models/Analytics/GetExtensionAnalyticsResponse.cs +++ b/TwitchLib.Api.Helix.Models/Analytics/GetExtensionAnalyticsResponse.cs @@ -2,9 +2,19 @@ namespace TwitchLib.Api.Helix.Models.Analytics { - public class GetExtensionAnalyticsResponse - { - [JsonProperty(PropertyName = "data")] - public ExtensionAnalytics[] Data { get; protected set; } - } + /// + /// The response for GetExtensionAnalytics that gets a list of analytic reports for one or more extensions. + /// The response contains the URLs used to download the reports (CSV files) and the URLs are only valid for 5 minutes. + /// + public class GetExtensionAnalyticsResponse + { + /// + /// A list of analytic reports for the extensions. + /// The reports are returned in no particular order; however, the data within each report is in ascending order by date (newest first). + /// The report contains one row of data per day of the reporting window and only contains rows for the days that the extension was used. + /// The array is empty if there are no reports. + /// + [JsonProperty(PropertyName = "data")] + public ExtensionAnalytics[] Data { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Analytics/GetGameAnalyticsResponse.cs b/TwitchLib.Api.Helix.Models/Analytics/GetGameAnalyticsResponse.cs index 1bb03bfd..9781ff30 100644 --- a/TwitchLib.Api.Helix.Models/Analytics/GetGameAnalyticsResponse.cs +++ b/TwitchLib.Api.Helix.Models/Analytics/GetGameAnalyticsResponse.cs @@ -3,11 +3,28 @@ namespace TwitchLib.Api.Helix.Models.Analytics { - public class GetGameAnalyticsResponse - { - [JsonProperty(PropertyName = "data")] - public GameAnalytics[] Data { get; protected set; } - [JsonProperty(PropertyName = "pagination")] - public Pagination Pagination { get; protected set; } - } + /// + /// Response for GetGameAnalytics which gets gets a list of analytic reports for one or more games. + /// The response contains the URLs used to download the reports (CSV files) and the URLs are only valid for 5 minutes. + /// + public class GetGameAnalyticsResponse + { + /// + /// A list of game analytics reports. + /// The reports are returned in no particular order; however, the data within each report is in ascending order by date (newest first). + /// The report contains one row of data per day of the reporting window and only contains rows the days that the game was used. + /// A report is available only if the game was broadcast for at least 5 hours over the reporting period. + /// The array is empty if there are no reports. + /// + [JsonProperty(PropertyName = "data")] + public GameAnalytics[] Data { get; protected set; } + + /// + /// Contains the information used to page through the list of results. + /// The object is empty if there are no more pages left to page through. + /// Use the cursor to set the GetGameAnalytics request’s after query parameter. + /// + [JsonProperty(PropertyName = "pagination")] + public Pagination Pagination { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix.Models/Common/DateRange.cs b/TwitchLib.Api.Helix.Models/Common/DateRange.cs index ddcfa8bb..a278bd9f 100644 --- a/TwitchLib.Api.Helix.Models/Common/DateRange.cs +++ b/TwitchLib.Api.Helix.Models/Common/DateRange.cs @@ -1,13 +1,23 @@ -using System; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System; namespace TwitchLib.Api.Helix.Models.Common { - public class DateRange - { - [JsonProperty(PropertyName = "started_at")] - public DateTime StartedAt { get; protected set; } - [JsonProperty(PropertyName = "ended_at")] - public DateTime EndedAt { get; protected set; } - } + /// + /// The reporting period's start and end dates + /// + public class DateRange + { + /// + /// The reporting period's start date. + /// + [JsonProperty(PropertyName = "started_at")] + public DateTime StartedAt { get; protected set; } + + /// + /// The reporting period's end date. + /// + [JsonProperty(PropertyName = "ended_at")] + public DateTime EndedAt { get; protected set; } + } } diff --git a/TwitchLib.Api.Helix/Analytics.cs b/TwitchLib.Api.Helix/Analytics.cs index 07121cf4..f5563edc 100644 --- a/TwitchLib.Api.Helix/Analytics.cs +++ b/TwitchLib.Api.Helix/Analytics.cs @@ -9,142 +9,192 @@ namespace TwitchLib.Api.Helix { - /// - /// Analytics related APIs - /// - public class Analytics : ApiBase - { - public Analytics(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandler http) : base(settings, rateLimiter, http) - { - } - - #region GetGameAnalytics - - /// - /// Gets a URL that game developers can use to download analytics reports (CSV files) for their games. The URL is valid for 5 minutes. - /// !! the Token used to call this API has to be from a member of the Org the Game is registered to !! - /// Required scope: analytics:read:games - /// - /// - /// Game ID. If this is specified, the returned URL points to an analytics report for just the specified game. - /// If this is not specified, the response includes multiple URLs (paginated), pointing to separate analytics reports for each of the authenticated user’s games. - /// - /// - /// Starting date/time for returned reports, in RFC3339 format with the hours, minutes, and seconds zeroed out and the UTC timezone: YYYY-MM-DDT00:00:00Z. - /// If this is provided, endedAt also must be specified. - /// If startedAt is earlier than the default start date, the default date is used. - /// Default: 365 days before the report was issued. The file contains one row of data per day. - /// - /// - /// Ending date/time for returned reports, in RFC3339 format with the hours, minutes, and seconds zeroed out and the UTC timezone: YYYY-MM-DDT00:00:00Z. - /// The report covers the entire ending date; e.g., if 2018-05-01T00:00:00Z is specified, the report covers up to 2018-05-01T23:59:59Z. - /// If this is provided, startedAt also must be specified. - /// If endedAt is later than the default end date, the default date is used. - /// Default: 1-2 days before the request was issued (depending on report availability). - /// - /// Maximum number of objects to return. Maximum: 100. Default: 20. - /// - /// Cursor for forward pagination: tells the server where to start fetching the next set of results, in a multi-page response. - /// This applies only to queries without gameId. - /// - /// - /// Type of analytics report that is returned. - /// Currently, this field has no affect on the response as there is only one report type. - /// If additional types were added, using this field would return only the URL for the specified report. - /// Valid values: "overview_v2". - /// - /// optional access token to override the use of the stored one in the TwitchAPI instance - /// - public Task GetGameAnalyticsAsync(string gameId = null, DateTime? startedAt = null, DateTime? endedAt = null, int first = 20, string after = null, string type = null, string accessToken = null) - { - var getParams = new List> - { - new KeyValuePair("first", first.ToString()) - }; - - if (!string.IsNullOrWhiteSpace(gameId)) - getParams.Add(new KeyValuePair("game_id", gameId)); - - if (startedAt != null && endedAt != null) - { - getParams.Add(new KeyValuePair("started_at", startedAt.Value.ToRfc3339String())); - getParams.Add(new KeyValuePair("ended_at", endedAt.Value.ToRfc3339String())); - } - - if (!string.IsNullOrWhiteSpace(type)) - getParams.Add(new KeyValuePair("type", type)); - - if (!string.IsNullOrWhiteSpace(after)) - getParams.Add(new KeyValuePair("after", after)); - - return TwitchGetGenericAsync("/analytics/games", ApiVersion.Helix, getParams, accessToken); - } - - #endregion - - #region GetExtensionAnalytics - - /// - /// Gets a URL that Extension developers can use to download analytics reports (CSV files) for their Extensions. The URL is valid for 5 minutes. - /// !! the Token used to call this API has to be from a member of the Org the Extension is registered to, or if not part of an Org, the Extension Developer !! - /// Required scope: analytics:read:extensions - /// - /// - /// Client ID value assigned to the extension when it is created. If this is specified, the returned URL points to an analytics report for just the specified extension. - /// If this is not specified, the response includes multiple URLs (paginated), pointing to separate analytics reports for each of the authenticated user’s Extensions. - /// - /// - /// Starting date/time for returned reports, in RFC3339 format with the hours, minutes, and seconds zeroed out and the UTC timezone: YYYY-MM-DDT00:00:00Z. - /// If this is provided, endedAt also must be specified. - /// If startedAt is earlier than the default start date, the default date is used. - /// Default: 365 days before the report was issued. The file contains one row of data per day. - /// - /// - /// Ending date/time for returned reports, in RFC3339 format with the hours, minutes, and seconds zeroed out and the UTC timezone: YYYY-MM-DDT00:00:00Z. - /// The report covers the entire ending date; e.g., if 2018-05-01T00:00:00Z is specified, the report covers up to 2018-05-01T23:59:59Z. - /// If this is provided, startedAt also must be specified. - /// If endedAt is later than the default end date, the default date is used. - /// Default: 1-2 days before the request was issued (depending on report availability). - /// - /// Maximum number of objects to return. Maximum: 100. Default: 20. - /// - /// Cursor for forward pagination: tells the server where to start fetching the next set of results, in a multi-page response. - /// This applies only to queries without gameId. - /// - /// - /// Type of analytics report that is returned. - /// Currently, this field has no affect on the response as there is only one report type. - /// If additional types were added, using this field would return only the URL for the specified report. - /// Valid values: "overview_v2". - /// - /// optional access token to override the use of the stored one in the TwitchAPI instance - /// - public Task GetExtensionAnalyticsAsync(string extensionId, DateTime? startedAt = null, DateTime? endedAt = null, int first = 20, string after = null, string type = null, string accessToken = null) - { - var getParams = new List> - { - new KeyValuePair("first", first.ToString()) - }; - - if (!string.IsNullOrWhiteSpace(extensionId)) - getParams.Add(new KeyValuePair("extension_id", extensionId)); - - if (startedAt != null && endedAt != null) - { - getParams.Add(new KeyValuePair("started_at", startedAt.Value.ToRfc3339String())); - getParams.Add(new KeyValuePair("ended_at", endedAt.Value.ToRfc3339String())); - } - - if (!string.IsNullOrWhiteSpace(type)) - getParams.Add(new KeyValuePair("type", type)); - - if (!string.IsNullOrWhiteSpace(after)) - getParams.Add(new KeyValuePair("after", after)); - - return TwitchGetGenericAsync("/analytics/extensions", ApiVersion.Helix, getParams, accessToken); - } - - #endregion - - } + /// + /// Analytics related APIs + /// + public class Analytics : ApiBase + { + /// + /// Analytics related APIs + /// + /// + /// + /// + public Analytics(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandler http) : base(settings, rateLimiter, http) + { + } + + #region GetGameAnalytics + + /// + /// + /// Twitch Docs: Get Game Analytics + /// Gets a URL that game developers can use to download analytics reports (CSV files) for their games. The URL is valid for 5 minutes. + /// !! The user access token used to call this API must be from a member of the organization the game is registered to !! + /// Requires a user access token that includes the scope:
+ /// analytics:read:games
+ ///
+ /// + /// + /// The game’s client ID. + /// If specified, the response contains an analytics report for just the specified game. + /// If not specified, the response includes multiple URLs (paginated), pointing to separate analytics reports for each of the authenticated user’s games. + /// + /// + /// + /// The starting date for the analytic report time period.
+ /// (This is automtically converted to RFC3339 format)
+ /// If you specify a start date, you must also specify an end date in endedAt. + /// The start date must be within one year of today’s date.
+ /// If you specify an earlier date, the API ignores it and uses a date that’s one year prior to today’s date.
+ /// If you don’t specify a start and end date, the report includes all available data for the last 365 days from today.
+ /// The report contains one row of data for each day in the reporting window. + /// + /// + /// + /// The ending date for the analytic report time period.
+ /// (This is automatically converted to RFC3339 format)
+ /// Only specify an end date if you specified a start date. + /// Because it can take up to two days for the data to be available, you must specify an end date that’s earlier than today minus one to two days. + /// If not, the API ignores your end date and uses an end date that is today minus one to two days. + /// + /// + /// + /// The maximum number of report URLs to return per page in the response. + /// Minimum page size: 1 URL per page
+ /// Maximum page size: 100 URLs per page.
+ /// Default page size: 20 URLs per page.
+ /// While you may specify a maximum value of 100, the response will contain at most 20 URLs per page. + /// + /// + /// + /// Cursor for forward pagination: tells the server where to start fetching the next set of results, in a multi-page response. + /// This parameter is ignored if the game_id parameter is set. + /// + /// + /// + /// Type of analytics report that is returned. + /// Currently, this field has no affect on the response as there is only one report type. + /// If additional types were added, using this field would return only the URL for the specified report. + /// Valid values: "overview_v2". + /// + /// + /// + /// Optional access token to override the use of the stored one in the TwitchAPI instance. + /// + /// + public Task GetGameAnalyticsAsync(string gameId = null, DateTime? startedAt = null, DateTime? endedAt = null, int first = 20, string after = null, string type = null, string accessToken = null) + { + var getParams = new List> + { + new KeyValuePair("first", first.ToString()) + }; + + if (!string.IsNullOrWhiteSpace(gameId)) + getParams.Add(new KeyValuePair("game_id", gameId)); + + if (startedAt != null && endedAt != null) + { + getParams.Add(new KeyValuePair("started_at", startedAt.Value.ToRfc3339String())); + getParams.Add(new KeyValuePair("ended_at", endedAt.Value.ToRfc3339String())); + } + + if (!string.IsNullOrWhiteSpace(type)) + getParams.Add(new KeyValuePair("type", type)); + + if (!string.IsNullOrWhiteSpace(after)) + getParams.Add(new KeyValuePair("after", after)); + + return TwitchGetGenericAsync("/analytics/games", ApiVersion.Helix, getParams, accessToken); + } + + #endregion + + #region GetExtensionAnalytics + + /// + /// + /// Twitch Docs: Get Extension Analytics + /// Gets a URL that Extension developers can use to download analytics reports (CSV files) for their Extensions. The URL is valid for 5 minutes. + /// !! The user access token used to call this API must be from a member of the organzation the extension is registered to or the Extension Developer !! + /// Requires a user access token that includes the analytics:read:extensions scope. + /// + /// + /// + /// Client ID value assigned to the extension when it is created. + /// If this is specified, the returned URL points to an analytics report for just the specified extension. + /// If this is not specified, the response includes multiple URLs (paginated), pointing to separate analytics reports for each of the authenticated user’s Extensions. + /// + /// + /// + /// The starting date for the analytic report time period.
+ /// (This is automtically converted to RFC3339 format)
+ /// If you specify a start date, you must also specify an end date in endedAt. + /// The start date must be on or after January 31, 2018.
+ /// If you specify an earlier date, the API ignores it and uses January 31, 2018.
+ /// If you specify a start date, you must specify an end date.
+ /// If you don’t specify a start and end date, the report includes all available data since January 31, 2018.
+ /// The report contains one row of data for each day in the reporting window. + /// + /// + /// + /// The ending date for the analytic report time period.
+ /// (This is automatically converted to RFC3339 format)
+ /// Only specify an end date if you specified a start date. + /// Because it can take up to two days for the data to be available, you must specify an end date that’s earlier than today minus one to two days. + /// If not, the API ignores your end date and uses an end date that is today minus one to two days. + /// + /// + /// + /// The maximum number of report URLs to return per page in the response. + /// Minimum page size: 1 URL per page
+ /// Maximum page size: 100 URLs per page.
+ /// Default page size: 20 URLs per page.
+ /// Note: While you may specify a maximum value of 100, the response will contain at most 20 URLs per page. + /// + /// + /// + /// Cursor for forward pagination: tells the server where to start fetching the next set of results, in a multi-page response. + /// This parameter is ignored if the extension_id parameter is set. + /// + /// + /// + /// Type of analytics report that is returned. + /// Currently, this field has no affect on the response as there is only one report type. + /// If additional types were added, using this field would return only the URL for the specified report. + /// Valid values: "overview_v2". + /// + /// + /// + /// Optional access token to override the use of the stored one in the TwitchAPI instance. + /// + /// + public Task GetExtensionAnalyticsAsync(string extensionId, DateTime? startedAt = null, DateTime? endedAt = null, int first = 20, string after = null, string type = null, string accessToken = null) + { + var getParams = new List> + { + new KeyValuePair("first", first.ToString()) + }; + + if (!string.IsNullOrWhiteSpace(extensionId)) + getParams.Add(new KeyValuePair("extension_id", extensionId)); + + if (startedAt != null && endedAt != null) + { + getParams.Add(new KeyValuePair("started_at", startedAt.Value.ToRfc3339String())); + getParams.Add(new KeyValuePair("ended_at", endedAt.Value.ToRfc3339String())); + } + + if (!string.IsNullOrWhiteSpace(type)) + getParams.Add(new KeyValuePair("type", type)); + + if (!string.IsNullOrWhiteSpace(after)) + getParams.Add(new KeyValuePair("after", after)); + + return TwitchGetGenericAsync("/analytics/extensions", ApiVersion.Helix, getParams, accessToken); + } + + #endregion + + } } \ No newline at end of file From ddeeb6aa45a10bfb3ae436b85288c30195dfc3d9 Mon Sep 17 00:00:00 2001 From: koishibuh Date: Fri, 21 Jul 2023 21:19:21 +0100 Subject: [PATCH 36/55] - Added missing Pagination property in GetExtensionAnalyticsResponse --- .../Analytics/GetExtensionAnalyticsResponse.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/TwitchLib.Api.Helix.Models/Analytics/GetExtensionAnalyticsResponse.cs b/TwitchLib.Api.Helix.Models/Analytics/GetExtensionAnalyticsResponse.cs index 7ee47c44..0c4d524b 100644 --- a/TwitchLib.Api.Helix.Models/Analytics/GetExtensionAnalyticsResponse.cs +++ b/TwitchLib.Api.Helix.Models/Analytics/GetExtensionAnalyticsResponse.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using TwitchLib.Api.Helix.Models.Common; namespace TwitchLib.Api.Helix.Models.Analytics { @@ -16,5 +17,13 @@ public class GetExtensionAnalyticsResponse ///
[JsonProperty(PropertyName = "data")] public ExtensionAnalytics[] Data { get; protected set; } + + /// + /// Contains the information used to page through the list of results. + /// The object is empty if there are no more pages left to page through. + /// Use the cursor to set the GetExtensionAnalytics request’s after query parameter. + /// + [JsonProperty(PropertyName = "pagination")] + public Pagination Pagination { get; protected set; } } } From 7bc2c9d8863cebf3e39705adf83a1185c10389d3 Mon Sep 17 00:00:00 2001 From: cole Date: Sat, 28 Oct 2023 11:19:20 -0700 Subject: [PATCH 37/55] SnoozeNextAd, GetAdSchedule, ad related scopes (#372) * SnoozeNextAd, GetAdSchedule, ad related scopes --- TwitchLib.Api.Core.Enums/AuthScopesEnum.cs | 32 +++++++++++-- TwitchLib.Api.Core/Common/Helpers.cs | 10 ++++ .../Channels/GetAdSchedule/AdSchedule.cs | 44 +++++++++++++++++ .../GetAdSchedule/GetAdScheduleResponse.cs | 19 ++++++++ .../Channels/SnoozeNextAd/SnoozeNextAd.cs | 29 ++++++++++++ .../SnoozeNextAd/SnoozeNextAdResponse.cs | 19 ++++++++ TwitchLib.Api.Helix/Channels.cs | 47 +++++++++++++++++++ 7 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs create mode 100644 TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/GetAdScheduleResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/Channels/SnoozeNextAd/SnoozeNextAd.cs create mode 100644 TwitchLib.Api.Helix.Models/Channels/SnoozeNextAd/SnoozeNextAdResponse.cs diff --git a/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs b/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs index 6b9bebd8..6929b140 100644 --- a/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs +++ b/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs @@ -48,12 +48,22 @@ public enum AuthScopes /// View Bits information for a channel. ///
Bits_Read, + + /// + /// Allows the client’s bot users access to a channel. + /// + Channel_Bot, /// /// Run commercials on a channel. /// Channel_Edit_Commercial, - + + /// + /// Manage ads schedule on a channel. + /// + Channel_Manage_Ads, + /// /// Manage a channel’s broadcast configuration, including updating channel configuration and managing stream markers and stream tags. /// @@ -108,7 +118,12 @@ public enum AuthScopes /// Add or remove the VIP role from users in your channel. ///
Channel_Manage_VIPs, - + + /// + /// Read the ads schedule and details on your channel. + /// + Channel_Read_Ads, + /// /// Read charity campaign details and user donations on your channel. /// @@ -263,7 +278,13 @@ public enum AuthScopes /// View a broadcaster’s shoutouts. /// Moderator_Read_Shoutouts, - + + + /// + /// Allows client’s bot to act as this user. + /// + User_Bot, + /// /// Manage a user object. /// @@ -299,6 +320,11 @@ public enum AuthScopes /// View a user’s broadcasting configuration, including Extension configurations. /// User_Read_Broadcast, + + /// + /// View live stream chat and room messages. + /// + User_Read_Chat, /// /// View a user’s email address. diff --git a/TwitchLib.Api.Core/Common/Helpers.cs b/TwitchLib.Api.Core/Common/Helpers.cs index 7d6f62fc..37fc827c 100644 --- a/TwitchLib.Api.Core/Common/Helpers.cs +++ b/TwitchLib.Api.Core/Common/Helpers.cs @@ -34,6 +34,8 @@ public static string AuthScopesToString(AuthScopes scope) AuthScopes.Analytics_Read_Extensions => "analytics:read:extensions", AuthScopes.Analytics_Read_Games => "analytics:read:games", AuthScopes.Bits_Read => "bits:read", + AuthScopes.Channel_Bot => "channel:bot", + AuthScopes.Channel_Manage_Ads => "channel:manage:ads", AuthScopes.Channel_Edit_Commercial => "channel:edit:commercial", AuthScopes.Channel_Manage_Broadcast => "channel:manage:broadcast", AuthScopes.Channel_Manage_Extensions => "channel:manage:extensions", @@ -46,6 +48,7 @@ public static string AuthScopesToString(AuthScopes scope) AuthScopes.Channel_Manage_VIPs => "channel:manage:vips", AuthScopes.Channel_Manage_Guest_Star => "channel:manage:guest_star", AuthScopes.Channel_Manage_Raids => "channel:manage:raids", + AuthScopes.Channel_Read_Ads => "channel:read:ads", AuthScopes.Channel_Read_Charity => "channel:read:charity", AuthScopes.Channel_Read_Editors => "channel:read:editors", AuthScopes.Channel_Read_Goals => "channel:read:goals", @@ -59,10 +62,12 @@ public static string AuthScopesToString(AuthScopes scope) AuthScopes.Channel_Read_Guest_Star => "channel:read:guest_star", AuthScopes.Clips_Edit => "clips:edit", AuthScopes.Moderation_Read => "moderation:read", + AuthScopes.User_Bot => "user:bot", AuthScopes.User_Edit => "user:edit", AuthScopes.User_Edit_Follows => "user:edit:follows", AuthScopes.User_Read_BlockedUsers => "user:read:blocked_users", AuthScopes.User_Read_Broadcast => "user:read:broadcast", + AuthScopes.User_Read_Chat => "user:read:chat", AuthScopes.User_Read_Email => "user:read:email", AuthScopes.User_Read_Follows => "user:read:follows", AuthScopes.User_Read_Subscriptions => "user:read:subscriptions", @@ -110,7 +115,9 @@ public static AuthScopes StringToScope(string scope) "analytics:read:extensions" => AuthScopes.Analytics_Read_Extensions, "analytics:read:games" => AuthScopes.Analytics_Read_Games, "bits:read" => AuthScopes.Bits_Read, + "channel:bot" => AuthScopes.Channel_Bot, "channel:edit:commercial" => AuthScopes.Channel_Edit_Commercial, + "channel:manage:ads" => AuthScopes.Channel_Manage_Ads, "channel:manage:broadcast" => AuthScopes.Channel_Manage_Broadcast, "channel:manage:extensions" => AuthScopes.Channel_Manage_Extensions, "channel:manage:moderators" => AuthScopes.Channel_Manage_Moderators, @@ -122,6 +129,7 @@ public static AuthScopes StringToScope(string scope) "channel:manage:vips" => AuthScopes.Channel_Manage_VIPs, "channel:manage:guest_star" => AuthScopes.Channel_Manage_Guest_Star, "channel:manage:raids" => AuthScopes.Channel_Manage_Raids, + "channel:read:ads" => AuthScopes.Channel_Read_Ads, "channel:read:charity" => AuthScopes.Channel_Read_Charity, "channel:read:editors" => AuthScopes.Channel_Read_Editors, "channel:read:goals" => AuthScopes.Channel_Read_Goals, @@ -135,10 +143,12 @@ public static AuthScopes StringToScope(string scope) "channel:read:guest_star" => AuthScopes.Channel_Read_Guest_Star, "clips:edit" => AuthScopes.Clips_Edit, "moderation:read" => AuthScopes.Moderation_Read, + "user:bot" => AuthScopes.User_Bot, "user:edit" => AuthScopes.User_Edit, "user:edit:follows" => AuthScopes.User_Edit_Follows, "user:read:blocked_users" => AuthScopes.User_Read_BlockedUsers, "user:read:broadcast" => AuthScopes.User_Read_Broadcast, + "user:read:chat" => AuthScopes.User_Read_Chat, "user:read:email" => AuthScopes.User_Read_Email, "user:read:follows" => AuthScopes.User_Read_Follows, "user:read:subscriptions" => AuthScopes.User_Read_Subscriptions, diff --git a/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs b/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs new file mode 100644 index 00000000..2808f19a --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs @@ -0,0 +1,44 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace TwitchLib.Api.Helix.Models.Channels.GetAdSchedule +{ + /// + /// Contains information related to the channel’s ad schedule. + /// + public class AdSchedule + { + /// + /// The number of snoozes available for the broadcaster. + /// + [JsonProperty(PropertyName = "snooze_count")] + public int SnoozeCount { get; protected set; } + /// + /// The UTC timestamp when the broadcaster will gain an additional snooze, in RFC3339 format. + /// + [JsonProperty(PropertyName = "snooze_refresh_at")] + public string SnoozeRefreshAt { get; protected set; } + /// + /// The UTC timestamp of the broadcaster’s next scheduled ad, in RFC3339 format. Empty if the channel has no ad scheduled or is not live. + /// + [JsonProperty(PropertyName = "next_ad_at")] + public string NextAdAt { get; protected set; } + /// + /// The length in seconds of the scheduled upcoming ad break. + /// + [JsonProperty(PropertyName = "lengths_seconds")] + public int LengthsSeconds { get;protected set; } + /// + /// The UTC timestamp of the broadcaster’s last ad-break, in RFC3339 format. Empty if the channel has not run an ad or is not live. + /// + [JsonProperty(PropertyName = "last_ad_at")] + public string LastAdAt { get; protected set; } + /// + /// The amount of pre-roll free time remaining for the channel in seconds. Returns 0 if they are currently not pre-roll free. + /// + [JsonProperty(PropertyName = "preroll_free_time_seconds")] + public int PrerollFreeTimeSeconds { get; protected set; } + } +} diff --git a/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/GetAdScheduleResponse.cs b/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/GetAdScheduleResponse.cs new file mode 100644 index 00000000..37f13e75 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/GetAdScheduleResponse.cs @@ -0,0 +1,19 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace TwitchLib.Api.Helix.Models.Channels.GetAdSchedule +{ + /// + /// Response to getting ad schedule + /// + public class GetAdScheduleResponse + { + /// + /// A list that contains information related to the channel’s ad schedule. + /// + [JsonProperty(PropertyName = "data")] + public AdSchedule[] Data { get; protected set; } + } +} diff --git a/TwitchLib.Api.Helix.Models/Channels/SnoozeNextAd/SnoozeNextAd.cs b/TwitchLib.Api.Helix.Models/Channels/SnoozeNextAd/SnoozeNextAd.cs new file mode 100644 index 00000000..071c7592 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Channels/SnoozeNextAd/SnoozeNextAd.cs @@ -0,0 +1,29 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace TwitchLib.Api.Helix.Models.Channels.SnoozeNextAd +{ + /// + /// Contains information about the channel’s snoozes and next upcoming ad after successfully snoozing. + /// + public class SnoozeNextAd + { + /// + /// The number of snoozes available for the broadcaster. + /// + [JsonProperty(PropertyName = "snooze_count")] + public int SnoozeCount { get; protected set; } + /// + /// The UTC timestamp when the broadcaster will gain an additional snooze, in RFC3339 format. + /// + [JsonProperty(PropertyName = "snooze_refresh_at")] + public string SnoozeRefreshAt { get; protected set; } + /// + /// The UTC timestamp of the broadcaster’s next scheduled ad, in RFC3339 format. + /// + [JsonProperty(PropertyName = "next_ad_at")] + public string NextAdAt { get; protected set; } + } +} diff --git a/TwitchLib.Api.Helix.Models/Channels/SnoozeNextAd/SnoozeNextAdResponse.cs b/TwitchLib.Api.Helix.Models/Channels/SnoozeNextAd/SnoozeNextAdResponse.cs new file mode 100644 index 00000000..401f673e --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Channels/SnoozeNextAd/SnoozeNextAdResponse.cs @@ -0,0 +1,19 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace TwitchLib.Api.Helix.Models.Channels.SnoozeNextAd +{ + /// + /// Response to attempting to snooze an ad. + /// + public class SnoozeNextAdResponse + { + /// + /// A list that contains information about the channel’s snoozes and next upcoming ad after successfully snoozing. + /// + [JsonProperty(PropertyName = "data")] + public SnoozeNextAd[] Data { get; protected set; } + } +} diff --git a/TwitchLib.Api.Helix/Channels.cs b/TwitchLib.Api.Helix/Channels.cs index 926b4818..971b5fd8 100644 --- a/TwitchLib.Api.Helix/Channels.cs +++ b/TwitchLib.Api.Helix/Channels.cs @@ -6,12 +6,14 @@ using TwitchLib.Api.Core.Enums; using TwitchLib.Api.Core.Exceptions; using TwitchLib.Api.Core.Interfaces; +using TwitchLib.Api.Helix.Models.Channels.GetAdSchedule; using TwitchLib.Api.Helix.Models.Channels.GetChannelEditors; using TwitchLib.Api.Helix.Models.Channels.GetChannelFollowers; using TwitchLib.Api.Helix.Models.Channels.GetChannelInformation; using TwitchLib.Api.Helix.Models.Channels.GetChannelVIPs; using TwitchLib.Api.Helix.Models.Channels.GetFollowedChannels; using TwitchLib.Api.Helix.Models.Channels.ModifyChannelInformation; +using TwitchLib.Api.Helix.Models.Channels.SnoozeNextAd; namespace TwitchLib.Api.Helix { @@ -280,5 +282,50 @@ public Task GetChannelFollowersAsync(string broadca } #endregion + + #region GetAdSchedule + + /// + /// Returns ad schedule related information, including snooze, when the last ad was run, when the next ad is scheduled, and if the channel is currently in pre-roll free time. + /// + /// The broadcaster's ID. Ad schedule is relevant to this broadcaster, and so should the auth. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + public Task GetAdScheduleAsync(string broadcasterId, string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + var getParams = new List> + { + + new KeyValuePair("broadcaster_id", broadcasterId) + }; + + return TwitchGetGenericAsync("/channels/ads", ApiVersion.Helix, getParams, accessToken); + } + + #endregion + + #region SnoozeNextAd + + /// + /// If available, pushes back the timestamp of the upcoming automatic mid-roll ad by 5 minutes. This endpoint duplicates the snooze functionality in the creator dashboard’s Ads Manager. + /// + /// The broadcaster's ID. Ad snoozing is relevant to this broadcaster, and so should the auth. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + public Task SnoozeNextAd(string broadcasterId, string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + var getParams = new List> + { + new KeyValuePair("broadcaster_id", broadcasterId) + }; + + return TwitchPostGenericAsync("/channels/ads/schedule/snooze", ApiVersion.Helix, null, getParams, accessToken); + } + + #endregion } } From 38d58c9cd438f8beac9317fe42f52a600e855af6 Mon Sep 17 00:00:00 2001 From: Tobias 'Syzuna' Teske Date: Sat, 28 Oct 2023 20:58:32 +0200 Subject: [PATCH 38/55] chore: Updated actions to their latest versions --- .github/workflows/check-buildstatus.yml | 4 ++-- .github/workflows/preview-release.yml | 6 +++--- .github/workflows/release.yml | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/check-buildstatus.yml b/.github/workflows/check-buildstatus.yml index a5c4d329..fca1d46e 100644 --- a/.github/workflows/check-buildstatus.yml +++ b/.github/workflows/check-buildstatus.yml @@ -10,9 +10,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup .NET - uses: actions/setup-dotnet@v2 + uses: actions/setup-dotnet@v3 with: dotnet-version: 6.0.x - name: Restore dependencies diff --git a/.github/workflows/preview-release.yml b/.github/workflows/preview-release.yml index a9ac5873..72584dff 100644 --- a/.github/workflows/preview-release.yml +++ b/.github/workflows/preview-release.yml @@ -10,11 +10,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: benjlevesque/short-sha@v2.1 + - uses: actions/checkout@v4 + - uses: benjlevesque/short-sha@v2.2 id: short-sha - name: Setup .NET - uses: actions/setup-dotnet@v2 + uses: actions/setup-dotnet@v3 with: dotnet-version: 6.0.x - name: Restore dependencies diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b779a6ac..4e82d0d1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,9 +10,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup .NET - uses: actions/setup-dotnet@v2 + uses: actions/setup-dotnet@v3 with: dotnet-version: 6.0.x - name: Restore dependencies From 8d79331ab66f0b11b5e42d699a83bb7de80d80df Mon Sep 17 00:00:00 2001 From: Tobias 'Syzuna' Teske Date: Mon, 30 Oct 2023 23:07:31 +0100 Subject: [PATCH 39/55] chore: updated dependencies (Moq was left out on purpose) --- TwitchLib.Api.Core/TwitchLib.Api.Core.csproj | 2 +- TwitchLib.Api.Test/TwitchLib.Api.Test.csproj | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj b/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj index 47f9158e..bb4b7959 100644 --- a/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj +++ b/TwitchLib.Api.Core/TwitchLib.Api.Core.csproj @@ -25,7 +25,7 @@ - + diff --git a/TwitchLib.Api.Test/TwitchLib.Api.Test.csproj b/TwitchLib.Api.Test/TwitchLib.Api.Test.csproj index 260e57e7..acac44fe 100644 --- a/TwitchLib.Api.Test/TwitchLib.Api.Test.csproj +++ b/TwitchLib.Api.Test/TwitchLib.Api.Test.csproj @@ -19,11 +19,11 @@ - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive From 23542e25e89ae11e7b3e6fb92c5eaaa62ebedfcb Mon Sep 17 00:00:00 2001 From: Syzuna Date: Mon, 30 Oct 2023 23:33:49 +0100 Subject: [PATCH 40/55] Adjust GetAdSchedule model after Twitch fix (#374) --- .../Channels/GetAdSchedule/AdSchedule.cs | 7 ++----- .../Channels/GetAdSchedule/GetAdScheduleResponse.cs | 3 --- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs b/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs index 2808f19a..2cfd9b96 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs @@ -1,7 +1,4 @@ using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Text; namespace TwitchLib.Api.Helix.Models.Channels.GetAdSchedule { @@ -28,8 +25,8 @@ public class AdSchedule /// /// The length in seconds of the scheduled upcoming ad break. /// - [JsonProperty(PropertyName = "lengths_seconds")] - public int LengthsSeconds { get;protected set; } + [JsonProperty(PropertyName = "length_seconds")] + public int LengthSeconds { get;protected set; } /// /// The UTC timestamp of the broadcaster’s last ad-break, in RFC3339 format. Empty if the channel has not run an ad or is not live. /// diff --git a/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/GetAdScheduleResponse.cs b/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/GetAdScheduleResponse.cs index 37f13e75..36537c45 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/GetAdScheduleResponse.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/GetAdScheduleResponse.cs @@ -1,7 +1,4 @@ using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Text; namespace TwitchLib.Api.Helix.Models.Channels.GetAdSchedule { From 13db111e19f718a1cebe154123775cb9980a2bbf Mon Sep 17 00:00:00 2001 From: Syzuna Date: Mon, 30 Oct 2023 23:34:28 +0100 Subject: [PATCH 41/55] Added is_featured to response model and as optional query param for GetClips (#375) --- TwitchLib.Api.Helix.Models/Clips/GetClips/Clip.cs | 6 ++++++ TwitchLib.Api.Helix/Clips.cs | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/TwitchLib.Api.Helix.Models/Clips/GetClips/Clip.cs b/TwitchLib.Api.Helix.Models/Clips/GetClips/Clip.cs index 3fbc9569..c793f412 100644 --- a/TwitchLib.Api.Helix.Models/Clips/GetClips/Clip.cs +++ b/TwitchLib.Api.Helix.Models/Clips/GetClips/Clip.cs @@ -106,5 +106,11 @@ public class Clip /// [JsonProperty(PropertyName = "vod_offset")] public int VodOffset { get; protected set; } + + /// + /// A Boolean value that indicates if the clip is featured or not. + /// + [JsonProperty(PropertyName = "is_featured")] + public bool IsFeatured { get; protected set; } } } diff --git a/TwitchLib.Api.Helix/Clips.cs b/TwitchLib.Api.Helix/Clips.cs index 8c45a543..ed38a881 100644 --- a/TwitchLib.Api.Helix/Clips.cs +++ b/TwitchLib.Api.Helix/Clips.cs @@ -52,11 +52,15 @@ public Clips(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandler h /// Ending date/time for returned clips, in RFC3339 format. (Note that the seconds value is ignored.) /// If this is specified, started_at also must be specified; otherwise, the time period is ignored. /// + /// + /// A Boolean value that determines whether the response includes featured clips. + /// If true, returns only clips that are featured. If false, returns only clips that aren’t featured. All clips are returned if this parameter is not present. + /// /// Maximum number of objects to return. Maximum: 100. Default: 20. /// optional access token to override the use of the stored one in the TwitchAPI instance /// /// - public Task GetClipsAsync(List clipIds = null, string gameId = null, string broadcasterId = null, string before = null, string after = null, DateTime? startedAt = null, DateTime? endedAt = null, int first = 20, string accessToken = null) + public Task GetClipsAsync(List clipIds = null, string gameId = null, string broadcasterId = null, string before = null, string after = null, DateTime? startedAt = null, DateTime? endedAt = null, bool? isFeatured = null, int first = 20, string accessToken = null) { if (first < 0 || first > 100) throw new BadParameterException("'first' must between 0 (inclusive) and 100 (inclusive)."); @@ -91,6 +95,9 @@ public Task GetClipsAsync(List clipIds = null, string if (!string.IsNullOrWhiteSpace(after)) getParams.Add(new KeyValuePair("after", after)); + + if (isFeatured.HasValue) + getParams.Add(new KeyValuePair("is_featured", isFeatured.Value.ToString())); getParams.Add(new KeyValuePair("first", first.ToString())); From 3b6bfd31d1f941dcfde253d07a221c0d8a603e08 Mon Sep 17 00:00:00 2001 From: Syzuna Date: Mon, 30 Oct 2023 23:35:23 +0100 Subject: [PATCH 42/55] Remove decommissioned Soundtrack APIs (#376) --- .../Soundtrack/Album.cs | 28 ------ .../Soundtrack/Artist.cs | 28 ------ .../GetCurrentTrack/CurrentTrack.cs | 22 ----- .../GetCurrentTrackResponse.cs | 16 --- .../GetPlaylist/GetPlaylistResponse.cs | 23 ----- .../GetPlaylists/GetPlaylistsResponse.cs | 23 ----- .../GetPlaylists/PlaylistMetadata.cs | 34 ------- .../Soundtrack/Source.cs | 46 --------- .../Soundtrack/Track.cs | 46 --------- TwitchLib.Api.Helix/Helix.cs | 5 - TwitchLib.Api.Helix/Soundtrack.cs | 97 ------------------- 11 files changed, 368 deletions(-) delete mode 100644 TwitchLib.Api.Helix.Models/Soundtrack/Album.cs delete mode 100644 TwitchLib.Api.Helix.Models/Soundtrack/Artist.cs delete mode 100644 TwitchLib.Api.Helix.Models/Soundtrack/GetCurrentTrack/CurrentTrack.cs delete mode 100644 TwitchLib.Api.Helix.Models/Soundtrack/GetCurrentTrack/GetCurrentTrackResponse.cs delete mode 100644 TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylist/GetPlaylistResponse.cs delete mode 100644 TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylists/GetPlaylistsResponse.cs delete mode 100644 TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylists/PlaylistMetadata.cs delete mode 100644 TwitchLib.Api.Helix.Models/Soundtrack/Source.cs delete mode 100644 TwitchLib.Api.Helix.Models/Soundtrack/Track.cs delete mode 100644 TwitchLib.Api.Helix/Soundtrack.cs diff --git a/TwitchLib.Api.Helix.Models/Soundtrack/Album.cs b/TwitchLib.Api.Helix.Models/Soundtrack/Album.cs deleted file mode 100644 index 08f753da..00000000 --- a/TwitchLib.Api.Helix.Models/Soundtrack/Album.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Newtonsoft.Json; - -namespace TwitchLib.Api.Helix.Models.Soundtrack -{ - /// - /// The album that includes the track. - /// - public class Album - { - /// - /// The album’s ASIN (Amazon Standard Identification Number). - /// - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - - /// - /// The album’s name. If the album contains explicit content, the name will contain [Explicit] in the string. For example, Let It Die [Explicit]. - /// - [JsonProperty(PropertyName = "name")] - public string Name { get; protected set; } - - /// - /// A URL to the album’s cover art. - /// - [JsonProperty(PropertyName = "image_url")] - public string ImageUrl { get; protected set; } - } -} diff --git a/TwitchLib.Api.Helix.Models/Soundtrack/Artist.cs b/TwitchLib.Api.Helix.Models/Soundtrack/Artist.cs deleted file mode 100644 index 1c9e6719..00000000 --- a/TwitchLib.Api.Helix.Models/Soundtrack/Artist.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Newtonsoft.Json; - -namespace TwitchLib.Api.Helix.Models.Soundtrack -{ - /// - /// The artists included on the track. - /// - public class Artist - { - /// - /// The artist’s ASIN (Amazon Standard Identification Number). - /// - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - - /// - /// The artist’s name. This can be the band’s name or the solo artist’s name. - /// - [JsonProperty(PropertyName = "name")] - public string Name { get; protected set; } - - /// - /// The ID of the Twitch user that created the track. Is empty if a Twitch user didn’t create the track. - /// - [JsonProperty(PropertyName = "creator_channel_id")] - public string CreatorChannelId { get; protected set; } - } -} diff --git a/TwitchLib.Api.Helix.Models/Soundtrack/GetCurrentTrack/CurrentTrack.cs b/TwitchLib.Api.Helix.Models/Soundtrack/GetCurrentTrack/CurrentTrack.cs deleted file mode 100644 index 0781733d..00000000 --- a/TwitchLib.Api.Helix.Models/Soundtrack/GetCurrentTrack/CurrentTrack.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Newtonsoft.Json; - -namespace TwitchLib.Api.Helix.Models.Soundtrack.GetCurrentTrack -{ - /// - /// Soundtrack track that the broadcaster is playing. - /// - public class CurrentTrack - { - /// - /// The track that’s currently playing. - /// - [JsonProperty(PropertyName = "track")] - public Track Track { get; protected set; } - - /// - /// The source of the track that’s currently playing. For example, a playlist or station. - /// - [JsonProperty(PropertyName = "source")] - public Source Source { get; protected set; } - } -} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/Soundtrack/GetCurrentTrack/GetCurrentTrackResponse.cs b/TwitchLib.Api.Helix.Models/Soundtrack/GetCurrentTrack/GetCurrentTrackResponse.cs deleted file mode 100644 index 6e89c5c6..00000000 --- a/TwitchLib.Api.Helix.Models/Soundtrack/GetCurrentTrack/GetCurrentTrackResponse.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Newtonsoft.Json; - -namespace TwitchLib.Api.Helix.Models.Soundtrack.GetCurrentTrack -{ - /// - /// Returns the Soundtrack track that the broadcaster is playing. - /// - public class GetCurrentTrackResponse - { - /// - /// A list that contains the Soundtrack track that the broadcaster is playing. - /// - [JsonProperty(PropertyName = "data")] - public CurrentTrack[] Data { get; protected set; } - } -} diff --git a/TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylist/GetPlaylistResponse.cs b/TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylist/GetPlaylistResponse.cs deleted file mode 100644 index d2897a23..00000000 --- a/TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylist/GetPlaylistResponse.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Newtonsoft.Json; -using TwitchLib.Api.Helix.Models.Common; - -namespace TwitchLib.Api.Helix.Models.Soundtrack.GetPlaylist -{ - /// - /// Returned tracks of a Soundtrack playlist. - /// - public class GetPlaylistResponse - { - /// - /// The list of tracks in the playlist. - /// - [JsonProperty(PropertyName = "data")] - public Track[] Data { get; protected set; } - - /// - /// Contains the information used to page through a list of tracks. The object is empty if there are no more tracks to page through. - /// - [JsonProperty(PropertyName = "pagination")] - public Pagination Pagination { get; protected set; } - } -} diff --git a/TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylists/GetPlaylistsResponse.cs b/TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylists/GetPlaylistsResponse.cs deleted file mode 100644 index 343bf4c3..00000000 --- a/TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylists/GetPlaylistsResponse.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Newtonsoft.Json; -using TwitchLib.Api.Helix.Models.Common; - -namespace TwitchLib.Api.Helix.Models.Soundtrack.GetPlaylists -{ - /// - /// Returns a list of Soundtrack playlists. - /// - public class GetPlaylistsResponse - { - /// - /// The list of Soundtrack playlists. - /// - [JsonProperty(PropertyName = "data")] - public PlaylistMetadata[] Data { get; protected set; } - - /// - /// Contains the information used to page through a list of playlists. The object is empty if there are no more playlists to page through. - /// - [JsonProperty(PropertyName = "pagination")] - public Pagination Pagination { get; protected set; } - } -} diff --git a/TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylists/PlaylistMetadata.cs b/TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylists/PlaylistMetadata.cs deleted file mode 100644 index d1cab4f3..00000000 --- a/TwitchLib.Api.Helix.Models/Soundtrack/GetPlaylists/PlaylistMetadata.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Newtonsoft.Json; - -namespace TwitchLib.Api.Helix.Models.Soundtrack.GetPlaylists -{ - /// - /// Soundtrack playlist. - /// - public class PlaylistMetadata - { - /// - /// The playlist’s title. - /// - [JsonProperty(PropertyName = "title")] - public string Title { get; protected set; } - - /// - /// The playlist’s ASIN (Amazon Standard Identification Number). - /// - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - - /// - /// A URL to the playlist’s image art. Is empty if the playlist doesn’t include art. - /// - [JsonProperty(PropertyName = "image_url")] - public string ImageUrl { get; protected set; } - - /// - /// A short description about the music that the playlist includes. - /// - [JsonProperty(PropertyName = "description")] - public string Description { get; protected set; } - } -} diff --git a/TwitchLib.Api.Helix.Models/Soundtrack/Source.cs b/TwitchLib.Api.Helix.Models/Soundtrack/Source.cs deleted file mode 100644 index e8c6ebd9..00000000 --- a/TwitchLib.Api.Helix.Models/Soundtrack/Source.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Newtonsoft.Json; - -namespace TwitchLib.Api.Helix.Models.Soundtrack -{ - /// - /// The source of the track that’s currently playing. For example, a playlist or station. - /// - public class Source - { - /// - /// The playlist’s or station’s ASIN (Amazon Standard Identification Number). - /// - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - - /// - /// The type of content that id maps to. Possible values are: PLAYLIST or STATION - /// - [JsonProperty(PropertyName = "content_type")] - public string ContentType { get; protected set; } - - /// - /// The playlist’s or station’s title. - /// - [JsonProperty(PropertyName = "title")] - public string Title { get; protected set; } - - /// - /// A URL to the playlist’s or station’s image art. - /// - [JsonProperty(PropertyName = "image_url")] - public string ImageUrl { get; protected set; } - - /// - /// A URL to the playlist on Soundtrack. The string is empty if content-type is STATION. - /// - [JsonProperty(PropertyName = "soundtrack_url")] - public string SoundtrackUrl { get; protected set; } - - /// - /// A URL to the playlist on Spotify. The string is empty if content-type is STATION. - /// - [JsonProperty(PropertyName = "spotify_url")] - public string SpotifyUrl { get; protected set; } - } -} diff --git a/TwitchLib.Api.Helix.Models/Soundtrack/Track.cs b/TwitchLib.Api.Helix.Models/Soundtrack/Track.cs deleted file mode 100644 index d06f3a70..00000000 --- a/TwitchLib.Api.Helix.Models/Soundtrack/Track.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Newtonsoft.Json; - -namespace TwitchLib.Api.Helix.Models.Soundtrack -{ - /// - /// The track - /// - public class Track - { - /// - /// The artists included on the track. - /// - [JsonProperty(PropertyName = "artists")] - public Artist[] Artists { get; protected set; } - - /// - /// The track’s ASIN (Amazon Standard Identification Number). - /// - [JsonProperty(PropertyName = "id")] - public string Id { get; protected set; } - - /// - /// The duration of the track, in seconds. - /// - [JsonProperty(PropertyName = "duration")] - public int Duration { get; protected set; } - - /// - /// The track’s title. If the track contains explicit content, the title will contain [Explicit] in the string. For example, Let It Die [Explicit]. - /// - [JsonProperty(PropertyName = "title")] - public string Title { get; protected set; } - - /// - /// The album that includes the track. - /// - [JsonProperty(PropertyName = "album")] - public Album Album { get; protected set; } - - /// - /// The track’s ISRC (International Standard Recording Code). - /// - [JsonProperty(PropertyName = "isrc")] - public string ISRC { get; protected set; } - } -} diff --git a/TwitchLib.Api.Helix/Helix.cs b/TwitchLib.Api.Helix/Helix.cs index 6bb2a321..b5c1835b 100644 --- a/TwitchLib.Api.Helix/Helix.cs +++ b/TwitchLib.Api.Helix/Helix.cs @@ -101,10 +101,6 @@ public class Helix /// public Search Search { get; } /// - /// Soundtrack related Helix APIs - /// - public Soundtrack Soundtrack { get; } - /// /// Stream related Helix APIs /// public Streams Streams { get; } @@ -168,7 +164,6 @@ public Helix(ILoggerFactory loggerFactory = null, IRateLimiter rateLimiter = nul Raids = new Raids(settings, rateLimiter, http); Schedule = new Schedule(Settings, rateLimiter, http); Search = new Search(Settings, rateLimiter, http); - Soundtrack = new Soundtrack(Settings, rateLimiter, http); Streams = new Streams(Settings, rateLimiter, http); Subscriptions = new Subscriptions(Settings, rateLimiter, http); Tags = new Tags(Settings, rateLimiter, http); diff --git a/TwitchLib.Api.Helix/Soundtrack.cs b/TwitchLib.Api.Helix/Soundtrack.cs deleted file mode 100644 index 854bc466..00000000 --- a/TwitchLib.Api.Helix/Soundtrack.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using TwitchLib.Api.Core; -using TwitchLib.Api.Core.Enums; -using TwitchLib.Api.Core.Exceptions; -using TwitchLib.Api.Core.Interfaces; -using TwitchLib.Api.Helix.Models.Soundtrack.GetCurrentTrack; -using TwitchLib.Api.Helix.Models.Soundtrack.GetPlaylist; -using TwitchLib.Api.Helix.Models.Soundtrack.GetPlaylists; - -namespace TwitchLib.Api.Helix -{ - /// - /// Soundtrack related APIs - /// - public class Soundtrack : ApiBase - { - public Soundtrack(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandler http) : base(settings, rateLimiter, http) - { - } - - /// - /// Gets the Soundtrack track that the broadcaster is playing. - /// - /// The ID of the broadcaster that’s playing a Soundtrack track. - /// optional access token to override the use of the stored one in the TwitchAPI instance - /// - /// - public Task GetCurrentTrackAsync(string broadcasterId, string accessToken = null) - { - if (string.IsNullOrWhiteSpace(broadcasterId)) - throw new BadParameterException("'broadcasterId' must be set"); - - var getParams = new List> - { - new KeyValuePair("broadcaster_id", broadcasterId) - }; - - return TwitchGetGenericAsync("/soundtrack/current_track", ApiVersion.Helix, getParams, accessToken); - } - - /// - /// Gets the tracks of a Soundtrack playlist. - /// - /// [Required] The ID of the Soundtrack playlist to get. - /// The maximum number of tracks to return for this playlist in the response. Maximum: 50. Default: 20. - /// The cursor used to get the next page of tracks for this playlist. - /// optional access token to override the use of the stored one in the TwitchAPI instance - /// The tracks of a Soundtrack playlist - public Task GetPlaylistAsync(string id, int first = 20, string after = null, string accessToken = null) - { - if (string.IsNullOrWhiteSpace(id)) - throw new BadParameterException("'id' must be set"); - - if (first < 1 || first > 50) - throw new BadParameterException("'first' must be value of 1 - 50"); - - var getParams = new List> - { - new KeyValuePair("id", id), - new KeyValuePair("first", first.ToString()) - }; - - if (!string.IsNullOrWhiteSpace(after)) - getParams.Add(new KeyValuePair("after", after)); - - return TwitchGetGenericAsync("/soundtrack/playlist", ApiVersion.Helix, getParams, accessToken); - } - - /// - /// Gets a list of Soundtrack playlists. - /// - /// The ID of the Soundtrack playlist to get. Specify an ID only if you want to get a single playlist instead of all playlists. - /// The maximum number of playlists to return in the response. Maximum: 50. Default: 20. - /// The cursor used to get the next page of playlists. - /// optional access token to override the use of the stored one in the TwitchAPI instance - /// - public Task GetPlaylistsAsync(string id = null, int first = 20, string after = null, string accessToken = null) - { - if (first < 1 || first > 50) - throw new BadParameterException("'first' must be value of 1 - 50"); - - var getParams = new List> - { - new KeyValuePair("first", first.ToString()) - }; - - if (!string.IsNullOrWhiteSpace(after)) - getParams.Add(new KeyValuePair("after", after)); - - if (!string.IsNullOrWhiteSpace(id)) - getParams.Add(new KeyValuePair("id", id)); - - return TwitchGetGenericAsync("/soundtrack/playlists", ApiVersion.Helix, getParams, accessToken); - } - } -} \ No newline at end of file From 1b109f52b55165c16e102b1d12370c8496ccd818 Mon Sep 17 00:00:00 2001 From: Syzuna Date: Mon, 6 Nov 2023 03:26:36 +0100 Subject: [PATCH 43/55] Add GuestStar APIs (#377) * Add GuestStar Models * Add GuestStar Api Section to Helix * implement Get/Update Channel Guest Star Settings * Implement GuestStar Session APIs * Implement GuestStar Invite APIs * implement Guest Star Slot APIs * fix typo --- .../CreateGuestStarSessionResponse.cs | 12 + .../EndGuestStarSessionResponse.cs | 12 + .../GetChannelGuestStarSettingsResponse.cs | 12 + .../GuestStarSettings.cs | 12 + .../GetGuestStarInvitesResponse.cs | 12 + .../GetGuestStarInvites/GuestStarInvite.cs | 51 ++ .../GetGuestStarSessionResponse.cs | 12 + .../GuestStar/GuestStarGuest.cs | 65 +++ .../GuestStar/GuestStarMediaSettings.cs | 22 + .../GuestStar/GuestStarSession.cs | 18 + .../GuestStar/GuestStarSettingsBase.cs | 29 ++ .../UpdateChannelGuestStarSettingsRequest.cs | 16 + TwitchLib.Api.Helix/GuestStar.cs | 467 ++++++++++++++++++ TwitchLib.Api.Helix/Helix.cs | 5 + 14 files changed, 745 insertions(+) create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/CreateGuestStarSession/CreateGuestStarSessionResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/EndGuestStarSession/EndGuestStarSessionResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/GetChannelGuestStarSettings/GetChannelGuestStarSettingsResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/GetChannelGuestStarSettings/GuestStarSettings.cs create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarInvites/GetGuestStarInvitesResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarInvites/GuestStarInvite.cs create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarSession/GetGuestStarSessionResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/GuestStarGuest.cs create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/GuestStarMediaSettings.cs create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/GuestStarSession.cs create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/GuestStarSettingsBase.cs create mode 100644 TwitchLib.Api.Helix.Models/GuestStar/UpdateChannelGuestStarSettings/UpdateChannelGuestStarSettingsRequest.cs create mode 100644 TwitchLib.Api.Helix/GuestStar.cs diff --git a/TwitchLib.Api.Helix.Models/GuestStar/CreateGuestStarSession/CreateGuestStarSessionResponse.cs b/TwitchLib.Api.Helix.Models/GuestStar/CreateGuestStarSession/CreateGuestStarSessionResponse.cs new file mode 100644 index 00000000..fe47d9c4 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/CreateGuestStarSession/CreateGuestStarSessionResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar.CreateGuestStarSession; + +public class CreateGuestStarSessionResponse +{ + /// + /// Summary of the session details. + /// + [JsonProperty(PropertyName = "data")] + public GuestStarSession[] Data { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/GuestStar/EndGuestStarSession/EndGuestStarSessionResponse.cs b/TwitchLib.Api.Helix.Models/GuestStar/EndGuestStarSession/EndGuestStarSessionResponse.cs new file mode 100644 index 00000000..735d5e17 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/EndGuestStarSession/EndGuestStarSessionResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar.CreateGuestStarSession; + +public class EndGuestStarSessionResponse +{ + /// + /// Summary of the session details when the session was ended. + /// + [JsonProperty(PropertyName = "data")] + public GuestStarSession[] Data { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/GuestStar/GetChannelGuestStarSettings/GetChannelGuestStarSettingsResponse.cs b/TwitchLib.Api.Helix.Models/GuestStar/GetChannelGuestStarSettings/GetChannelGuestStarSettingsResponse.cs new file mode 100644 index 00000000..4a189d35 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/GetChannelGuestStarSettings/GetChannelGuestStarSettingsResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar.GetChannelGuestStarSettings; + +public class GetChannelGuestStarSettingsResponse +{ + /// + /// A list that contains the channels guest star settings + /// + [JsonProperty(PropertyName = "data")] + public GuestStarSettings[] Data { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/GuestStar/GetChannelGuestStarSettings/GuestStarSettings.cs b/TwitchLib.Api.Helix.Models/GuestStar/GetChannelGuestStarSettings/GuestStarSettings.cs new file mode 100644 index 00000000..e9e76b6e --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/GetChannelGuestStarSettings/GuestStarSettings.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar.GetChannelGuestStarSettings; + +public class GuestStarSettings : GuestStarSettingsBase +{ + /// + /// View only token to generate browser source URLs + /// + [JsonProperty(PropertyName = "browser_source_token")] + public string BrowserSourceToken { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarInvites/GetGuestStarInvitesResponse.cs b/TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarInvites/GetGuestStarInvitesResponse.cs new file mode 100644 index 00000000..f608d088 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarInvites/GetGuestStarInvitesResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar.GetGuestStarInvites; + +public class GetGuestStarInvitesResponse +{ + /// + /// A list of invite objects describing the invited user as well as their ready status. + /// + [JsonProperty(PropertyName = "data")] + public GuestStarInvite[] Data { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarInvites/GuestStarInvite.cs b/TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarInvites/GuestStarInvite.cs new file mode 100644 index 00000000..ced7aa91 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarInvites/GuestStarInvite.cs @@ -0,0 +1,51 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar.GetGuestStarInvites; + +public class GuestStarInvite +{ + /// + /// Twitch User ID corresponding to the invited guest + /// + [JsonProperty(PropertyName = "user_id")] + public string UserId { get; protected set; } + + /// + /// Timestamp when this user was invited to the session. + /// + [JsonProperty(PropertyName = "invited_at")] + public string InvitedAt { get; protected set; } + + /// + /// Status representing the invited user’s join state. Can be one of the following: + /// INVITED: The user has been invited to the session but has not acknowledged it. + /// ACCEPTED: The invited user has acknowledged the invite and joined the waiting room, but may still be setting up their media devices or otherwise preparing to join the call. + /// READY: The invited user has signaled they are ready to join the call from the waiting room. + /// + [JsonProperty(PropertyName = "status")] + public string Status { get; protected set; } + + /// + /// Flag signaling that the invited user has chosen to disable their local video device. The user has hidden themselves, but they may choose to reveal their video feed upon joining the session. + /// + [JsonProperty(PropertyName = "is_video_enabled")] + public bool IsVideoEnabled { get; protected set; } + + /// + /// Flag signaling that the invited user has chosen to disable their local audio device. The user has muted themselves, but they may choose to unmute their audio feed upon joining the session. + /// + [JsonProperty(PropertyName = "is_audio_enabled")] + public bool IsAudioEnabled { get; protected set; } + + /// + /// Flag signaling that the invited user has chosen to disable their local video device. The user has hidden themselves, but they may choose to reveal their video feed upon joining the session. + /// + [JsonProperty(PropertyName = "is_video_available")] + public bool IsVideoAvailable { get; protected set; } + + /// + /// Flag signaling that the invited user has chosen to disable their local audio device. The user has muted themselves, but they may choose to unmute their audio feed upon joining the session. + /// + [JsonProperty(PropertyName = "is_audio_available")] + public bool IsAudioAvailable { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarSession/GetGuestStarSessionResponse.cs b/TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarSession/GetGuestStarSessionResponse.cs new file mode 100644 index 00000000..4cfb067b --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/GetGuestStarSession/GetGuestStarSessionResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar.GetGuestStarSession; + +public class GetGuestStarSessionResponse +{ + /// + /// A list that contains the channels guest star sessions + /// + [JsonProperty(PropertyName = "data")] + public GuestStarSession[] Data { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/GuestStar/GuestStarGuest.cs b/TwitchLib.Api.Helix.Models/GuestStar/GuestStarGuest.cs new file mode 100644 index 00000000..f6dfded0 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/GuestStarGuest.cs @@ -0,0 +1,65 @@ +using System; +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar; + +public class GuestStarGuest +{ + /// + /// ID representing this guest’s slot assignment. + /// Host is always in slot "0" + /// Guests are assigned the following consecutive IDs (e.g, "1", "2", "3", etc) + /// Screen Share is represented as a special guest with the ID "SCREENSHARE" + /// The identifier here matches the ID referenced in browser source links used in broadcasting software. + /// + [JsonProperty(PropertyName = "slot_id")] + public string SlotId { get; protected set; } + + /// + /// Flag determining whether or not the guest is visible in the browser source in the host’s streaming software. + /// + [JsonProperty(PropertyName = "is_live")] + public bool IsLive { get; protected set; } + + /// + /// User ID of the guest assigned to this slot. + /// + [JsonProperty(PropertyName = "user_id")] + public string UserId { get; protected set; } + + /// + /// Display name of the guest assigned to this slot. + /// + [JsonProperty(PropertyName = "user_display_name")] + public string UserDisplayName { get; protected set; } + + /// + /// Login of the guest assigned to this slot. + /// + [JsonProperty(PropertyName = "user_login")] + public string UserLogin { get; protected set; } + + /// + /// Value from 0 to 100 representing the host’s volume setting for this guest. + /// + [JsonProperty(PropertyName = "volume")] + public int Volume { get; protected set; } + + /// + /// Timestamp when this guest was assigned a slot in the session. + /// + [JsonProperty(PropertyName = "assigned_at")] + public string AssignedAt { get; protected set; } + + /// + /// Information about the guest’s audio settings + /// + [JsonProperty(PropertyName = "audio_settings")] + public GuestStarMediaSettings AudioSettings { get; protected set; } + + /// + /// Information about the guest’s video settings + /// + [JsonProperty(PropertyName = "video_settings")] + public GuestStarMediaSettings VideoSettings { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/GuestStar/GuestStarMediaSettings.cs b/TwitchLib.Api.Helix.Models/GuestStar/GuestStarMediaSettings.cs new file mode 100644 index 00000000..47a60615 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/GuestStarMediaSettings.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar; + +public class GuestStarMediaSettings +{ + /// + /// Flag determining whether the guest has an appropriate audio/video device available to be transmitted to the session. + /// + [JsonProperty(PropertyName = "is_available")] + public bool IsAvailable { get; protected set; } + /// + /// Flag determining whether the host is allowing the guest’s audio/video to be seen or heard within the session. + /// + [JsonProperty(PropertyName = "is_host_enabled")] + public bool IsHostEnabled { get; protected set; } + /// + /// Flag determining whether the guest is allowing their audio/video to be transmitted to the session. + /// + [JsonProperty(PropertyName = "is_guest_enabled")] + public bool IsGuestEnabled { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/GuestStar/GuestStarSession.cs b/TwitchLib.Api.Helix.Models/GuestStar/GuestStarSession.cs new file mode 100644 index 00000000..c0d42090 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/GuestStarSession.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar; + +public class GuestStarSession +{ + /// + /// ID uniquely representing the Guest Star session. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } + + /// + /// List of guests currently interacting with the Guest Star session. + /// + [JsonProperty(PropertyName = "guests")] + public GuestStarGuest[] Guests { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/GuestStar/GuestStarSettingsBase.cs b/TwitchLib.Api.Helix.Models/GuestStar/GuestStarSettingsBase.cs new file mode 100644 index 00000000..8fc8a897 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/GuestStarSettingsBase.cs @@ -0,0 +1,29 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar; + +public abstract class GuestStarSettingsBase +{ + /// + /// Flag determining if Guest Star moderators have access to control whether a guest is live once assigned to a slot. + /// + [JsonProperty(PropertyName = "is_moderator_send_live_enabled")] + public bool IsModeratorSendLiveEnabled { get; protected set; } + /// + /// Number of slots the Guest Star call interface will allow the host to add to a call. Required to be between 1 and 6. + /// + [JsonProperty(PropertyName = "slot_count")] + public int SlotCount { get; protected set; } + /// + /// Flag determining if Browser Sources subscribed to sessions on this channel should output audio + /// + [JsonProperty(PropertyName = "is_browser_source_audio_enabled")] + public bool IsBrowserSourceAudioEnabled { get; protected set; } + /// + /// This setting determines how the guests within a session should be laid out within the browser source. Can be one of the following values: + /// TILED_LAYOUT: All live guests are tiled within the browser source with the same size. + /// SCREENSHARE_LAYOUT: All live guests are tiled within the browser source with the same size. If there is an active screen share, it is sized larger than the other guests. + /// + [JsonProperty(PropertyName = "group_layout")] + public string GroupLayout { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/GuestStar/UpdateChannelGuestStarSettings/UpdateChannelGuestStarSettingsRequest.cs b/TwitchLib.Api.Helix.Models/GuestStar/UpdateChannelGuestStarSettings/UpdateChannelGuestStarSettingsRequest.cs new file mode 100644 index 00000000..9e9fc61b --- /dev/null +++ b/TwitchLib.Api.Helix.Models/GuestStar/UpdateChannelGuestStarSettings/UpdateChannelGuestStarSettingsRequest.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.GuestStar.UpdateChannelGuestStarSettings; + +/// +/// Request to update guest star settings +/// +public class UpdateChannelGuestStarSettingsRequest : GuestStarSettingsBase +{ + /// + /// Flag determining if Guest Star should regenerate the auth token associated with the channel’s browser sources. + /// Providing a true value for this will immediately invalidate all browser sources previously configured in your streaming software. + /// + [JsonProperty(PropertyName = "regenerate_browser_sources")] + public bool RegenerateBrowserSources { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix/GuestStar.cs b/TwitchLib.Api.Helix/GuestStar.cs new file mode 100644 index 00000000..3bb6b087 --- /dev/null +++ b/TwitchLib.Api.Helix/GuestStar.cs @@ -0,0 +1,467 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Newtonsoft.Json; +using TwitchLib.Api.Core; +using TwitchLib.Api.Core.Enums; +using TwitchLib.Api.Core.Exceptions; +using TwitchLib.Api.Core.Interfaces; +using TwitchLib.Api.Helix.Models.GuestStar.CreateGuestStarSession; +using TwitchLib.Api.Helix.Models.GuestStar.GetChannelGuestStarSettings; +using TwitchLib.Api.Helix.Models.GuestStar.GetGuestStarInvites; +using TwitchLib.Api.Helix.Models.GuestStar.GetGuestStarSession; +using TwitchLib.Api.Helix.Models.GuestStar.UpdateChannelGuestStarSettings; + +namespace TwitchLib.Api.Helix; + +public class GuestStar : ApiBase +{ + public GuestStar(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandler http) : base(settings, + rateLimiter, http) + { + } + + #region GetChannelGuestStarSettings + + /// + /// + /// Twitch Docs: Get Channel Guest Star Settings + /// Gets the channel settings for configuration of the Guest Star feature for a particular host. + /// + /// The ID of the broadcaster you want to get guest star settings for. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + /// + public Task GetChannelGuestStarSettingsAsync(string broadcasterId, + string moderatorId, string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + if (string.IsNullOrWhiteSpace(moderatorId)) + throw new BadParameterException("moderatorId must be set"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId), + new("moderator_id", moderatorId) + }; + + return TwitchGetGenericAsync("/guest_star/channel_settings", + ApiVersion.Helix, getParams, accessToken); + } + + #endregion + + #region UpdateChannelGuestStarSettings + + /// + /// + /// Twitch Docs: Update Channel Guest Star Settings + /// Mutates the channel settings for configuration of the Guest Star feature for a particular host. + /// + /// The ID of the broadcaster you want to update Guest Star settings for. + /// The new settings you want to apply + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + public Task UpdateChannelGuestStarSettingsAsync(string broadcasterId, + UpdateChannelGuestStarSettingsRequest newSettings, string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + + if (newSettings == null) + throw new BadParameterException("newSettings cannot be null"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId) + }; + + var payload = JsonConvert.SerializeObject(newSettings); + + return TwitchPatchAsync("/guest_star/channel_settings", ApiVersion.Helix, payload, getParams, accessToken); + } + + #endregion + + #region GetGuestStarSession + + /// + /// + /// Twitch Docs: Get Guest Star Session + /// Gets information about an ongoing Guest Star session for a particular channel. + /// + /// ID for the user hosting the Guest Star session. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + /// + public Task GetGuestStarSessionAsync(string broadcasterId, string moderatorId, + string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + if (string.IsNullOrWhiteSpace(moderatorId)) + throw new BadParameterException("moderatorId must be set"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId), + new("moderator_id", moderatorId) + }; + + return TwitchGetGenericAsync("/guest_star/session", ApiVersion.Helix, getParams, + accessToken); + } + + #endregion + + #region CreateGuestStarSession + + /// + /// + /// Twitch Docs: Create Guest Star Session + /// Programmatically creates a Guest Star session on behalf of the broadcaster. Requires the broadcaster to be present in the call interface, or the call will be ended automatically. + /// + /// The ID of the broadcaster you want to create a Guest Star session for. Provided broadcaster_id must match the user_id in the auth token. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + /// + public Task CreateGuestStarSession(string broadcasterId, string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId) + }; + + return TwitchPostGenericAsync("/guest_star/session", ApiVersion.Helix, null, + getParams, accessToken); + } + + #endregion + + #region EndGuestStarSession + + /// + /// + /// Twitch Docs: End Guest Star Session + /// A Programmatically ends a Guest Star session on behalf of the broadcaster. Performs the same action as if the host clicked the “End Call” button in the Guest Star UI. + /// + /// The ID of the broadcaster you want to end a Guest Star session for. Provided broadcaster_id must match the user_id in the auth token. + /// ID for the session to end on behalf of the broadcaster. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + /// + public Task EndGuestStarSession(string broadcasterId, string sessionId, + string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + + if (string.IsNullOrWhiteSpace(sessionId)) + throw new BadParameterException("sessionId must be set"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId), + new("sessionId", sessionId) + }; + + return TwitchDeleteGenericAsync("/guest_star/session", ApiVersion.Helix, getParams, + accessToken); + } + + #endregion + + #region GetGuestStarInvites + + /// + /// + /// Twitch Docs: Get Guest Star Invites + /// Provides the caller with a list of pending invites to a Guest Star session, including the invitee’s ready status while joining the waiting room. + /// + /// The ID of the broadcaster running the Guest Star session. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token. + /// The session ID to query for invite status. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + /// + public Task GetGuestStarInvitesAsync(string broadcasterId, string moderatorId, + string sessionId, string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + if (string.IsNullOrWhiteSpace(moderatorId)) + throw new BadParameterException("moderatorId must be set"); + if (string.IsNullOrWhiteSpace(sessionId)) + throw new BadParameterException("sessionId must be set"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId), + new("moderator_id", moderatorId), + new("session_id", sessionId) + }; + + return TwitchGetGenericAsync("/guest_star/invites", ApiVersion.Helix, getParams, + accessToken); + } + + #endregion + + #region SendGuestStarInvite + + /// + /// + /// Twitch Docs: Send Guest Star Invite + /// Sends an invite to a specified guest on behalf of the broadcaster for a Guest Star session in progress. + /// + /// The ID of the broadcaster running the Guest Star session. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token. + /// The session ID for the invite to be sent on behalf of the broadcaster. + /// Twitch User ID for the guest to invite to the Guest Star session. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + public Task SendGuestStarInvitesAsync(string broadcasterId, string moderatorId, string sessionId, string guestId, + string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + if (string.IsNullOrWhiteSpace(moderatorId)) + throw new BadParameterException("moderatorId must be set"); + if (string.IsNullOrWhiteSpace(sessionId)) + throw new BadParameterException("sessionId must be set"); + if (string.IsNullOrWhiteSpace(guestId)) + throw new BadParameterException("guestId must be set"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId), + new("moderator_id", moderatorId), + new("session_id", sessionId), + new("guest_id", guestId) + }; + + return TwitchPostAsync("/guest_star/invites", ApiVersion.Helix, null, getParams, accessToken); + } + + #endregion + + #region DeleteGuestStarInvite + + /// + /// + /// Twitch Docs: Delete Guest Star Invite + /// Revokes a previously sent invite for a Guest Star session. + /// + /// The ID of the broadcaster running the Guest Star session. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token. + /// The ID of the session for the invite to be revoked on behalf of the broadcaster. + /// Twitch User ID for the guest to revoke the Guest Star session invite from. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + public Task DeleteGuestStarInvitesAsync(string broadcasterId, string moderatorId, string sessionId, string guestId, + string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + if (string.IsNullOrWhiteSpace(moderatorId)) + throw new BadParameterException("moderatorId must be set"); + if (string.IsNullOrWhiteSpace(sessionId)) + throw new BadParameterException("sessionId must be set"); + if (string.IsNullOrWhiteSpace(guestId)) + throw new BadParameterException("guestId must be set"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId), + new("moderator_id", moderatorId), + new("session_id", sessionId), + new("guest_id", guestId) + }; + + return TwitchDeleteAsync("/guest_star/invites", ApiVersion.Helix, getParams, accessToken); + } + + #endregion + + #region AssignGuestStarSlot + + /// + /// + /// Twitch Docs: Assign Guest Star Slot + /// Allows a previously invited user to be assigned a slot within the active Guest Star session, once that guest has indicated they are ready to join. + /// + /// The ID of the broadcaster running the Guest Star session. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token. + /// The ID of the Guest Star session in which to assign the slot. + /// The Twitch User ID corresponding to the guest to assign a slot in the session. This user must already have an invite to this session, and have indicated that they are ready to join. + /// The slot assignment to give to the user. Must be a numeric identifier between “1” and “N” where N is the max number of slots for the session. Max number of slots allowed for the session is reported by Get Channel Guest Star Settings. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + public Task AssignGuestStarSlotAsync(string broadcasterId, string moderatorId, string sessionId, string guestId, + string slotId, string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + if (string.IsNullOrWhiteSpace(moderatorId)) + throw new BadParameterException("moderatorId must be set"); + if (string.IsNullOrWhiteSpace(sessionId)) + throw new BadParameterException("sessionId must be set"); + if (string.IsNullOrWhiteSpace(guestId)) + throw new BadParameterException("guestId must be set"); + if (string.IsNullOrWhiteSpace(slotId)) + throw new BadParameterException("slotId must be set"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId), + new("moderator_id", moderatorId), + new("session_id", sessionId), + new("guest_id", guestId), + new("slot_id", slotId) + }; + + return TwitchPostAsync("/guest_star/slot", ApiVersion.Helix, null, getParams, accessToken); + } + + #endregion + + #region UpdateGuestStarSlot + + /// + /// + /// Twitch Docs: Update Guest Star Slot + /// Allows a user to update the assigned slot for a particular user within the active Guest Star session. + /// + /// The ID of the broadcaster running the Guest Star session. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token. + /// The ID of the Guest Star session in which to update slot settings. + /// The slot assignment previously assigned to a user. + /// The slot to move this user assignment to. If the destination slot is occupied, the user assigned will be swapped into source_slot_id. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + public Task UpdateGuestStarSlotAsync(string broadcasterId, string moderatorId, string sessionId, + string sourceSlotId, string destinationSlotId, string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + if (string.IsNullOrWhiteSpace(moderatorId)) + throw new BadParameterException("moderatorId must be set"); + if (string.IsNullOrWhiteSpace(sessionId)) + throw new BadParameterException("sessionId must be set"); + if (string.IsNullOrWhiteSpace(sourceSlotId)) + throw new BadParameterException("sourceSlotId must be set"); + if (string.IsNullOrWhiteSpace(destinationSlotId)) + throw new BadParameterException("destinationSlotId must be set"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId), + new("moderator_id", moderatorId), + new("session_id", sessionId), + new("source_slot_id", sourceSlotId), + new("destination_slot_id", destinationSlotId) + }; + + return TwitchPatchAsync("/guest_star/slot", ApiVersion.Helix, null, getParams, accessToken); + } + + #endregion + + #region DeleteGuestStarSlot + + /// + /// + /// Twitch Docs: Delete Guest Star Slot + /// Allows a caller to remove a slot assignment from a user participating in an active Guest Star session. This revokes their access to the session immediately and disables their access to publish or subscribe to media within the session. + /// + /// The ID of the broadcaster running the Guest Star session. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token. + /// The ID of the Guest Star session in which to remove the slot assignment. + /// The slot ID representing the slot assignment to remove from the session. + /// Optional Flag signaling that the guest should be reinvited to the session, sending them back to the invite queue. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + public Task DeleteGuestStarSlotAsync(string broadcasterId, string moderatorId, string sessionId, string slotId, + bool? shouldReinviteGuest = null, string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + if (string.IsNullOrWhiteSpace(moderatorId)) + throw new BadParameterException("moderatorId must be set"); + if (string.IsNullOrWhiteSpace(sessionId)) + throw new BadParameterException("sessionId must be set"); + if (string.IsNullOrWhiteSpace(slotId)) + throw new BadParameterException("slotId must be set"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId), + new("moderator_id", moderatorId), + new("session_id", sessionId), + new("slot_id", slotId) + }; + + if (shouldReinviteGuest.HasValue) + getParams.Add(new KeyValuePair("should_reinvite_guest", shouldReinviteGuest.Value.ToString())); + + return TwitchDeleteAsync("/guest_star/slot", ApiVersion.Helix, getParams, accessToken); + } + + #endregion + + #region DeleteGuestStarSlot + + /// + /// + /// Twitch Docs: Update Guest Star Slot Settings + /// Allows a user to update slot settings for a particular guest within a Guest Star session, such as allowing the user to share audio or video within the call as a host. These settings will be broadcasted to all subscribers which control their view of the guest in that slot. One or more of the optional parameters to this API can be specified at any time. + /// + /// The ID of the broadcaster running the Guest Star session. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token. + /// The ID of the Guest Star session in which to update a slot’s settings. + /// The slot assignment that has previously been assigned to a user. + /// Optional Flag indicating whether the slot is allowed to share their audio with the rest of the session. If false, the slot will be muted in any views containing the slot. + /// Optional Flag indicating whether the slot is allowed to share their video with the rest of the session. If false, the slot will have no video shared in any views containing the slot. + /// Optional Flag indicating whether the user assigned to this slot is visible/can be heard from any public subscriptions. Generally, this determines whether or not the slot is enabled in any broadcasting software integrations. + /// Optional Value from 0-100 that controls the audio volume for shared views containing the slot. + /// Optional access token to override the use of the stored one in the TwitchAPI instance + /// + public Task UpdateGuestStarSlotSettingsAsync(string broadcasterId, string moderatorId, string sessionId, string slotId, + bool? isAudioEnabled = null, bool? isVideoEnabled = null, bool? isLive = null, int? volume = null, string accessToken = null) + { + if (string.IsNullOrWhiteSpace(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + if (string.IsNullOrWhiteSpace(moderatorId)) + throw new BadParameterException("moderatorId must be set"); + if (string.IsNullOrWhiteSpace(sessionId)) + throw new BadParameterException("sessionId must be set"); + if (string.IsNullOrWhiteSpace(slotId)) + throw new BadParameterException("slotId must be set"); + + var getParams = new List> + { + new("broadcaster_id", broadcasterId), + new("moderator_id", moderatorId), + new("session_id", sessionId), + new("slot_id", slotId), + }; + + if (isAudioEnabled.HasValue) + getParams.Add(new KeyValuePair("is_audio_enabled", isAudioEnabled.Value.ToString())); + if (isVideoEnabled.HasValue) + getParams.Add(new KeyValuePair("is_video_enabled", isVideoEnabled.Value.ToString())); + if (isLive.HasValue) + getParams.Add(new KeyValuePair("is_live", isLive.Value.ToString())); + if (volume is >= 0 and <= 100) + getParams.Add(new KeyValuePair("volume", volume.Value.ToString())); + + return TwitchPatchAsync("/guest_star/slot_settings", ApiVersion.Helix, null, getParams, accessToken); + } + + #endregion +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix/Helix.cs b/TwitchLib.Api.Helix/Helix.cs index b5c1835b..516d9390 100644 --- a/TwitchLib.Api.Helix/Helix.cs +++ b/TwitchLib.Api.Helix/Helix.cs @@ -73,6 +73,10 @@ public class Helix /// public Goals Goals { get; } /// + /// GuestStar related Helix APIs + /// + public GuestStar GuestStar { get; } + /// /// HypeTrain related Helix APIs /// public HypeTrain HypeTrain { get; } @@ -157,6 +161,7 @@ public Helix(ILoggerFactory loggerFactory = null, IRateLimiter rateLimiter = nul Extensions = new Extensions(Settings, rateLimiter, http); Games = new Games(Settings, rateLimiter, http); Goals = new Goals(settings, rateLimiter, http); + GuestStar = new GuestStar(settings, rateLimiter, http); HypeTrain = new HypeTrain(Settings, rateLimiter, http); Moderation = new Moderation(Settings, rateLimiter, http); Polls = new Polls(Settings, rateLimiter, http); From ad213d4bb5a25867707b7b65b9f6a7b9e0cbae98 Mon Sep 17 00:00:00 2001 From: Syzuna Date: Sun, 3 Dec 2023 22:42:49 +0100 Subject: [PATCH 44/55] Update NameBasedMonitor to use correct channel value --- .../Services/Core/FollowerService/NameBasedMonitor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TwitchLib.Api/Services/Core/FollowerService/NameBasedMonitor.cs b/TwitchLib.Api/Services/Core/FollowerService/NameBasedMonitor.cs index a54b129e..df5be211 100644 --- a/TwitchLib.Api/Services/Core/FollowerService/NameBasedMonitor.cs +++ b/TwitchLib.Api/Services/Core/FollowerService/NameBasedMonitor.cs @@ -22,7 +22,7 @@ public override async Task GetUsersFollowsAsync(str channelId = (await _api.Helix.Users.GetUsersAsync(logins: new List { channel })).Users.FirstOrDefault()?.Id; _channelToId[channel] = channelId ?? throw new InvalidOperationException($"No channel with the name \"{channel}\" could be found."); } - return await _api.Helix.Channels.GetChannelFollowersAsync(channel, null, queryCount); + return await _api.Helix.Channels.GetChannelFollowersAsync(channelId, null, queryCount); } public void ClearCache() @@ -30,4 +30,4 @@ public void ClearCache() _channelToId.Clear(); } } -} \ No newline at end of file +} From 0320c75dfa18fe2681d6223f608d336630a96104 Mon Sep 17 00:00:00 2001 From: Syzuna Date: Fri, 29 Dec 2023 00:19:16 +0100 Subject: [PATCH 45/55] Adjust property names for GetAdSchedule --- .../Channels/GetAdSchedule/AdSchedule.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs b/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs index 2cfd9b96..b9dd25fb 100644 --- a/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs +++ b/TwitchLib.Api.Helix.Models/Channels/GetAdSchedule/AdSchedule.cs @@ -25,8 +25,8 @@ public class AdSchedule /// /// The length in seconds of the scheduled upcoming ad break. /// - [JsonProperty(PropertyName = "length_seconds")] - public int LengthSeconds { get;protected set; } + [JsonProperty(PropertyName = "duration")] + public int Duration { get; protected set; } /// /// The UTC timestamp of the broadcaster’s last ad-break, in RFC3339 format. Empty if the channel has not run an ad or is not live. /// @@ -35,7 +35,7 @@ public class AdSchedule /// /// The amount of pre-roll free time remaining for the channel in seconds. Returns 0 if they are currently not pre-roll free. /// - [JsonProperty(PropertyName = "preroll_free_time_seconds")] - public int PrerollFreeTimeSeconds { get; protected set; } + [JsonProperty(PropertyName = "preroll_free_time")] + public int PrerollFreeTime { get; protected set; } } } From 45e39dbc2d3b329badb2ab34087d9ff642e59e13 Mon Sep 17 00:00:00 2001 From: Psychoboy Date: Fri, 2 Feb 2024 03:35:39 -0700 Subject: [PATCH 46/55] Adds ability to use the new Send Chat Message in the Helix API (#385) * Added ability to Send Chat Messages --- TwitchLib.Api.Core.Enums/AuthScopesEnum.cs | 120 +++++++++--------- TwitchLib.Api.Core/Common/Helpers.cs | 1 + .../SendChatMessage/ChatMessageInfo.cs | 24 ++++ .../Channels/SendChatMessage/DropReason.cs | 18 +++ .../SendChatMessageResponse.cs | 13 ++ TwitchLib.Api.Helix/Chat.cs | 31 +++++ 6 files changed, 148 insertions(+), 59 deletions(-) create mode 100644 TwitchLib.Api.Helix.Models/Channels/SendChatMessage/ChatMessageInfo.cs create mode 100644 TwitchLib.Api.Helix.Models/Channels/SendChatMessage/DropReason.cs create mode 100644 TwitchLib.Api.Helix.Models/Channels/SendChatMessage/SendChatMessageResponse.cs diff --git a/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs b/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs index 6929b140..9fbb659f 100644 --- a/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs +++ b/TwitchLib.Api.Core.Enums/AuthScopesEnum.cs @@ -8,42 +8,42 @@ public enum AuthScopes /// Any scope. /// Any, - + /// /// View live stream chat messages. /// Chat_Read, - + /// /// Send live stream chat messages. /// Chat_Edit, - + /// /// Perform moderation actions in a channel. The user requesting the scope must be a moderator in the channel. /// Channel_Moderate, - + /// /// View your whisper messages. /// Whisper_Read, - + /// /// Send whisper messages. /// Whisper_Edit, - + /// /// View analytics data for the Twitch Extensions owned by the authenticated account. /// Analytics_Read_Extensions, - + /// /// View analytics data for the games owned by the authenticated account. /// Analytics_Read_Games, - + /// /// View Bits information for a channel. /// @@ -53,7 +53,7 @@ public enum AuthScopes /// Allows the client’s bot users access to a channel. /// Channel_Bot, - + /// /// Run commercials on a channel. /// @@ -68,52 +68,52 @@ public enum AuthScopes /// Manage a channel’s broadcast configuration, including updating channel configuration and managing stream markers and stream tags. /// Channel_Manage_Broadcast, - + /// /// Manage a channel’s Extension configuration, including activating Extensions. /// Channel_Manage_Extensions, - + /// /// Add or remove the moderator role from users in your channel. /// Channel_Manage_Moderators, - + /// /// Manage a channel’s polls. /// Channel_Manage_Polls, - + /// /// Manage of channel’s Channel Points Predictions /// Channel_Manage_Predictions, - + /// /// Manage Channel Points custom rewards and their redemptions on a channel. /// Channel_Manage_Redemptions, - + /// /// Manage a channel’s stream schedule. /// Channel_Manage_Schedule, - + /// /// Manage Guest Star for your channel. /// Channel_Manage_Guest_Star, - + /// /// Manage a channel raiding another channel. /// Channel_Manage_Raids, - + /// /// Manage a channel’s videos, including deleting videos. /// Channel_Manage_Videos, - + /// /// Add or remove the VIP role from users in your channel. /// @@ -128,152 +128,152 @@ public enum AuthScopes /// Read charity campaign details and user donations on your channel. /// Channel_Read_Charity, - + /// /// View a list of users with the editor role for a channel. /// Channel_Read_Editors, - + /// /// View Creator Goals for a channel. /// Channel_Read_Goals, - + /// /// View Hype Train information for a channel. /// Channel_Read_Hype_Train, - + /// /// View a channel’s polls. /// Channel_Read_Polls, - + /// /// View a channel’s Channel Points Predictions. /// Channel_Read_Predictions, - + /// /// View Channel Points custom rewards and their redemptions on a channel. /// Channel_Read_Redemptions, - + /// /// Read Guest Star details for your channel. /// Channel_Read_Guest_Star, - + /// /// View an authorized user’s stream key. /// Channel_Read_Stream_Key, - + /// /// View a list of all subscribers to a channel and check if a user is subscribed to a channel. /// Channel_Read_Subscriptions, - + /// /// Read the list of VIPs in your channel. /// Channel_Read_VIPs, - + /// /// Manage Clips for a channel. /// Clips_Edit, - + /// /// View a channel’s moderation data including Moderators, Bans, Timeouts, and Automod settings. /// Moderation_Read, - + /// /// Send announcements in channels where you have the moderator role. /// Moderator_Manage_Announcements, - + /// /// Manage messages held for review by AutoMod in channels where you are a moderator. /// Moderator_Manage_Automod, - + /// /// Manage a broadcaster’s AutoMod settings. /// Moderator_Manage_Automod_Settings, - + /// /// Ban and unban users. /// Moderator_Manage_Banned_Users, - + /// /// Manage a broadcaster’s list of blocked terms. /// Moderator_Manage_Blocked_Terms, - + /// /// Delete chat messages in channels where you have the moderator role /// Moderator_Manage_Chat_Messages, - + /// /// Manage a broadcaster’s chat room settings. /// Moderator_Manage_Chat_Settings, - + /// /// Manage Guest Star for channels where you are a Guest Star moderator. /// Moderator_Manage_Guest_Star, - + /// /// Manage a broadcaster’s Shield Mode status. /// Moderator_Manage_Shield_Mode, - + /// /// Manage a broadcaster’s shoutouts. /// Moderator_Manage_Shoutouts, - + /// /// View a broadcaster’s AutoMod settings. /// Moderator_Read_Automod_Settings, - + /// /// View a broadcaster’s list of blocked terms. /// Moderator_Read_Blocked_Terms, - + /// /// View a broadcaster’s chat room settings. /// Moderator_Read_Chat_Settings, - + /// /// View the chatters in a broadcaster’s chat room. /// Moderator_Read_Chatters, - + /// /// Read the followers of a broadcaster. /// Moderator_Read_Followers, - + /// /// Read Guest Star details for channels where you are a Guest Star moderator. /// Moderator_Read_Guest_Star, - + /// /// View a broadcaster’s Shield Mode status. /// Moderator_Read_Shield_Mode, - + /// /// View a broadcaster’s shoutouts. /// @@ -289,33 +289,33 @@ public enum AuthScopes /// Manage a user object. /// User_Edit, - + /// /// Deprecated. Was previously used for “Create User Follows” and “Delete User Follows.” /// [Obsolete("Deprecated")] User_Edit_Follows, - + /// /// Manage the block list of a user. /// User_Manage_BlockedUsers, - + /// /// Update the color used for the user’s name in chat. /// User_Manage_Chat_Color, - + /// /// Read whispers that you send and receive, and send whispers on your behalf. /// User_Manage_Whispers, - + /// /// View the block list of a user. /// User_Read_BlockedUsers, - + /// /// View a user’s broadcasting configuration, including Extension configurations. /// @@ -325,22 +325,24 @@ public enum AuthScopes /// View live stream chat and room messages. /// User_Read_Chat, - + /// /// View a user’s email address. /// User_Read_Email, - + /// /// View the list of channels a user follows. /// User_Read_Follows, - + /// /// View if an authorized user is subscribed to specific channels. /// User_Read_Subscriptions, - + + User_Write_Chat, + /// /// No scope /// diff --git a/TwitchLib.Api.Core/Common/Helpers.cs b/TwitchLib.Api.Core/Common/Helpers.cs index 37fc827c..29e1f6d5 100644 --- a/TwitchLib.Api.Core/Common/Helpers.cs +++ b/TwitchLib.Api.Core/Common/Helpers.cs @@ -74,6 +74,7 @@ public static string AuthScopesToString(AuthScopes scope) AuthScopes.User_Manage_BlockedUsers => "user:manage:blocked_users", AuthScopes.User_Manage_Chat_Color => "user:manage:chat_color", AuthScopes.User_Manage_Whispers => "user:manage:whispers", + AuthScopes.User_Write_Chat => "user:write:chat", AuthScopes.Moderator_Manage_Announcements => "moderator:manage:announcements", AuthScopes.Moderator_Manage_Automod => "moderator:manage:automod", AuthScopes.Moderator_Manage_Automod_Settings => "moderator:manage:automod_settings", diff --git a/TwitchLib.Api.Helix.Models/Channels/SendChatMessage/ChatMessageInfo.cs b/TwitchLib.Api.Helix.Models/Channels/SendChatMessage/ChatMessageInfo.cs new file mode 100644 index 00000000..acbbd620 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Channels/SendChatMessage/ChatMessageInfo.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.Channels.SendChatMessage +{ + public class ChatMessageInfo + { + /// + /// The message id for the message that was sent. + /// + [JsonProperty(PropertyName = "message_id", NullValueHandling = NullValueHandling.Ignore)] + public string MessageId { get; set; } = string.Empty; + /// + /// If the message passed all checks and was sent. + /// + [JsonProperty(PropertyName = "is_sent", NullValueHandling = NullValueHandling.Ignore)] + public bool IsSent { get; set; } + /// + /// The reason the message was dropped, if any. + /// + [JsonProperty(PropertyName = "drop_reason", NullValueHandling = NullValueHandling.Ignore)] + public DropReason[] DropReason { get; set; } = []; + + } +} diff --git a/TwitchLib.Api.Helix.Models/Channels/SendChatMessage/DropReason.cs b/TwitchLib.Api.Helix.Models/Channels/SendChatMessage/DropReason.cs new file mode 100644 index 00000000..21af9bef --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Channels/SendChatMessage/DropReason.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.Channels.SendChatMessage +{ + public class DropReason + { + /// + /// Code for why the message was dropped. + /// + [JsonProperty(PropertyName = "code", NullValueHandling = NullValueHandling.Ignore)] + public string Code { get; set; } = string.Empty; + /// + /// Message for why the message was dropped. + /// + [JsonProperty(PropertyName = "message", NullValueHandling = NullValueHandling.Ignore)] + public string Message { get; set; } = string.Empty; + } +} diff --git a/TwitchLib.Api.Helix.Models/Channels/SendChatMessage/SendChatMessageResponse.cs b/TwitchLib.Api.Helix.Models/Channels/SendChatMessage/SendChatMessageResponse.cs new file mode 100644 index 00000000..fe2aac41 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Channels/SendChatMessage/SendChatMessageResponse.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.Channels.SendChatMessage +{ + public class SendChatMessageResponse + { + /// + /// The data for the chat message + /// + [JsonProperty(PropertyName = "data", NullValueHandling = NullValueHandling.Ignore)] + public ChatMessageInfo[] Data { get; protected set; } + } +} diff --git a/TwitchLib.Api.Helix/Chat.cs b/TwitchLib.Api.Helix/Chat.cs index 879ab7fa..69d39844 100644 --- a/TwitchLib.Api.Helix/Chat.cs +++ b/TwitchLib.Api.Helix/Chat.cs @@ -8,6 +8,7 @@ using TwitchLib.Api.Core.Enums; using TwitchLib.Api.Core.Exceptions; using TwitchLib.Api.Core.Interfaces; +using TwitchLib.Api.Helix.Models.Channels.SendChatMessage; using TwitchLib.Api.Helix.Models.Chat; using TwitchLib.Api.Helix.Models.Chat.Badges.GetChannelChatBadges; using TwitchLib.Api.Helix.Models.Chat.Badges.GetGlobalChatBadges; @@ -297,6 +298,36 @@ public Task SendShoutoutAsync(string fromBroadcasterId, string toBroadcasterId, return TwitchPostAsync("/chat/shoutouts", ApiVersion.Helix, null, getParams, accessToken); } + /// + /// Sends a message to a chat + /// + /// The ID of the broadcaster whose chat room the message will be sent to. + /// The ID of the user sending the message. This ID must match the user ID in the user access token. + /// The message to send. The message is limited to a maximum of 500 characters. Chat messages can also include emoticons. To include emoticons, use the name of the emote. The names are case sensitive. Don’t include colons around the name (e.g., :bleedPurple:). If Twitch recognizes the name, Twitch converts the name to the emote before writing the chat message to the chat room + /// + /// + /// + public Task SendChatMessage(string broadcasterId, string senderId, string message, string accessToken = null) + { + if (string.IsNullOrEmpty(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + + if (string.IsNullOrEmpty(senderId)) + throw new BadParameterException("senderId must be set"); + + if (string.IsNullOrEmpty(message)) + throw new BadParameterException("message must be set"); + + var json = new JObject + { + ["broadcaster_id"] = broadcasterId, + ["sender_id"] = senderId, + ["message"] = message + }; + + return TwitchPostGenericAsync("/chat/messages", ApiVersion.Helix, json.ToString(), null, accessToken); + } + #endregion #region Update User Chat Color From 917ee17930cc6007b5aba3850f81111b1d786b4c Mon Sep 17 00:00:00 2001 From: Proddy Date: Fri, 22 Mar 2024 18:18:55 +0000 Subject: [PATCH 47/55] Update FollowerService.cs Surrounding the tick methid in a `try`/`catch` block to prevent errors from stalling the service --- TwitchLib.Api/Services/FollowerService.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/TwitchLib.Api/Services/FollowerService.cs b/TwitchLib.Api/Services/FollowerService.cs index 879ab2aa..35ef7beb 100644 --- a/TwitchLib.Api/Services/FollowerService.cs +++ b/TwitchLib.Api/Services/FollowerService.cs @@ -174,8 +174,10 @@ public async Task UpdateLatestFollowersAsync(bool callEvents = true) protected override async Task OnServiceTimerTick() { - await base.OnServiceTimerTick(); - await UpdateLatestFollowersAsync(); + try { + await base.OnServiceTimerTick(); + await UpdateLatestFollowersAsync(); + } catch {} } private async Task> GetLatestFollowersAsync(string channel) From 97052d8ca0018d7ef3ccf870c56c415f22d2deff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20K=C3=B6nig?= Date: Mon, 1 Apr 2024 01:38:18 +0200 Subject: [PATCH 48/55] add optional `replyParentMessageId` to SendChatMessage, as per API (#386) --- TwitchLib.Api.Helix/Chat.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/TwitchLib.Api.Helix/Chat.cs b/TwitchLib.Api.Helix/Chat.cs index 69d39844..22aea8f3 100644 --- a/TwitchLib.Api.Helix/Chat.cs +++ b/TwitchLib.Api.Helix/Chat.cs @@ -304,10 +304,11 @@ public Task SendShoutoutAsync(string fromBroadcasterId, string toBroadcasterId, /// The ID of the broadcaster whose chat room the message will be sent to. /// The ID of the user sending the message. This ID must match the user ID in the user access token. /// The message to send. The message is limited to a maximum of 500 characters. Chat messages can also include emoticons. To include emoticons, use the name of the emote. The names are case sensitive. Don’t include colons around the name (e.g., :bleedPurple:). If Twitch recognizes the name, Twitch converts the name to the emote before writing the chat message to the chat room + /// The ID of the chat message being replied to. If omitted, the message is not a reply /// /// /// - public Task SendChatMessage(string broadcasterId, string senderId, string message, string accessToken = null) + public Task SendChatMessage(string broadcasterId, string senderId, string message, string replyParentMessageId = null, string accessToken = null) { if (string.IsNullOrEmpty(broadcasterId)) throw new BadParameterException("broadcasterId must be set"); @@ -324,6 +325,10 @@ public Task SendChatMessage(string broadcasterId, strin ["sender_id"] = senderId, ["message"] = message }; + if (replyParentMessageId != null) + { + json.Add("reply_parent_message_id", replyParentMessageId); + } return TwitchPostGenericAsync("/chat/messages", ApiVersion.Helix, json.ToString(), null, accessToken); } From 42dbe49de61c1ba26cfc3848ec1fb8799451d8e6 Mon Sep 17 00:00:00 2001 From: cole Date: Tue, 2 Apr 2024 16:52:31 +0300 Subject: [PATCH 49/55] Conduit support (#389) Adds conduit support in EventSub: GetConduits, CreateConduit, UpdateConduit, DeleteConduit, GetConduitShards, UpdateConduitShards --- .../EventSub/Conduits/Conduit.cs | 17 +++ .../CreateConduits/CreateConduitsRequest.cs | 12 ++ .../CreateConduits/CreateConduitsResponse.cs | 12 ++ .../GetConduits/GetConduitsResponse.cs | 12 ++ .../GetConduitShardsResponse.cs | 18 +++ .../EventSub/Conduits/Shards/Shard.cs | 18 +++ .../EventSub/Conduits/Shards/Transport.cs | 33 +++++ .../Shards/UpdateConduitShards/Error.cs | 22 +++ .../Shards/UpdateConduitShards/ShardUpdate.cs | 18 +++ .../UpdateConduitShards/TransportUpdate.cs | 28 ++++ .../UpdateConduitShardsRequest.cs | 17 +++ .../UpdateConduitShardsResponse.cs | 17 +++ .../UpdateConduits/UpdateConduitsRequest.cs | 17 +++ .../UpdateConduits/UpdateConduitsResponse.cs | 12 ++ TwitchLib.Api.Helix/EventSub.cs | 125 ++++++++++++++++++ 15 files changed, 378 insertions(+) create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/Conduit.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/CreateConduits/CreateConduitsRequest.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/CreateConduits/CreateConduitsResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/GetConduits/GetConduitsResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/GetConduitShards/GetConduitShardsResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/Shard.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/Transport.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/Error.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/ShardUpdate.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/TransportUpdate.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/UpdateConduitShardsRequest.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/UpdateConduitShardsResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/UpdateConduits/UpdateConduitsRequest.cs create mode 100644 TwitchLib.Api.Helix.Models/EventSub/Conduits/UpdateConduits/UpdateConduitsResponse.cs diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/Conduit.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Conduit.cs new file mode 100644 index 00000000..502403c4 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Conduit.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits; + +public class Conduit +{ + /// + /// Conduit ID. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } + /// + /// Number of shards associated with this conduit. + /// + [JsonProperty(PropertyName = "shard_count")] + public int ShardCount { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/CreateConduits/CreateConduitsRequest.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/CreateConduits/CreateConduitsRequest.cs new file mode 100644 index 00000000..c3d7d5f6 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/CreateConduits/CreateConduitsRequest.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.CreateConduits; + +public class CreateConduitsRequest +{ + /// + /// The number of shards to create for this conduit. + /// + [JsonProperty(PropertyName = "shard_count")] + public int ShardCount { get; set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/CreateConduits/CreateConduitsResponse.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/CreateConduits/CreateConduitsResponse.cs new file mode 100644 index 00000000..02ff366b --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/CreateConduits/CreateConduitsResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.CreateConduits; + +public class CreateConduitsResponse +{ + /// + /// List of information about the client’s conduits. + /// + [JsonProperty(PropertyName = "data")] + public Conduit[] Data { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/GetConduits/GetConduitsResponse.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/GetConduits/GetConduitsResponse.cs new file mode 100644 index 00000000..27a2b1bb --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/GetConduits/GetConduitsResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.GetConduits; + +public class GetConduitsResponse +{ + /// + /// List of information about the client’s conduits. + /// + [JsonProperty(PropertyName = "data")] + public Conduit[] Data { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/GetConduitShards/GetConduitShardsResponse.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/GetConduitShards/GetConduitShardsResponse.cs new file mode 100644 index 00000000..efb9af77 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/GetConduitShards/GetConduitShardsResponse.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; +using TwitchLib.Api.Helix.Models.Common; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.Shards.GetConduitShards; + +public class GetConduitShardsResponse +{ + /// + /// List of information about a conduit's shards. + /// + [JsonProperty(PropertyName = "data")] + public Shard[] Shards { get; protected set; } + /// + /// Contains information used to page through a list of results. The object is empty if there are no more pages left to page through. + /// + [JsonProperty(PropertyName = "pagination")] + public Pagination Pagination { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/Shard.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/Shard.cs new file mode 100644 index 00000000..a44a27fe --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/Shard.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.Shards; + +public class Shard +{ + /// + /// Shard ID. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } + /// + /// The shard status. The subscriber receives events only for enabled shards. Possible values are: + /// enabled, webhook_callback_verification_pending, webhook_callback_verification_failed, notification_failures_exceeded, websocket_disconnected, websocket_failed_ping_pong, websocket_received_inbound_traffic, websocket_internal_error, websocket_network_timeout, websocket_network_error + /// + [JsonProperty(PropertyName = "status")] + public string Status { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/Transport.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/Transport.cs new file mode 100644 index 00000000..e9603b65 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/Transport.cs @@ -0,0 +1,33 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.Shards; + +public class Transport +{ + /// + /// The transport method. Possible values are: + /// webhook, websocket + /// + [JsonProperty(PropertyName = "method")] + public string Method { get; protected set; } + /// + /// The callback URL where the notifications are sent. Included only if method is set to webhook. + /// + [JsonProperty(PropertyName = "callback")] + public string Callback { get; protected set; } + /// + /// An ID that identifies the WebSocket that notifications are sent to. Included only if method is set to websocket. + /// + [JsonProperty(PropertyName = "session_id")] + public string SessionId { get; protected set; } + /// + /// The UTC date and time that the WebSocket connection was established. Included only if method is set to websocket. + /// + [JsonProperty(PropertyName = "connected_at")] + public string ConnectedAt { get; protected set; } + /// + /// The UTC date and time that the WebSocket connection was lost. Included only if method is set to websocket. + /// + [JsonProperty(PropertyName = "disconnected_at")] + public string DisconnectedAt { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/Error.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/Error.cs new file mode 100644 index 00000000..a925d5cd --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/Error.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.Shards.UpdateConduitShards; + +public class Error +{ + /// + /// Shard ID. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } + /// + /// The error that occurred while updating the shard. + /// + [JsonProperty(PropertyName = "message")] + public string Message { get; protected set; } + /// + /// Error codes used to represent a specific error condition while attempting to update shards. + /// + [JsonProperty(PropertyName = "code")] + public string Code { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/ShardUpdate.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/ShardUpdate.cs new file mode 100644 index 00000000..00f5d890 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/ShardUpdate.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.Shards.UpdateConduitShards; + +public class ShardUpdate +{ + /// + /// Shard ID. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; set; } + /// + /// The transport details that you want Twitch to use when sending you notifications. + /// + [JsonProperty(PropertyName = "transport")] + public TransportUpdate Transport { get; set; } + +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/TransportUpdate.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/TransportUpdate.cs new file mode 100644 index 00000000..dc1ece70 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/TransportUpdate.cs @@ -0,0 +1,28 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.Shards.UpdateConduitShards; + +public class TransportUpdate +{ + /// + /// The transport method. Possible values are: + /// webhook, websocket + /// + [JsonProperty(PropertyName = "method")] + public string Method { get; set; } + /// + /// The callback URL where the notifications are sent. The URL must use the HTTPS protocol and port 443. See Processing an event.Specify this field only if method is set to webhook.NOTE: Redirects are not followed. + /// + [JsonProperty(PropertyName = "callback", NullValueHandling = NullValueHandling.Ignore)] + public string Callback { get; set; } + /// + /// The secret used to verify the signature. The secret must be an ASCII string that’s a minimum of 10 characters long and a maximum of 100 characters long. For information about how the secret is used, see Verifying the event message.Specify this field only if method is set to webhook. + /// + [JsonProperty(PropertyName = "secret", NullValueHandling = NullValueHandling.Ignore)] + public string Secret { get; set; } + /// + /// An ID that identifies the WebSocket to send notifications to. When you connect to EventSub using WebSockets, the server returns the ID in the Welcome message.Specify this field only if method is set to websocket. + /// + [JsonProperty(PropertyName = "session_id", NullValueHandling = NullValueHandling.Ignore)] + public string SessionId { get; set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/UpdateConduitShardsRequest.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/UpdateConduitShardsRequest.cs new file mode 100644 index 00000000..ac026881 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/UpdateConduitShardsRequest.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.Shards.UpdateConduitShards; + +public class UpdateConduitShardsRequest +{ + /// + /// Conduit ID. + /// + [JsonProperty(PropertyName = "conduit_id")] + public string ConduitId { get; set; } + /// + /// List of shards to update. + /// + [JsonProperty(PropertyName = "shards")] + public ShardUpdate[] Shards { get; set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/UpdateConduitShardsResponse.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/UpdateConduitShardsResponse.cs new file mode 100644 index 00000000..cad07e25 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/Shards/UpdateConduitShards/UpdateConduitShardsResponse.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.Shards.UpdateConduitShards; + +public class UpdateConduitShardsResponse +{ + /// + /// List of successful shard updates. + /// + [JsonProperty(PropertyName = "data")] + public Shard[] Shards { get; protected set; } + /// + /// List of unsuccessful updates. + /// + [JsonProperty(PropertyName = "errors")] + public Error[] Errors { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/UpdateConduits/UpdateConduitsRequest.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/UpdateConduits/UpdateConduitsRequest.cs new file mode 100644 index 00000000..b61f6e9f --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/UpdateConduits/UpdateConduitsRequest.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.UpdateConduits; + +public class UpdateConduitsRequest +{ + /// + /// Conduit ID. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; set; } + /// + /// The new number of shards for this conduit. + /// + [JsonProperty(PropertyName = "shard_count")] + public int ShardCount { get; set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/EventSub/Conduits/UpdateConduits/UpdateConduitsResponse.cs b/TwitchLib.Api.Helix.Models/EventSub/Conduits/UpdateConduits/UpdateConduitsResponse.cs new file mode 100644 index 00000000..75e47bda --- /dev/null +++ b/TwitchLib.Api.Helix.Models/EventSub/Conduits/UpdateConduits/UpdateConduitsResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.EventSub.Conduits.UpdateConduits; + +public class UpdateConduitsResponse +{ + /// + /// List of information about the client’s conduits. + /// + [JsonProperty(PropertyName = "data")] + public Conduit[] Data { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix/EventSub.cs b/TwitchLib.Api.Helix/EventSub.cs index f73fc699..b902d0ec 100644 --- a/TwitchLib.Api.Helix/EventSub.cs +++ b/TwitchLib.Api.Helix/EventSub.cs @@ -8,6 +8,11 @@ using TwitchLib.Api.Core.Exceptions; using TwitchLib.Api.Core.Interfaces; using TwitchLib.Api.Helix.Models.EventSub; +using TwitchLib.Api.Helix.Models.EventSub.Conduits.CreateConduits; +using TwitchLib.Api.Helix.Models.EventSub.Conduits.GetConduits; +using TwitchLib.Api.Helix.Models.EventSub.Conduits.Shards.GetConduitShards; +using TwitchLib.Api.Helix.Models.EventSub.Conduits.Shards.UpdateConduitShards; +using TwitchLib.Api.Helix.Models.EventSub.Conduits.UpdateConduits; namespace TwitchLib.Api.Helix { @@ -132,5 +137,125 @@ public async Task DeleteEventSubSubscriptionAsync(string id, string client return response.Key == (int) HttpStatusCode.NoContent; } + + /// + /// Gets the conduits for a client ID. + /// + /// optional Client ID to override the use of the stored one in the TwitchAPI instance + /// optional access token to override the use of the stored one in the TwitchAPI instance + /// Returns a list of your conduits. + public async Task GetConduits(string clientId = null, string accessToken = null) + { + return await TwitchGetGenericAsync("/eventsub/conduits", ApiVersion.Helix, + null, accessToken, clientId); + } + + /// + /// Creates a new conduit. + /// + /// Request body parameters identifying conduit details + /// optional Client ID to override the use of the stored one in the TwitchAPI instance + /// optional access token to override the use of the stored one in the TwitchAPI instance + /// Returns a list of your conduits. + public async Task CreateConduits(CreateConduitsRequest request, string clientId = null, + string accessToken = null) + { + if (request.ShardCount is <= 0 or > 20_000) + throw new BadParameterException("request.ShardCount must be greater than 0 and less or equal than 20000"); + + return await TwitchPostGenericAsync("/eventsub/conduits", ApiVersion.Helix, + JsonConvert.SerializeObject(request), null, accessToken, clientId); + } + + /// + /// Updates a conduit’s shard count. To delete shards, update the count to a lower number, and the shards above the count will be deleted. For example, if the existing shard count is 100, by resetting shard count to 50, shards 50-99 are disabled. + /// + /// Request body parameters identifying conduit details + /// optional Client ID to override the use of the stored one in the TwitchAPI instance + /// optional access token to override the use of the stored one in the TwitchAPI instance + /// Returns a list of your conduits. + public async Task UpdateConduits(UpdateConduitsRequest request, string clientId = null, + string accessToken = null) + { + if (request.ShardCount is <= 0 or > 20_000) + throw new BadParameterException("request.ShardCount must be greater than 0 and less or equal than 20000"); + + return await TwitchPatchGenericAsync("/eventsub/conduits", ApiVersion.Helix, + JsonConvert.SerializeObject(request), null, accessToken, clientId); + } + + /// + /// Deletes a conduit. + /// + /// The ID of the conduit to delete. + /// optional Client ID to override the use of the stored one in the TwitchAPI instance + /// optional access token to override the use of the stored one in the TwitchAPI instance + /// True: If successfully deleted; False: If delete failed + public async Task DeleteConduit(string id, string clientId = null, string accessToken = null) + { + var getParams = new List> + { + new KeyValuePair("id", id) + }; + + var response = await TwitchDeleteAsync("/eventsub/conduits", ApiVersion.Helix, getParams, accessToken, clientId); + + return response.Key == (int) HttpStatusCode.NoContent; + } + + /// + /// Gets a lists of all shards for a conduit. + /// + /// Conduit ID. + /// Status to filter by. + /// The cursor used to get the next page of results. The pagination object in the response contains the cursor’s value. + /// optional Client ID to override the use of the stored one in the TwitchAPI instance + /// optional access token to override the use of the stored one in the TwitchAPI instance + /// Returns a list shards owned by the specified conduit. + public async Task GetConduitShards(string conduitId, string status = null, string after = null, string clientId = null, + string accessToken = null) + { + var getParams = new List> + { + new KeyValuePair("conduit_id", conduitId) + }; + if(!string.IsNullOrWhiteSpace(status)) + getParams.Add(new KeyValuePair("status", status)); + if(!string.IsNullOrWhiteSpace(after)) + getParams.Add(new KeyValuePair("after", after)); + + return await TwitchGetGenericAsync("/eventsub/conduits/shards", ApiVersion.Helix, + getParams, accessToken, clientId); + } + + /// + /// Updates shard(s) for a conduit. + /// + /// Request body parameters for updating conduit shards + /// optional Client ID to override the use of the stored one in the TwitchAPI instance + /// optional access token to override the use of the stored one in the TwitchAPI instance + /// Returns a list of successfully and errored conduit shard updates + public async Task UpdateConduitShards(UpdateConduitShardsRequest request, string clientId = null, + string accessToken = null) + { + List validMethods = new List() + { + "webhook", "websocket" + }; + const int secretMinLength = 10; + const int secretMaxLength = 100; + + foreach (var shard in request.Shards) + { + if (!validMethods.Contains(shard.Transport.Method)) + throw new BadParameterException($"request.Shards.Transport.Method valid values: {String.Join(", ", validMethods)}"); + if (shard.Transport.Secret != null && (shard.Transport.Secret.Length < secretMinLength || shard.Transport.Secret.Length > secretMaxLength)) + throw new BadParameterException( + $"request.Shards.Transport.Secret must be greater than or equal to {secretMinLength} and less than or equal to {secretMaxLength}"); + } + + return await TwitchPatchGenericAsync("/eventsub/conduits/shards", + ApiVersion.Helix, JsonConvert.SerializeObject(request), null, accessToken, clientId); + } } } From aafc9bccc7332a6a66d615526f8a5c6ff3a6e6b2 Mon Sep 17 00:00:00 2001 From: cole Date: Wed, 1 May 2024 12:49:06 +0800 Subject: [PATCH 50/55] add support for Chat/Emotes/GetUserEmotes (#391) * add support for GetUserEmotes --- .../Chat/Emotes/ChannelEmote.cs | 5 +++ .../Chat/Emotes/Emote.cs | 5 --- .../Chat/Emotes/EmoteSet.cs | 5 +++ .../GetUserEmotes/GetUserEmotesResponse.cs | 14 ++++++++ .../Chat/Emotes/GlobalEmote.cs | 10 ++++-- .../Chat/Emotes/UserEmote.cs | 36 +++++++++++++++++++ TwitchLib.Api.Helix/Chat.cs | 30 ++++++++++++++++ 7 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 TwitchLib.Api.Helix.Models/Chat/Emotes/GetUserEmotes/GetUserEmotesResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/Chat/Emotes/UserEmote.cs diff --git a/TwitchLib.Api.Helix.Models/Chat/Emotes/ChannelEmote.cs b/TwitchLib.Api.Helix.Models/Chat/Emotes/ChannelEmote.cs index c13b31c1..e51e49e3 100644 --- a/TwitchLib.Api.Helix.Models/Chat/Emotes/ChannelEmote.cs +++ b/TwitchLib.Api.Helix.Models/Chat/Emotes/ChannelEmote.cs @@ -4,6 +4,11 @@ namespace TwitchLib.Api.Helix.Models.Chat.Emotes { public class ChannelEmote : Emote { + /// + /// Contains the image URLs for the emote. + /// + [JsonProperty("images")] + public EmoteImages Images { get; protected set; } /// /// The subscriber tier at which the emote is unlocked. /// diff --git a/TwitchLib.Api.Helix.Models/Chat/Emotes/Emote.cs b/TwitchLib.Api.Helix.Models/Chat/Emotes/Emote.cs index cd176043..2d23e7d4 100644 --- a/TwitchLib.Api.Helix.Models/Chat/Emotes/Emote.cs +++ b/TwitchLib.Api.Helix.Models/Chat/Emotes/Emote.cs @@ -15,11 +15,6 @@ public abstract class Emote [JsonProperty("name")] public string Name { get; protected set; } /// - /// Contains the image URLs for the emote. - /// - [JsonProperty("images")] - public EmoteImages Images { get; protected set; } - /// /// The formats that the emote is available in. /// [JsonProperty("format")] diff --git a/TwitchLib.Api.Helix.Models/Chat/Emotes/EmoteSet.cs b/TwitchLib.Api.Helix.Models/Chat/Emotes/EmoteSet.cs index 47ae22ca..2b10ba14 100644 --- a/TwitchLib.Api.Helix.Models/Chat/Emotes/EmoteSet.cs +++ b/TwitchLib.Api.Helix.Models/Chat/Emotes/EmoteSet.cs @@ -15,6 +15,11 @@ public class EmoteSet : Emote [JsonProperty("emote_set_id")] public string EmoteSetId { get; protected set; } /// + /// Contains the image URLs for the emote. + /// + [JsonProperty("images")] + public EmoteImages Images { get; protected set; } + /// /// The ID of the broadcaster who owns the emote. /// [JsonProperty("owner_id")] diff --git a/TwitchLib.Api.Helix.Models/Chat/Emotes/GetUserEmotes/GetUserEmotesResponse.cs b/TwitchLib.Api.Helix.Models/Chat/Emotes/GetUserEmotes/GetUserEmotesResponse.cs new file mode 100644 index 00000000..6a3c7dd5 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Chat/Emotes/GetUserEmotes/GetUserEmotesResponse.cs @@ -0,0 +1,14 @@ +using Newtonsoft.Json; +using TwitchLib.Api.Helix.Models.Common; + +namespace TwitchLib.Api.Helix.Models.Chat.Emotes.GetUserEmotes; + +public class GetUserEmotesResponse +{ + [JsonProperty("data")] + public UserEmote[] Data { get; protected set; } + [JsonProperty("template")] + public string Template { get; protected set; } + [JsonProperty("pagination")] + public Pagination Pagination { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/Chat/Emotes/GlobalEmote.cs b/TwitchLib.Api.Helix.Models/Chat/Emotes/GlobalEmote.cs index 0b2197a7..6bdc88d6 100644 --- a/TwitchLib.Api.Helix.Models/Chat/Emotes/GlobalEmote.cs +++ b/TwitchLib.Api.Helix.Models/Chat/Emotes/GlobalEmote.cs @@ -1,7 +1,13 @@ -namespace TwitchLib.Api.Helix.Models.Chat.Emotes +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.Chat.Emotes { public class GlobalEmote : Emote { - // Empty for now as everything is in the base class already + /// + /// Contains the image URLs for the emote. + /// + [JsonProperty("images")] + public EmoteImages Images { get; protected set; } } } \ No newline at end of file diff --git a/TwitchLib.Api.Helix.Models/Chat/Emotes/UserEmote.cs b/TwitchLib.Api.Helix.Models/Chat/Emotes/UserEmote.cs new file mode 100644 index 00000000..820fa695 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Chat/Emotes/UserEmote.cs @@ -0,0 +1,36 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Helix.Models.Chat.Emotes; + +public class UserEmote : Emote +{ + /// + /// The type of emote. The possible values are: + /// none — No emote type was assigned to this emote. + /// - bitstier — A Bits tier emote. + /// - follower — A follower emote. + /// - subscriptions — A subscriber emote. + /// - channelpoints — An emote granted by using channel points. + /// - rewards — An emote granted to the user through a special event. + /// - hypetrain — An emote granted for participation in a Hype Train. + /// - prime — An emote granted for linking an Amazon Prime account. + /// - turbo — An emote granted for having Twitch Turbo. + /// - smilies — Emoticons supported by Twitch. + /// - globals — An emote accessible by everyone. + /// - owl2019 — Emotes related to Overwatch League 2019. + /// - twofactor — Emotes granted by enabling two-factor authentication on an account. + /// - limitedtime — Emotes that were granted for only a limited time. + /// + [JsonProperty("emote_type")] + public string EmoteType { get; protected set; } + /// + /// An ID that identifies the emote set that the emote belongs to. + /// + [JsonProperty("emote_set_id")] + public string EmoteSetId { get; protected set; } + /// + /// The ID of the broadcaster who owns the emote. + /// + [JsonProperty("owner_id")] + public string OwnerId { get; protected set; } +} \ No newline at end of file diff --git a/TwitchLib.Api.Helix/Chat.cs b/TwitchLib.Api.Helix/Chat.cs index 22aea8f3..03e1e35d 100644 --- a/TwitchLib.Api.Helix/Chat.cs +++ b/TwitchLib.Api.Helix/Chat.cs @@ -16,6 +16,7 @@ using TwitchLib.Api.Helix.Models.Chat.Emotes.GetChannelEmotes; using TwitchLib.Api.Helix.Models.Chat.Emotes.GetEmoteSets; using TwitchLib.Api.Helix.Models.Chat.Emotes.GetGlobalEmotes; +using TwitchLib.Api.Helix.Models.Chat.Emotes.GetUserEmotes; using TwitchLib.Api.Helix.Models.Chat.GetChatters; using TwitchLib.Api.Helix.Models.Chat.GetUserChatColor; @@ -148,6 +149,35 @@ public Task GetGlobalEmotesAsync(string accessToken = n { return TwitchGetGenericAsync("/chat/emotes/global", ApiVersion.Helix, accessToken: accessToken); } + + /// + /// Retrieves emotes available to the user across all channels. + /// + /// The ID of the user. This ID must match the user ID in the user access token. + /// The cursor used to get the next page of results. The Pagination object in the response contains the cursor’s value. + /// The User ID of a broadcaster you wish to get follower emotes of. Using this query parameter will guarantee inclusion of the broadcaster’s follower emotes in the response body. + /// optional access token to override the use of the stored one in the TwitchAPI instance + /// + public Task GetUserEmotesAsync(string userId, string after = null, + string broadcasterId = null, string accessToken = null) + { + if (string.IsNullOrEmpty(userId)) + throw new BadParameterException("userId must be set"); + + var getParams = new List> + { + new KeyValuePair("user_id", userId) + }; + + if (!string.IsNullOrEmpty(after)) + getParams.Add(new KeyValuePair("after", after)); + + if (!string.IsNullOrEmpty(broadcasterId)) + getParams.Add(new KeyValuePair("broadcaster_id", broadcasterId)); + + return TwitchGetGenericAsync("/chat/emotes/user", ApiVersion.Helix, getParams, + accessToken); + } #endregion #region GetChatSettings From d794ad503535c53b4099626c4d19f8cf809c2516 Mon Sep 17 00:00:00 2001 From: cole Date: Mon, 27 May 2024 15:43:05 -0700 Subject: [PATCH 51/55] add GetUnbanRequests and ResolveUnbanRequests (#394) * add GetUnbanRequests and ResolveUnbanRequests --- .../GetUnbanRequestsResponse.cs | 22 ++++ .../ResolveUnbanRequestsResponse.cs | 16 +++ .../Moderation/UnbanRequests/UnbanRequest.cs | 89 +++++++++++++++ TwitchLib.Api.Helix/Moderation.cs | 105 ++++++++++++++++++ 4 files changed, 232 insertions(+) create mode 100644 TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/GetUnbanRequests/GetUnbanRequestsResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/ResolveUnbanRequests/ResolveUnbanRequestsResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/UnbanRequest.cs diff --git a/TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/GetUnbanRequests/GetUnbanRequestsResponse.cs b/TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/GetUnbanRequests/GetUnbanRequestsResponse.cs new file mode 100644 index 00000000..cee6bf73 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/GetUnbanRequests/GetUnbanRequestsResponse.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; +using TwitchLib.Api.Helix.Models.Common; + +namespace TwitchLib.Api.Helix.Models.Moderation.UnbanRequests.GetUnbanRequests +{ + public class GetUnbanRequestsResponse + { + /// + /// A list that contains information about the channel's unban requests. + /// + [JsonProperty(PropertyName = "data")] + public UnbanRequest[] Data { get; protected set; } + /// + /// Contains information used to page through a list of results. The object is empty if there are no more pages left to page through. + /// + [JsonProperty(PropertyName = "pagination")] + public Pagination Pagination { get; protected set; } + } +} diff --git a/TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/ResolveUnbanRequests/ResolveUnbanRequestsResponse.cs b/TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/ResolveUnbanRequests/ResolveUnbanRequestsResponse.cs new file mode 100644 index 00000000..fe9be745 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/ResolveUnbanRequests/ResolveUnbanRequestsResponse.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace TwitchLib.Api.Helix.Models.Moderation.UnbanRequests.ResolveUnbanRequests +{ + public class ResolveUnbanRequestsResponse + { + /// + /// Contains information about the channel's unban request. + /// + [JsonProperty(PropertyName = "data")] + public UnbanRequest[] Data { get; protected set; } + } +} diff --git a/TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/UnbanRequest.cs b/TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/UnbanRequest.cs new file mode 100644 index 00000000..ea7ca1af --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Moderation/UnbanRequests/UnbanRequest.cs @@ -0,0 +1,89 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace TwitchLib.Api.Helix.Models.Moderation.UnbanRequests +{ + /// + /// Contains information about the channel's unban request + /// + public class UnbanRequest + { + /// + /// Unban request ID. + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; protected set; } + /// + /// The broadcaster's display name. + /// + [JsonProperty(PropertyName = "broadcaster_name")] + public string BroadcasterName { get; protected set; } + /// + /// The broadcaster's login name. + /// + [JsonProperty(PropertyName = "broadcaster_login")] + public string BroadcasterLogin { get; protected set; } + /// + /// User ID of broadcaster whose channel is receiving the unban request. + /// + [JsonProperty(PropertyName = "broadcaster_id")] + public string BroadcasterId { get; protected set; } + /// + /// User ID of moderator who approved/denied the request. + /// + [JsonProperty(PropertyName = "moderator_id")] + public string ModeratorId { get; protected set; } + /// + /// The moderator's login name. + /// + [JsonProperty(PropertyName = "moderator_login")] + public string ModeratorLogin { get; protected set; } + /// + /// The moderator's display name. + /// + [JsonProperty(PropertyName = "moderator_name")] + public string ModeratorName { get; protected set; } + /// + /// User ID of the requestor who is asking for an unban. + /// + [JsonProperty(PropertyName = "user_id")] + public string UserId { get; protected set; } + /// + /// The user's login name. + /// + [JsonProperty(PropertyName = "user_login")] + public string UserLogin { get; protected set; } + /// + /// The user's display name. + /// + [JsonProperty(PropertyName = "user_name")] + public string UserName { get; protected set; } + /// + /// Text of the request from the requesting user. + /// + [JsonProperty(PropertyName = "text")] + public string Text { get; protected set; } + /// + /// Status of the request. One of: pending, approved, denied, acknowledged, canceled + /// + [JsonProperty(PropertyName = "status")] + public string Status { get; protected set; } + /// + /// Timestamp of when the unban request was created. + /// + [JsonProperty(PropertyName = "created_at")] + public DateTime CreatedAt { get; protected set; } + /// + /// Timestamp of when moderator/broadcaster approved or denied the request. + /// + [JsonProperty(PropertyName = "resolved_at")] + public DateTime? ResolvedAt { get; protected set; } + /// + /// Text input by the resolver (moderator) of the unban. request + /// + [JsonProperty(PropertyName = "resolution_text")] + public string ResolutionText { get; protected set; } + } +} diff --git a/TwitchLib.Api.Helix/Moderation.cs b/TwitchLib.Api.Helix/Moderation.cs index 69d781e0..b01c818e 100644 --- a/TwitchLib.Api.Helix/Moderation.cs +++ b/TwitchLib.Api.Helix/Moderation.cs @@ -1,12 +1,15 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using TwitchLib.Api.Core; using TwitchLib.Api.Core.Enums; using TwitchLib.Api.Core.Exceptions; using TwitchLib.Api.Core.Interfaces; +using TwitchLib.Api.Helix.Models.Entitlements; using TwitchLib.Api.Helix.Models.Moderation.AutomodSettings; using TwitchLib.Api.Helix.Models.Moderation.BanUser; using TwitchLib.Api.Helix.Models.Moderation.BlockedTerms; @@ -19,6 +22,9 @@ using TwitchLib.Api.Helix.Models.Moderation.ShieldModeStatus; using TwitchLib.Api.Helix.Models.Moderation.ShieldModeStatus.GetShieldModeStatus; using TwitchLib.Api.Helix.Models.Moderation.ShieldModeStatus.UpdateShieldModeStatus; +using TwitchLib.Api.Helix.Models.Moderation.UnbanRequests; +using TwitchLib.Api.Helix.Models.Moderation.UnbanRequests.GetUnbanRequests; +using TwitchLib.Api.Helix.Models.Moderation.UnbanRequests.ResolveUnbanRequests; namespace TwitchLib.Api.Helix { @@ -671,5 +677,104 @@ public Task UpdateShieldModeStatusAsync(string broadcasterId, #endregion #endregion + + #region UnbanRequests + + #region GetUnbanRequests + + /// + /// Gets a list of unban requests for a broadcaster’s channel. + /// + /// The ID of the broadcaster whose channel is receiving unban requests. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s unban requests. This ID must match the user ID in the user access token. + /// Filter by a status: pending, approved, denied, acknowledged, canceled + /// The ID used to filter what unban requests are returned. + /// Cursor used to get next page of results. Pagination object in response contains cursor value. + /// The maximum number of items to return per page in response + /// optional access token to override the one used while creating the TwitchAPI object + /// + /// + public Task GetUnbanRequestsAsync(string broadcasterId, string moderatorId, string status, string userId = null, string after = null, int first = 0, string accessToken = null) + { + if (string.IsNullOrEmpty(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + + if (string.IsNullOrEmpty(moderatorId)) + throw new BadParameterException("moderatorId must be set"); + + string[] validStatus = { "pending", "approved", "denied", "acknowledged", "canceled" }; + if (string.IsNullOrEmpty(status) || !validStatus.Contains(status)) + throw new BadParameterException("status must be set and a valid value"); + + var getParams = new List> + { + new KeyValuePair("broadcaster_id", broadcasterId), + new KeyValuePair("moderator_id", moderatorId), + new KeyValuePair("status", status), + }; + + if (!string.IsNullOrEmpty(userId)) + getParams.Add(new KeyValuePair("user_id", userId)); + + if (!string.IsNullOrEmpty(after)) + getParams.Add(new KeyValuePair("after", after)); + + if (first > 0) + getParams.Add(new KeyValuePair("first", first.ToString())); + + return TwitchGetGenericAsync("/moderation/unban_requests", ApiVersion.Helix, getParams, accessToken); + } + + #endregion + + #region ResolveUnbanRequests + + /// + /// Resolves an unban request by approving or denying it. + /// + /// The ID of the broadcaster whose channel is approving or denying the unban request. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s unban requests. This ID must match the user ID in the user access token. + /// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s unban requests. This ID must match the user ID in the user access token. + /// Resolution status: approved, denied + /// Message supplied by the unban request resolver. The message is limited to a maximum of 500 characters. + /// optional access token to override the one used while creating the TwitchAPI object + /// + /// + public Task ResolveUnbanRequestsAsync(string broadcasterId, string moderatorId, string unbanRequestId, string status, string resolutionText, string accessToken = null) + { + if (string.IsNullOrEmpty(broadcasterId)) + throw new BadParameterException("broadcasterId must be set"); + + if (string.IsNullOrEmpty(moderatorId)) + throw new BadParameterException("moderatorId must be set"); + + if (string.IsNullOrEmpty(unbanRequestId)) + throw new BadParameterException("unbanRequestId must be set"); + + string[] validStatus = { "approved", "denied" }; + if (string.IsNullOrEmpty(status) || !validStatus.Contains(status)) + throw new BadParameterException("status must be set and a valid value"); + + var getParams = new List> + { + new KeyValuePair("broadcaster_id", broadcasterId), + new KeyValuePair("moderator_id", moderatorId), + new KeyValuePair("unban_request_id", unbanRequestId), + new KeyValuePair("status", status) + }; + if (!string.IsNullOrEmpty(resolutionText)) + { + if (resolutionText.Length > 500) + throw new BadParameterException("resolutionText cannot be longer than 500 characters"); + + getParams.Add(new KeyValuePair("resolution_text", resolutionText)); + } + + return TwitchPatchGenericAsync("/moderation/unban_requests", ApiVersion.Helix, null, getParams, accessToken); + } + + #endregion + + #endregion } } From 1ac5740255a74b93f392aa21ccd91541e8510da1 Mon Sep 17 00:00:00 2001 From: cole Date: Mon, 27 May 2024 15:44:12 -0700 Subject: [PATCH 52/55] move StartCommercialAsync to Channels class; remove Ads class (#392) * move StartCommercialAsync to Channels class; remove Ads classs --- .../StartCommercialRequest.cs | 2 +- .../StartCommercialResponse.cs | 2 +- TwitchLib.Api.Helix/Ads.cs | 39 ------------------- TwitchLib.Api.Helix/Channels.cs | 21 ++++++++++ TwitchLib.Api.Helix/Helix.cs | 5 --- 5 files changed, 23 insertions(+), 46 deletions(-) rename TwitchLib.Api.Helix.Models/{Ads => Channels/StartCommercial}/StartCommercialRequest.cs (93%) rename TwitchLib.Api.Helix.Models/{Ads => Channels/StartCommercial}/StartCommercialResponse.cs (93%) delete mode 100644 TwitchLib.Api.Helix/Ads.cs diff --git a/TwitchLib.Api.Helix.Models/Ads/StartCommercialRequest.cs b/TwitchLib.Api.Helix.Models/Channels/StartCommercial/StartCommercialRequest.cs similarity index 93% rename from TwitchLib.Api.Helix.Models/Ads/StartCommercialRequest.cs rename to TwitchLib.Api.Helix.Models/Channels/StartCommercial/StartCommercialRequest.cs index dc53cb9c..c3f8bcb7 100644 --- a/TwitchLib.Api.Helix.Models/Ads/StartCommercialRequest.cs +++ b/TwitchLib.Api.Helix.Models/Channels/StartCommercial/StartCommercialRequest.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace TwitchLib.Api.Helix.Models.Ads +namespace TwitchLib.Api.Helix.Models.Channels.StartCommercial { /// /// Request Body for StartCommercial diff --git a/TwitchLib.Api.Helix.Models/Ads/StartCommercialResponse.cs b/TwitchLib.Api.Helix.Models/Channels/StartCommercial/StartCommercialResponse.cs similarity index 93% rename from TwitchLib.Api.Helix.Models/Ads/StartCommercialResponse.cs rename to TwitchLib.Api.Helix.Models/Channels/StartCommercial/StartCommercialResponse.cs index 582b1b42..91e307d7 100644 --- a/TwitchLib.Api.Helix.Models/Ads/StartCommercialResponse.cs +++ b/TwitchLib.Api.Helix.Models/Channels/StartCommercial/StartCommercialResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace TwitchLib.Api.Helix.Models.Ads +namespace TwitchLib.Api.Helix.Models.Channels.StartCommercial { /// /// The response for starting a commercial on a specified channel. diff --git a/TwitchLib.Api.Helix/Ads.cs b/TwitchLib.Api.Helix/Ads.cs deleted file mode 100644 index 9844a7c9..00000000 --- a/TwitchLib.Api.Helix/Ads.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Newtonsoft.Json; -using System.Threading.Tasks; -using TwitchLib.Api.Core; -using TwitchLib.Api.Core.Enums; -using TwitchLib.Api.Core.Interfaces; -using TwitchLib.Api.Helix.Models.Ads; - -namespace TwitchLib.Api.Helix -{ - /// - /// Ads related APIs - /// - public class Ads : ApiBase - { - public Ads(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandler http) : base(settings, rateLimiter, http) - { - } - - #region StartCommercial - - /// - /// - /// Twitch Docs: Start Commercial - /// Starts a commercial on the specified channel. - /// Only partners and affiliates may run commercials and they must be streaming live at the time. - /// Only the broadcaster may start a commercial - the broadcaster’s editors and moderators may not start commercials on behalf of the broadcaster. - /// Requires a user access token that includes the channel:edit:commercial scope. - /// - /// - /// Optional access token to override the use of the stored one in the TwitchAPI instance. - /// - public Task StartCommercialAsync(StartCommercialRequest request, string accessToken = null) - { - return TwitchPostGenericAsync("/channels/commercial", ApiVersion.Helix, JsonConvert.SerializeObject(request), null, accessToken); - } - - #endregion - } -} diff --git a/TwitchLib.Api.Helix/Channels.cs b/TwitchLib.Api.Helix/Channels.cs index 971b5fd8..fac8fe87 100644 --- a/TwitchLib.Api.Helix/Channels.cs +++ b/TwitchLib.Api.Helix/Channels.cs @@ -14,6 +14,7 @@ using TwitchLib.Api.Helix.Models.Channels.GetFollowedChannels; using TwitchLib.Api.Helix.Models.Channels.ModifyChannelInformation; using TwitchLib.Api.Helix.Models.Channels.SnoozeNextAd; +using TwitchLib.Api.Helix.Models.Channels.StartCommercial; namespace TwitchLib.Api.Helix { @@ -327,5 +328,25 @@ public Task SnoozeNextAd(string broadcasterId, string acce } #endregion + + #region StartCommercial + + /// + /// + /// Twitch Docs: Start Commercial + /// Starts a commercial on the specified channel. + /// Only partners and affiliates may run commercials and they must be streaming live at the time. + /// Only the broadcaster may start a commercial - the broadcaster’s editors and moderators may not start commercials on behalf of the broadcaster. + /// Requires a user access token that includes the channel:edit:commercial scope. + /// + /// + /// Optional access token to override the use of the stored one in the TwitchAPI instance. + /// + public Task StartCommercialAsync(StartCommercialRequest request, string accessToken = null) + { + return TwitchPostGenericAsync("/channels/commercial", ApiVersion.Helix, JsonConvert.SerializeObject(request), null, accessToken); + } + + #endregion } } diff --git a/TwitchLib.Api.Helix/Helix.cs b/TwitchLib.Api.Helix/Helix.cs index 516d9390..b778a8b8 100644 --- a/TwitchLib.Api.Helix/Helix.cs +++ b/TwitchLib.Api.Helix/Helix.cs @@ -21,10 +21,6 @@ public class Helix /// public Analytics Analytics { get; } /// - /// Ads related Helix APIs - /// - public Ads Ads { get; } - /// /// Bits related Helix APIs /// public Bits Bits { get; } @@ -148,7 +144,6 @@ public Helix(ILoggerFactory loggerFactory = null, IRateLimiter rateLimiter = nul Settings = settings ?? new ApiSettings(); Analytics = new Analytics(Settings, rateLimiter, http); - Ads = new Ads(Settings, rateLimiter, http); Bits = new Bits(Settings, rateLimiter, http); Chat = new Chat(Settings, rateLimiter, http); Channels = new Channels(Settings, rateLimiter, http); From b097221413e9719547a6a0316d5019a6d83b87f6 Mon Sep 17 00:00:00 2001 From: Mahsaap Date: Mon, 27 May 2024 19:45:23 -0300 Subject: [PATCH 53/55] Quick fix GetChanneliCalendar (#390) Added return string as quick fix. --- TwitchLib.Api.Helix/Schedule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TwitchLib.Api.Helix/Schedule.cs b/TwitchLib.Api.Helix/Schedule.cs index e88e2fdb..a978d9c5 100644 --- a/TwitchLib.Api.Helix/Schedule.cs +++ b/TwitchLib.Api.Helix/Schedule.cs @@ -187,7 +187,7 @@ public Task DeleteChannelStreamScheduleSegmentAsync(string broadcasterId, string /// /// User ID of the broadcaster who owns the channel streaming schedule. /// - public Task GetChanneliCalendarAsync(string broadcasterId) + public Task GetChanneliCalendarAsync(string broadcasterId) { var getParams = new List> { @@ -197,4 +197,4 @@ public Task GetChanneliCalendarAsync(string broadcasterId) return TwitchGetAsync("/schedule/icalendar", ApiVersion.Helix, getParams); } } -} \ No newline at end of file +} From 7deef4b67b9ce89505ce7968a7bb947e6e606935 Mon Sep 17 00:00:00 2001 From: Faey <1144986+FaeyUmbrea@users.noreply.github.com> Date: Sun, 9 Jun 2024 11:25:10 +0200 Subject: [PATCH 54/55] Add conduit subscription support (#393) --- .../EventSubTransportMethod.cs | 5 +++-- TwitchLib.Api.Helix/EventSub.cs | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/TwitchLib.Api.Core.Enums/EventSubTransportMethod.cs b/TwitchLib.Api.Core.Enums/EventSubTransportMethod.cs index aa906a76..40f13b92 100644 --- a/TwitchLib.Api.Core.Enums/EventSubTransportMethod.cs +++ b/TwitchLib.Api.Core.Enums/EventSubTransportMethod.cs @@ -3,6 +3,7 @@ public enum EventSubTransportMethod { Webhook, - Websocket + Websocket, + Conduit } -} \ No newline at end of file +} diff --git a/TwitchLib.Api.Helix/EventSub.cs b/TwitchLib.Api.Helix/EventSub.cs index b902d0ec..bd71dd2a 100644 --- a/TwitchLib.Api.Helix/EventSub.cs +++ b/TwitchLib.Api.Helix/EventSub.cs @@ -30,13 +30,14 @@ public EventSub(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandle /// The parameter values that are specific to the specified subscription type. /// The transport method. Supported values: Webhook, Websocket. /// The session Id of a websocket connection that you want to subscribe to an event for. Only needed if method is Websocket + /// The conduit Id of a EventSub conduit. Only needed if method is Conduit. /// The callback URL where the Webhook notification should be sent. Only needed if method is Webhook /// The secret used for verifying a Webhooks signature. Only needed if method is Webhook /// optional Client ID to override the use of the stored one in the TwitchAPI instance /// optional access token to override the use of the stored one in the TwitchAPI instance /// public Task CreateEventSubSubscriptionAsync(string type, string version, Dictionary condition, EventSubTransportMethod method, string websocketSessionId = null, string webhookCallback = null, - string webhookSecret = null, string clientId = null, string accessToken = null) + string webhookSecret = null, string conduitId = null, string clientId = null, string accessToken = null) { if (string.IsNullOrEmpty(type)) throw new BadParameterException("type must be set"); @@ -85,6 +86,22 @@ public Task CreateEventSubSubscriptionAsync( } }; return TwitchPostGenericAsync("/eventsub/subscriptions", ApiVersion.Helix, JsonConvert.SerializeObject(websocketBody), null, accessToken, clientId); + case EventSubTransportMethod.Conduit: + if (string.IsNullOrWhiteSpace(conduitId)) + throw new BadParameterException("conduitId must be set"); + + var conduitBody = new + { + type, + version, + condition, + transport = new + { + method = method.ToString().ToLowerInvariant(), + conduit_id = conduitId + } + }; + return TwitchPostGenericAsync("/eventsub/subscriptions", ApiVersion.Helix, JsonConvert.SerializeObject(conduitBody), null, accessToken, clientId); default: throw new ArgumentOutOfRangeException(nameof(method), method, null); } From b738286cf960d6959ec7c3de0ad4b34dfe29c0fa Mon Sep 17 00:00:00 2001 From: Mahsaap Date: Thu, 13 Jun 2024 10:08:20 -0300 Subject: [PATCH 55/55] Add get Moderated Channels --- .../GetModeratedChannelsResponse.cs | 26 ++++++++++++++ .../GetModeratedChannels/ModeratedChannel.cs | 29 ++++++++++++++++ TwitchLib.Api.Helix/Moderation.cs | 34 +++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 TwitchLib.Api.Helix.Models/Moderation/GetModeratedChannels/GetModeratedChannelsResponse.cs create mode 100644 TwitchLib.Api.Helix.Models/Moderation/GetModeratedChannels/ModeratedChannel.cs diff --git a/TwitchLib.Api.Helix.Models/Moderation/GetModeratedChannels/GetModeratedChannelsResponse.cs b/TwitchLib.Api.Helix.Models/Moderation/GetModeratedChannels/GetModeratedChannelsResponse.cs new file mode 100644 index 00000000..c258e8fa --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Moderation/GetModeratedChannels/GetModeratedChannelsResponse.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; +using TwitchLib.Api.Helix.Models.Common; +using TwitchLib.Api.Helix.Models.Moderation.GetModerators; + +namespace TwitchLib.Api.Helix.Models.Moderation.GetModeratedChannels +{ + /// + /// List of channels that the specified user has moderator privileges in. + /// + public class GetModeratedChannelsResponse + { + /// + /// The list of channels that the user has moderator privileges in. + /// + [JsonProperty(PropertyName = "data")] + public ModeratedChannel[] Data { get; protected set; } + /// + /// Contains the information used to page through the list of results. The object is empty if there are no more pages left to page through. + /// + [JsonProperty(PropertyName = "pagination")] + public Pagination Pagination { get; protected set; } + } +} diff --git a/TwitchLib.Api.Helix.Models/Moderation/GetModeratedChannels/ModeratedChannel.cs b/TwitchLib.Api.Helix.Models/Moderation/GetModeratedChannels/ModeratedChannel.cs new file mode 100644 index 00000000..af09ef62 --- /dev/null +++ b/TwitchLib.Api.Helix.Models/Moderation/GetModeratedChannels/ModeratedChannel.cs @@ -0,0 +1,29 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace TwitchLib.Api.Helix.Models.Moderation.GetModeratedChannels +{ + /// + /// Channel that the user has moderator privileges in. + /// + public class ModeratedChannel + { + /// + /// An ID that uniquely identifies the channel this user can moderate. + /// + [JsonProperty(PropertyName = "broadcaster_id")] + public string BroadcasterId { get; protected set; } + /// + /// The channel’s login name. + /// + [JsonProperty(PropertyName = "broadcaster_login")] + public string BroadcasterLogin { get; protected set; } + /// + /// The channels’ display name. + /// + [JsonProperty(PropertyName = "broadcaster_name")] + public string BroadcasterName { get; protected set; } + } +} diff --git a/TwitchLib.Api.Helix/Moderation.cs b/TwitchLib.Api.Helix/Moderation.cs index b01c818e..a629c6a2 100644 --- a/TwitchLib.Api.Helix/Moderation.cs +++ b/TwitchLib.Api.Helix/Moderation.cs @@ -17,6 +17,7 @@ using TwitchLib.Api.Helix.Models.Moderation.CheckAutoModStatus.Request; using TwitchLib.Api.Helix.Models.Moderation.GetBannedEvents; using TwitchLib.Api.Helix.Models.Moderation.GetBannedUsers; +using TwitchLib.Api.Helix.Models.Moderation.GetModeratedChannels; using TwitchLib.Api.Helix.Models.Moderation.GetModeratorEvents; using TwitchLib.Api.Helix.Models.Moderation.GetModerators; using TwitchLib.Api.Helix.Models.Moderation.ShieldModeStatus; @@ -776,5 +777,38 @@ public Task ResolveUnbanRequestsAsync(string broad #endregion #endregion + + #region GetModeratedChannels + /// + /// Gets a list of channels that the specified user has moderator privileges in. + /// Requires a user access token that includes the user:read:moderated_channels scope. + /// The ID in the broadcaster_id query parameter must match the user ID in the access token. + /// + /// Id of the user you want the list of channels that this user has moderator privileges in. + /// Maximum number of objects to return. Maximum: 100. Default: 20. + /// Cursor for forward pagination: tells the server where to start fetching the next set of results in a multi-page response. + /// optional access token to override the use of the stored one in the TwitchAPI instance + /// + /// + public Task GetModeratedChannelsAsync(string userId, int first = 20, string after = null, string accessToken = null) + { + if (string.IsNullOrWhiteSpace(userId)) + throw new BadParameterException("userId cannot be null/empty/whitespace"); + if (first > 100 || first < 1) + throw new BadParameterException("first must be greater than 0 and less than 101"); + + var getParams = new List> + { + new KeyValuePair("user_id", userId), + new KeyValuePair("first", first.ToString()) + }; + + if (!string.IsNullOrWhiteSpace(after)) + getParams.Add(new KeyValuePair("after", after)); + + return TwitchGetGenericAsync("/moderation/channels", ApiVersion.Helix, getParams, accessToken); + } + + #endregion } }