From cce3ab7275ff8f5b4b5a0e9e9d84c59287f074b4 Mon Sep 17 00:00:00 2001
From: Foretack <69414142+Foretack@users.noreply.github.com>
Date: Wed, 1 Nov 2023 10:30:10 +0100
Subject: [PATCH] Add MiniTwitch.Helix (#44)
---
.github/workflows/build-helix.yml | 30 +
MiniTwitch.Helix/Enums/AnalyticsType.cs | 6 +
MiniTwitch.Helix/Enums/AnnouncementColor.cs | 10 +
.../Enums/BitsLeaderboardPeriod.cs | 10 +
MiniTwitch.Helix/Enums/ChatColor.cs | 20 +
MiniTwitch.Helix/Enums/ConfigSegmentType.cs | 8 +
MiniTwitch.Helix/Enums/ContentLabelid.cs | 10 +
MiniTwitch.Helix/Enums/EventSubStatus.cs | 20 +
MiniTwitch.Helix/Enums/FulfillmentStatus.cs | 7 +
MiniTwitch.Helix/Enums/LabelLocale.cs | 34 +
.../Enums/RewardRedemptionStatus.cs | 8 +
MiniTwitch.Helix/Enums/SortMethod.cs | 7 +
MiniTwitch.Helix/Enums/StreamTypes.cs | 7 +
MiniTwitch.Helix/Enums/VideoPeriod.cs | 9 +
MiniTwitch.Helix/Enums/VideoSortMethod.cs | 8 +
MiniTwitch.Helix/Enums/VideoType.cs | 9 +
MiniTwitch.Helix/HelixWrapper.cs | 984 ++++++++
MiniTwitch.Helix/Interfaces/IHelixResult.cs | 11 +
MiniTwitch.Helix/Interfaces/IPaginable.cs | 8 +
MiniTwitch.Helix/Internal/HelixApiClient.cs | 176 ++
.../Internal/HelixResultFactory.cs | 125 +
.../Internal/Json/EnumToString.cs | 30 +
.../Internal/Json/ICaseConverter.cs | 7 +
MiniTwitch.Helix/Internal/Json/IntToString.cs | 12 +
.../Internal/Json/LongToString.cs | 12 +
MiniTwitch.Helix/Internal/Json/SnakeCase.cs | 56 +
.../Internal/Json/SnakeCaseNamingPolicy.cs | 32 +
.../Internal/Json/TimeSpanToSeconds.cs | 12 +
MiniTwitch.Helix/Internal/Models/Endpoints.cs | 1901 +++++++++++++++
.../Internal/Models/HelixEndpoint.cs | 11 +
MiniTwitch.Helix/Internal/Models/HelixTask.cs | 8 +
.../Internal/Models/InvalidToken.cs | 8 +
.../Internal/Models/QueryParams.cs | 65 +
.../Internal/Models/RequestData.cs | 72 +
.../Internal/Models/ValidToken.cs | 15 +
MiniTwitch.Helix/MiniTwitch.Helix.csproj | 46 +
MiniTwitch.Helix/Models/AllCategories.cs | 2106 +++++++++++++++++
MiniTwitch.Helix/Models/AnalyticsCategory.cs | 33 +
MiniTwitch.Helix/Models/BaseResponse.cs | 12 +
MiniTwitch.Helix/Models/BitsCategory.cs | 39 +
.../Models/ChannelPointsCategory.cs | 84 +
MiniTwitch.Helix/Models/ChannelsCategory.cs | 91 +
MiniTwitch.Helix/Models/CharityCategory.cs | 24 +
MiniTwitch.Helix/Models/ChatCategory.cs | 99 +
MiniTwitch.Helix/Models/ClipsCategory.cs | 41 +
.../Models/ContentClassificationLabel.cs | 9 +
.../Models/EntitlementsCategory.cs | 38 +
MiniTwitch.Helix/Models/EventsubCategory.cs | 32 +
MiniTwitch.Helix/Models/ExtensionsCategory.cs | 87 +
MiniTwitch.Helix/Models/GamesCategory.cs | 32 +
MiniTwitch.Helix/Models/GuestStarCategory.cs | 105 +
MiniTwitch.Helix/Models/HelixResult.cs | 96 +
.../Models/InvalidTokenException.cs | 11 +
MiniTwitch.Helix/Models/ModerationCategory.cs | 135 ++
MiniTwitch.Helix/Models/PaginableResponse.cs | 10 +
MiniTwitch.Helix/Models/Pagination.cs | 6 +
MiniTwitch.Helix/Models/PollsCategory.cs | 40 +
.../Models/PredictionsCategory.cs | 38 +
MiniTwitch.Helix/Models/RaidsCategory.cs | 24 +
MiniTwitch.Helix/Models/RequestRatelimit.cs | 17 +
MiniTwitch.Helix/Models/ScheduleCategory.cs | 58 +
MiniTwitch.Helix/Models/SearchCategory.cs | 26 +
MiniTwitch.Helix/Models/SingleResponse.cs | 15 +
MiniTwitch.Helix/Models/StreamsCategory.cs | 58 +
.../Models/SubscriptionsCategory.cs | 33 +
MiniTwitch.Helix/Models/TeamsCategory.cs | 24 +
MiniTwitch.Helix/Models/UsersCategory.cs | 57 +
MiniTwitch.Helix/Models/VideosCategory.cs | 48 +
MiniTwitch.Helix/README.md | 94 +
MiniTwitch.Helix/Requests/Announcement.cs | 12 +
.../Requests/ConfigurationSegment.cs | 21 +
.../Requests/ExtensionChatMessage.cs | 8 +
.../Requests/ExtensionPubSubMessage.cs | 16 +
.../ExtensionRequiredConfiguration.cs | 8 +
MiniTwitch.Helix/Requests/MessageToCheck.cs | 13 +
.../Requests/NewAutoModSettings.cs | 14 +
.../Requests/NewChannelInformation.cs | 18 +
MiniTwitch.Helix/Requests/NewChatSettings.cs | 14 +
MiniTwitch.Helix/Requests/NewCommercial.cs | 11 +
MiniTwitch.Helix/Requests/NewCustomReward.cs | 18 +
.../Requests/NewGuestStarSettings.cs | 10 +
MiniTwitch.Helix/Requests/NewPoll.cs | 21 +
MiniTwitch.Helix/Requests/NewPrediction.cs | 19 +
.../Requests/NewScheduleSegment.cs | 15 +
MiniTwitch.Helix/Requests/NewSubscription.cs | 16 +
MiniTwitch.Helix/Requests/PredictionToEnd.cs | 13 +
.../Requests/UpdatedBitsProduct.cs | 17 +
.../Requests/UpdatedCustomReward.cs | 19 +
.../Requests/UpdatedScheduleSegment.cs | 15 +
MiniTwitch.Helix/Requests/UserToBan.cs | 18 +
.../Responses/ActiveExtensions.cs | 38 +
MiniTwitch.Helix/Responses/AdSchedule.cs | 16 +
MiniTwitch.Helix/Responses/AutoModSettings.cs | 21 +
MiniTwitch.Helix/Responses/AutoModStatus.cs | 12 +
MiniTwitch.Helix/Responses/BannedUser.cs | 15 +
MiniTwitch.Helix/Responses/BannedUsers.cs | 19 +
MiniTwitch.Helix/Responses/BitsLeaderboard.cs | 24 +
MiniTwitch.Helix/Responses/BlockList.cs | 13 +
MiniTwitch.Helix/Responses/BlockedTerm.cs | 7 +
MiniTwitch.Helix/Responses/BlockedTerms.cs | 17 +
.../Responses/BroadcasterSubscriptions.cs | 32 +
MiniTwitch.Helix/Responses/Categories.cs | 13 +
MiniTwitch.Helix/Responses/ChannelEditors.cs | 13 +
.../Responses/ChannelFollowers.cs | 17 +
.../Responses/ChannelGuestStarSettings.cs | 15 +
MiniTwitch.Helix/Responses/ChannelTeams.cs | 22 +
MiniTwitch.Helix/Responses/Channels.cs | 21 +
.../Responses/ChannelsInformation.cs | 23 +
MiniTwitch.Helix/Responses/CharityCampaign.cs | 32 +
.../Responses/CharityCampaignDonations.cs | 25 +
MiniTwitch.Helix/Responses/ChatBadges.cs | 23 +
MiniTwitch.Helix/Responses/ChatSettings.cs | 20 +
MiniTwitch.Helix/Responses/Chatters.cs | 16 +
MiniTwitch.Helix/Responses/Cheermotes.cs | 32 +
MiniTwitch.Helix/Responses/Clip.cs | 12 +
MiniTwitch.Helix/Responses/Clips.cs | 27 +
MiniTwitch.Helix/Responses/Commercial.cs | 13 +
.../Responses/ContentClassificationLabels.cs | 13 +
.../Responses/CreatedSubscription.cs | 34 +
MiniTwitch.Helix/Responses/CreatorGoals.cs | 19 +
MiniTwitch.Helix/Responses/CustomReward.cs | 51 +
.../Responses/CustomRewardRedemptions.cs | 36 +
.../Responses/DropsEntitlements.cs | 17 +
MiniTwitch.Helix/Responses/EmoteSets.cs | 28 +
MiniTwitch.Helix/Responses/Emotes.cs | 28 +
.../Responses/EventSubSubscriptions.cs | 35 +
.../Responses/ExtensionAnalytics.cs | 18 +
.../Responses/ExtensionBitsProducts.cs | 21 +
.../ExtensionConfigurationSegment.cs | 13 +
.../Responses/ExtensionLiveChannels.cs | 15 +
.../Responses/ExtensionSecrets.cs | 18 +
.../Responses/ExtensionTransactions.cs | 33 +
MiniTwitch.Helix/Responses/Extensions.cs | 76 +
.../Responses/FollowedChannels.cs | 17 +
MiniTwitch.Helix/Responses/FollowedStreams.cs | 21 +
MiniTwitch.Helix/Responses/GameAnalytics.cs | 18 +
MiniTwitch.Helix/Responses/Games.cs | 18 +
.../Responses/GuestStarInvites.cs | 18 +
.../Responses/GuestStarSession.cs | 36 +
MiniTwitch.Helix/Responses/HypeTrainEvents.cs | 35 +
MiniTwitch.Helix/Responses/Moderators.cs | 13 +
MiniTwitch.Helix/Responses/Poll.cs | 29 +
MiniTwitch.Helix/Responses/Polls.cs | 7 +
MiniTwitch.Helix/Responses/Prediction.cs | 31 +
MiniTwitch.Helix/Responses/Predictions.cs | 7 +
MiniTwitch.Helix/Responses/Raid.cs | 12 +
.../Responses/ReleasedExtensions.cs | 7 +
MiniTwitch.Helix/Responses/ScheduleSegment.cs | 37 +
.../Responses/ShieldModeStatus.cs | 15 +
MiniTwitch.Helix/Responses/SnoozedAd.cs | 13 +
MiniTwitch.Helix/Responses/StreamKey.cs | 11 +
MiniTwitch.Helix/Responses/StreamMarker.cs | 14 +
MiniTwitch.Helix/Responses/StreamMarkers.cs | 27 +
MiniTwitch.Helix/Responses/StreamSchedule.cs | 37 +
MiniTwitch.Helix/Responses/Streams.cs | 25 +
MiniTwitch.Helix/Responses/Teams.cs | 25 +
.../Responses/UpdatedDropsEntitlements.cs | 12 +
.../Responses/UpdatedScheduleSegment.cs | 38 +
MiniTwitch.Helix/Responses/UpdatedUser.cs | 20 +
MiniTwitch.Helix/Responses/UserExtensions.cs | 15 +
.../Responses/UserSubscription.cs | 15 +
MiniTwitch.Helix/Responses/Users.cs | 24 +
MiniTwitch.Helix/Responses/UsersChatColor.cs | 18 +
MiniTwitch.Helix/Responses/VIPs.cs | 13 +
MiniTwitch.Helix/Responses/Videos.cs | 31 +
MiniTwitch.Helix/SortedHelixWrapper.cs | 71 +
.../CompilerFeatureRequiredAttribute.cs | 33 +
.../RequiredMemberAttribute.cs | 8 +
MiniTwitch.sln | 6 +
README.md | 98 +
170 files changed, 9600 insertions(+)
create mode 100644 .github/workflows/build-helix.yml
create mode 100644 MiniTwitch.Helix/Enums/AnalyticsType.cs
create mode 100644 MiniTwitch.Helix/Enums/AnnouncementColor.cs
create mode 100644 MiniTwitch.Helix/Enums/BitsLeaderboardPeriod.cs
create mode 100644 MiniTwitch.Helix/Enums/ChatColor.cs
create mode 100644 MiniTwitch.Helix/Enums/ConfigSegmentType.cs
create mode 100644 MiniTwitch.Helix/Enums/ContentLabelid.cs
create mode 100644 MiniTwitch.Helix/Enums/EventSubStatus.cs
create mode 100644 MiniTwitch.Helix/Enums/FulfillmentStatus.cs
create mode 100644 MiniTwitch.Helix/Enums/LabelLocale.cs
create mode 100644 MiniTwitch.Helix/Enums/RewardRedemptionStatus.cs
create mode 100644 MiniTwitch.Helix/Enums/SortMethod.cs
create mode 100644 MiniTwitch.Helix/Enums/StreamTypes.cs
create mode 100644 MiniTwitch.Helix/Enums/VideoPeriod.cs
create mode 100644 MiniTwitch.Helix/Enums/VideoSortMethod.cs
create mode 100644 MiniTwitch.Helix/Enums/VideoType.cs
create mode 100644 MiniTwitch.Helix/HelixWrapper.cs
create mode 100644 MiniTwitch.Helix/Interfaces/IHelixResult.cs
create mode 100644 MiniTwitch.Helix/Interfaces/IPaginable.cs
create mode 100644 MiniTwitch.Helix/Internal/HelixApiClient.cs
create mode 100644 MiniTwitch.Helix/Internal/HelixResultFactory.cs
create mode 100644 MiniTwitch.Helix/Internal/Json/EnumToString.cs
create mode 100644 MiniTwitch.Helix/Internal/Json/ICaseConverter.cs
create mode 100644 MiniTwitch.Helix/Internal/Json/IntToString.cs
create mode 100644 MiniTwitch.Helix/Internal/Json/LongToString.cs
create mode 100644 MiniTwitch.Helix/Internal/Json/SnakeCase.cs
create mode 100644 MiniTwitch.Helix/Internal/Json/SnakeCaseNamingPolicy.cs
create mode 100644 MiniTwitch.Helix/Internal/Json/TimeSpanToSeconds.cs
create mode 100644 MiniTwitch.Helix/Internal/Models/Endpoints.cs
create mode 100644 MiniTwitch.Helix/Internal/Models/HelixEndpoint.cs
create mode 100644 MiniTwitch.Helix/Internal/Models/HelixTask.cs
create mode 100644 MiniTwitch.Helix/Internal/Models/InvalidToken.cs
create mode 100644 MiniTwitch.Helix/Internal/Models/QueryParams.cs
create mode 100644 MiniTwitch.Helix/Internal/Models/RequestData.cs
create mode 100644 MiniTwitch.Helix/Internal/Models/ValidToken.cs
create mode 100644 MiniTwitch.Helix/MiniTwitch.Helix.csproj
create mode 100644 MiniTwitch.Helix/Models/AllCategories.cs
create mode 100644 MiniTwitch.Helix/Models/AnalyticsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/BaseResponse.cs
create mode 100644 MiniTwitch.Helix/Models/BitsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/ChannelPointsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/ChannelsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/CharityCategory.cs
create mode 100644 MiniTwitch.Helix/Models/ChatCategory.cs
create mode 100644 MiniTwitch.Helix/Models/ClipsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/ContentClassificationLabel.cs
create mode 100644 MiniTwitch.Helix/Models/EntitlementsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/EventsubCategory.cs
create mode 100644 MiniTwitch.Helix/Models/ExtensionsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/GamesCategory.cs
create mode 100644 MiniTwitch.Helix/Models/GuestStarCategory.cs
create mode 100644 MiniTwitch.Helix/Models/HelixResult.cs
create mode 100644 MiniTwitch.Helix/Models/InvalidTokenException.cs
create mode 100644 MiniTwitch.Helix/Models/ModerationCategory.cs
create mode 100644 MiniTwitch.Helix/Models/PaginableResponse.cs
create mode 100644 MiniTwitch.Helix/Models/Pagination.cs
create mode 100644 MiniTwitch.Helix/Models/PollsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/PredictionsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/RaidsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/RequestRatelimit.cs
create mode 100644 MiniTwitch.Helix/Models/ScheduleCategory.cs
create mode 100644 MiniTwitch.Helix/Models/SearchCategory.cs
create mode 100644 MiniTwitch.Helix/Models/SingleResponse.cs
create mode 100644 MiniTwitch.Helix/Models/StreamsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/SubscriptionsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/TeamsCategory.cs
create mode 100644 MiniTwitch.Helix/Models/UsersCategory.cs
create mode 100644 MiniTwitch.Helix/Models/VideosCategory.cs
create mode 100644 MiniTwitch.Helix/README.md
create mode 100644 MiniTwitch.Helix/Requests/Announcement.cs
create mode 100644 MiniTwitch.Helix/Requests/ConfigurationSegment.cs
create mode 100644 MiniTwitch.Helix/Requests/ExtensionChatMessage.cs
create mode 100644 MiniTwitch.Helix/Requests/ExtensionPubSubMessage.cs
create mode 100644 MiniTwitch.Helix/Requests/ExtensionRequiredConfiguration.cs
create mode 100644 MiniTwitch.Helix/Requests/MessageToCheck.cs
create mode 100644 MiniTwitch.Helix/Requests/NewAutoModSettings.cs
create mode 100644 MiniTwitch.Helix/Requests/NewChannelInformation.cs
create mode 100644 MiniTwitch.Helix/Requests/NewChatSettings.cs
create mode 100644 MiniTwitch.Helix/Requests/NewCommercial.cs
create mode 100644 MiniTwitch.Helix/Requests/NewCustomReward.cs
create mode 100644 MiniTwitch.Helix/Requests/NewGuestStarSettings.cs
create mode 100644 MiniTwitch.Helix/Requests/NewPoll.cs
create mode 100644 MiniTwitch.Helix/Requests/NewPrediction.cs
create mode 100644 MiniTwitch.Helix/Requests/NewScheduleSegment.cs
create mode 100644 MiniTwitch.Helix/Requests/NewSubscription.cs
create mode 100644 MiniTwitch.Helix/Requests/PredictionToEnd.cs
create mode 100644 MiniTwitch.Helix/Requests/UpdatedBitsProduct.cs
create mode 100644 MiniTwitch.Helix/Requests/UpdatedCustomReward.cs
create mode 100644 MiniTwitch.Helix/Requests/UpdatedScheduleSegment.cs
create mode 100644 MiniTwitch.Helix/Requests/UserToBan.cs
create mode 100644 MiniTwitch.Helix/Responses/ActiveExtensions.cs
create mode 100644 MiniTwitch.Helix/Responses/AdSchedule.cs
create mode 100644 MiniTwitch.Helix/Responses/AutoModSettings.cs
create mode 100644 MiniTwitch.Helix/Responses/AutoModStatus.cs
create mode 100644 MiniTwitch.Helix/Responses/BannedUser.cs
create mode 100644 MiniTwitch.Helix/Responses/BannedUsers.cs
create mode 100644 MiniTwitch.Helix/Responses/BitsLeaderboard.cs
create mode 100644 MiniTwitch.Helix/Responses/BlockList.cs
create mode 100644 MiniTwitch.Helix/Responses/BlockedTerm.cs
create mode 100644 MiniTwitch.Helix/Responses/BlockedTerms.cs
create mode 100644 MiniTwitch.Helix/Responses/BroadcasterSubscriptions.cs
create mode 100644 MiniTwitch.Helix/Responses/Categories.cs
create mode 100644 MiniTwitch.Helix/Responses/ChannelEditors.cs
create mode 100644 MiniTwitch.Helix/Responses/ChannelFollowers.cs
create mode 100644 MiniTwitch.Helix/Responses/ChannelGuestStarSettings.cs
create mode 100644 MiniTwitch.Helix/Responses/ChannelTeams.cs
create mode 100644 MiniTwitch.Helix/Responses/Channels.cs
create mode 100644 MiniTwitch.Helix/Responses/ChannelsInformation.cs
create mode 100644 MiniTwitch.Helix/Responses/CharityCampaign.cs
create mode 100644 MiniTwitch.Helix/Responses/CharityCampaignDonations.cs
create mode 100644 MiniTwitch.Helix/Responses/ChatBadges.cs
create mode 100644 MiniTwitch.Helix/Responses/ChatSettings.cs
create mode 100644 MiniTwitch.Helix/Responses/Chatters.cs
create mode 100644 MiniTwitch.Helix/Responses/Cheermotes.cs
create mode 100644 MiniTwitch.Helix/Responses/Clip.cs
create mode 100644 MiniTwitch.Helix/Responses/Clips.cs
create mode 100644 MiniTwitch.Helix/Responses/Commercial.cs
create mode 100644 MiniTwitch.Helix/Responses/ContentClassificationLabels.cs
create mode 100644 MiniTwitch.Helix/Responses/CreatedSubscription.cs
create mode 100644 MiniTwitch.Helix/Responses/CreatorGoals.cs
create mode 100644 MiniTwitch.Helix/Responses/CustomReward.cs
create mode 100644 MiniTwitch.Helix/Responses/CustomRewardRedemptions.cs
create mode 100644 MiniTwitch.Helix/Responses/DropsEntitlements.cs
create mode 100644 MiniTwitch.Helix/Responses/EmoteSets.cs
create mode 100644 MiniTwitch.Helix/Responses/Emotes.cs
create mode 100644 MiniTwitch.Helix/Responses/EventSubSubscriptions.cs
create mode 100644 MiniTwitch.Helix/Responses/ExtensionAnalytics.cs
create mode 100644 MiniTwitch.Helix/Responses/ExtensionBitsProducts.cs
create mode 100644 MiniTwitch.Helix/Responses/ExtensionConfigurationSegment.cs
create mode 100644 MiniTwitch.Helix/Responses/ExtensionLiveChannels.cs
create mode 100644 MiniTwitch.Helix/Responses/ExtensionSecrets.cs
create mode 100644 MiniTwitch.Helix/Responses/ExtensionTransactions.cs
create mode 100644 MiniTwitch.Helix/Responses/Extensions.cs
create mode 100644 MiniTwitch.Helix/Responses/FollowedChannels.cs
create mode 100644 MiniTwitch.Helix/Responses/FollowedStreams.cs
create mode 100644 MiniTwitch.Helix/Responses/GameAnalytics.cs
create mode 100644 MiniTwitch.Helix/Responses/Games.cs
create mode 100644 MiniTwitch.Helix/Responses/GuestStarInvites.cs
create mode 100644 MiniTwitch.Helix/Responses/GuestStarSession.cs
create mode 100644 MiniTwitch.Helix/Responses/HypeTrainEvents.cs
create mode 100644 MiniTwitch.Helix/Responses/Moderators.cs
create mode 100644 MiniTwitch.Helix/Responses/Poll.cs
create mode 100644 MiniTwitch.Helix/Responses/Polls.cs
create mode 100644 MiniTwitch.Helix/Responses/Prediction.cs
create mode 100644 MiniTwitch.Helix/Responses/Predictions.cs
create mode 100644 MiniTwitch.Helix/Responses/Raid.cs
create mode 100644 MiniTwitch.Helix/Responses/ReleasedExtensions.cs
create mode 100644 MiniTwitch.Helix/Responses/ScheduleSegment.cs
create mode 100644 MiniTwitch.Helix/Responses/ShieldModeStatus.cs
create mode 100644 MiniTwitch.Helix/Responses/SnoozedAd.cs
create mode 100644 MiniTwitch.Helix/Responses/StreamKey.cs
create mode 100644 MiniTwitch.Helix/Responses/StreamMarker.cs
create mode 100644 MiniTwitch.Helix/Responses/StreamMarkers.cs
create mode 100644 MiniTwitch.Helix/Responses/StreamSchedule.cs
create mode 100644 MiniTwitch.Helix/Responses/Streams.cs
create mode 100644 MiniTwitch.Helix/Responses/Teams.cs
create mode 100644 MiniTwitch.Helix/Responses/UpdatedDropsEntitlements.cs
create mode 100644 MiniTwitch.Helix/Responses/UpdatedScheduleSegment.cs
create mode 100644 MiniTwitch.Helix/Responses/UpdatedUser.cs
create mode 100644 MiniTwitch.Helix/Responses/UserExtensions.cs
create mode 100644 MiniTwitch.Helix/Responses/UserSubscription.cs
create mode 100644 MiniTwitch.Helix/Responses/Users.cs
create mode 100644 MiniTwitch.Helix/Responses/UsersChatColor.cs
create mode 100644 MiniTwitch.Helix/Responses/VIPs.cs
create mode 100644 MiniTwitch.Helix/Responses/Videos.cs
create mode 100644 MiniTwitch.Helix/SortedHelixWrapper.cs
create mode 100644 MiniTwitch.Helix/net6-compatibility/CompilerFeatureRequiredAttribute.cs
create mode 100644 MiniTwitch.Helix/net6-compatibility/RequiredMemberAttribute.cs
diff --git a/.github/workflows/build-helix.yml b/.github/workflows/build-helix.yml
new file mode 100644
index 0000000..410a888
--- /dev/null
+++ b/.github/workflows/build-helix.yml
@@ -0,0 +1,30 @@
+name: Build (Helix)
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+
+jobs:
+
+ build:
+
+ runs-on: windows-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Install .NET 6
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 6.0.x
+
+ - name: Build
+ run: |
+ cd .\MiniTwitch.Helix\
+ dotnet build -v d -c Release
+
\ No newline at end of file
diff --git a/MiniTwitch.Helix/Enums/AnalyticsType.cs b/MiniTwitch.Helix/Enums/AnalyticsType.cs
new file mode 100644
index 0000000..6e0c855
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/AnalyticsType.cs
@@ -0,0 +1,6 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum AnalyticsType
+{
+ OverView_V2
+}
diff --git a/MiniTwitch.Helix/Enums/AnnouncementColor.cs b/MiniTwitch.Helix/Enums/AnnouncementColor.cs
new file mode 100644
index 0000000..8c9620d
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/AnnouncementColor.cs
@@ -0,0 +1,10 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum AnnouncementColor
+{
+ Primary,
+ Blue,
+ Green,
+ Orange,
+ Purple
+}
\ No newline at end of file
diff --git a/MiniTwitch.Helix/Enums/BitsLeaderboardPeriod.cs b/MiniTwitch.Helix/Enums/BitsLeaderboardPeriod.cs
new file mode 100644
index 0000000..6fbe351
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/BitsLeaderboardPeriod.cs
@@ -0,0 +1,10 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum BitsLeaderboardPeriod
+{
+ Day,
+ Week,
+ Month,
+ Year,
+ All
+}
diff --git a/MiniTwitch.Helix/Enums/ChatColor.cs b/MiniTwitch.Helix/Enums/ChatColor.cs
new file mode 100644
index 0000000..1ae31b0
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/ChatColor.cs
@@ -0,0 +1,20 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum ChatColor
+{
+ Blue,
+ BlueViolet,
+ CadetBlue,
+ Chocolate,
+ Coral,
+ DodgerBlue,
+ Firebrick,
+ GoldenRod,
+ Green,
+ HotPink,
+ OrangeRed,
+ Red,
+ SeaGreen,
+ SpringGreen,
+ YellowGreen
+}
diff --git a/MiniTwitch.Helix/Enums/ConfigSegmentType.cs b/MiniTwitch.Helix/Enums/ConfigSegmentType.cs
new file mode 100644
index 0000000..0b60f1c
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/ConfigSegmentType.cs
@@ -0,0 +1,8 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum ConfigSegmentType
+{
+ Broadcaster,
+ Developer,
+ Global
+}
diff --git a/MiniTwitch.Helix/Enums/ContentLabelid.cs b/MiniTwitch.Helix/Enums/ContentLabelid.cs
new file mode 100644
index 0000000..2d041db
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/ContentLabelid.cs
@@ -0,0 +1,10 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum ContentLabelid
+{
+ DrugsIntoxication,
+ SexualThemes,
+ ViolentGraphic,
+ Gambling,
+ ProfanityVulgarity
+}
diff --git a/MiniTwitch.Helix/Enums/EventSubStatus.cs b/MiniTwitch.Helix/Enums/EventSubStatus.cs
new file mode 100644
index 0000000..0ccac06
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/EventSubStatus.cs
@@ -0,0 +1,20 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum EventSubStatus
+{
+ Enabled,
+ WebhookCallbackVerificationPending,
+ WebhookCallbackVerificationFailed,
+ NotificationFailuresExceeded,
+ AuthorizationRevoked,
+ ModeratorRemoved,
+ UserRemoved,
+ VersionRemoved,
+ WebsocketDisconnected,
+ WebsocketFailedPingPong,
+ WebsocketReceivedInboundTraffic,
+ WebsocketConnectionUnused,
+ WebsocketInternalError,
+ WebsocketNetworkTimeout,
+ WebsocketNetworkError
+}
diff --git a/MiniTwitch.Helix/Enums/FulfillmentStatus.cs b/MiniTwitch.Helix/Enums/FulfillmentStatus.cs
new file mode 100644
index 0000000..f749027
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/FulfillmentStatus.cs
@@ -0,0 +1,7 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum FulfillmentStatus
+{
+ CLAIMED,
+ FULFILLED
+}
diff --git a/MiniTwitch.Helix/Enums/LabelLocale.cs b/MiniTwitch.Helix/Enums/LabelLocale.cs
new file mode 100644
index 0000000..94b970b
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/LabelLocale.cs
@@ -0,0 +1,34 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum LabelLocale
+{
+ bg_BG,
+ cs_CZ,
+ da_DK,
+ de_DE,
+ el_GR,
+ en_GB,
+ en_US,
+ es_ES,
+ es_MX,
+ fi_FI,
+ fr_FR,
+ hu_HU,
+ it_IT,
+ ja_JP,
+ ko_KR,
+ nl_NL,
+ no_NO,
+ pl_PL,
+ pt_BT,
+ pt_PT,
+ ro_RO,
+ ru_RU,
+ sk_SK,
+ sv_SE,
+ th_TH,
+ tr_TR,
+ vi_VN,
+ zh_CN,
+ zh_TW
+}
diff --git a/MiniTwitch.Helix/Enums/RewardRedemptionStatus.cs b/MiniTwitch.Helix/Enums/RewardRedemptionStatus.cs
new file mode 100644
index 0000000..c477e27
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/RewardRedemptionStatus.cs
@@ -0,0 +1,8 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum RewardRedemptionStatus
+{
+ CANCELED,
+ FULFILLED,
+ UNFULFILLED
+}
\ No newline at end of file
diff --git a/MiniTwitch.Helix/Enums/SortMethod.cs b/MiniTwitch.Helix/Enums/SortMethod.cs
new file mode 100644
index 0000000..5034a7f
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/SortMethod.cs
@@ -0,0 +1,7 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum SortMethod
+{
+ OLDEST,
+ NEWEST
+}
diff --git a/MiniTwitch.Helix/Enums/StreamTypes.cs b/MiniTwitch.Helix/Enums/StreamTypes.cs
new file mode 100644
index 0000000..f22503f
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/StreamTypes.cs
@@ -0,0 +1,7 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum StreamTypes
+{
+ All,
+ Live
+}
diff --git a/MiniTwitch.Helix/Enums/VideoPeriod.cs b/MiniTwitch.Helix/Enums/VideoPeriod.cs
new file mode 100644
index 0000000..49b4793
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/VideoPeriod.cs
@@ -0,0 +1,9 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum VideoPeriod
+{
+ All,
+ Day,
+ Month,
+ Week
+}
diff --git a/MiniTwitch.Helix/Enums/VideoSortMethod.cs b/MiniTwitch.Helix/Enums/VideoSortMethod.cs
new file mode 100644
index 0000000..2ac7c98
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/VideoSortMethod.cs
@@ -0,0 +1,8 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum VideoSortMethod
+{
+ Time,
+ Trending,
+ Views
+}
diff --git a/MiniTwitch.Helix/Enums/VideoType.cs b/MiniTwitch.Helix/Enums/VideoType.cs
new file mode 100644
index 0000000..8d9af85
--- /dev/null
+++ b/MiniTwitch.Helix/Enums/VideoType.cs
@@ -0,0 +1,9 @@
+namespace MiniTwitch.Helix.Enums;
+
+public enum VideoType
+{
+ All,
+ Archive,
+ Highlight,
+ Upload
+}
diff --git a/MiniTwitch.Helix/HelixWrapper.cs b/MiniTwitch.Helix/HelixWrapper.cs
new file mode 100644
index 0000000..ba38e78
--- /dev/null
+++ b/MiniTwitch.Helix/HelixWrapper.cs
@@ -0,0 +1,984 @@
+using Microsoft.Extensions.Logging;
+using MiniTwitch.Common;
+using MiniTwitch.Helix.Enums;
+using MiniTwitch.Helix.Internal;
+using MiniTwitch.Helix.Models;
+using MiniTwitch.Helix.Requests;
+using MiniTwitch.Helix.Responses;
+
+namespace MiniTwitch.Helix;
+
+///
+/// Wraps all Helix endpoints and exposes them directly as methods.
+///
+public class HelixWrapper
+{
+ ///
+ /// The default logger for , only used when is not provided in the constructor
+ /// Can be toggled with
+ ///
+ public DefaultMiniTwitchLogger DefaultLogger => _all.ApiClient.Logger;
+
+ private readonly AllCategories _all;
+
+ public HelixWrapper(string bearerToken, string clientId, ILogger? logger = null,
+ string helixBaseUrl = "https://api.twitch.tv/helix", string tokenValidationUrl = "https://id.twitch.tv/oauth2/validate")
+ {
+ _all = new(new HelixApiClient(bearerToken, clientId, logger, tokenValidationUrl), helixBaseUrl);
+ }
+
+ public Task> StartCommercial(
+ NewCommercial body,
+ CancellationToken cancellationToken = default)
+ => _all.StartCommercial(body, cancellationToken);
+
+ public Task> GetExtensionAnalytics(
+ string? extensionId = null,
+ AnalyticsType? type = null,
+ DateTime? startedAt = null,
+ DateTime? endedAt = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetExtensionAnalytics(extensionId, type, startedAt, endedAt, first, cancellationToken);
+
+ public Task> GetGameAnalytics(
+ string? gameId = null,
+ AnalyticsType? type = null,
+ DateTime? startedAt = null,
+ DateTime? endedAt = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetGameAnalytics(gameId, type, startedAt, endedAt, first, cancellationToken);
+
+ public Task> GetBitsLeaderboard(
+ int? count = null,
+ BitsLeaderboardPeriod? period = null,
+ DateTime? startedAt = null,
+ long? UserId = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetBitsLeaderboard(count, period, startedAt, UserId, cancellationToken);
+
+ public Task> GetCheermotes(
+ long? broadcasterId = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetCheermotes(broadcasterId, cancellationToken);
+
+ public Task> GetExtensionTransactions(
+ string extensionId,
+ string? id = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetExtensionTransactions(extensionId, id, first, cancellationToken);
+
+ public Task> GetExtensionTransactions(
+ string extensionId,
+ IEnumerable? ids = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetExtensionTransactions(extensionId, ids, first, cancellationToken);
+
+ public Task> GetChannelInformation(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.GetChannelInformation(broadcasterId, cancellationToken);
+
+ public Task> GetChannelInformation(
+ IEnumerable broadcasterIds,
+ CancellationToken cancellationToken = default)
+ => _all.GetChannelInformation(broadcasterIds, cancellationToken);
+
+ public Task ModifyChannelInformation(
+ long broadcasterId,
+ NewChannelInformation body,
+ CancellationToken cancellationToken = default)
+ => _all.ModifyChannelInformation(broadcasterId, body, cancellationToken);
+
+ public Task> GetChannelEditors(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.GetChannelEditors(broadcasterId, cancellationToken);
+
+ public Task> GetFollowedChannels(
+ long userId,
+ long? broadcasterId = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetFollowedChannels(userId, broadcasterId, first, cancellationToken);
+
+ public Task> GetChannelFollowers(
+ long broadcasterId,
+ long? userId = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetChannelFollowers(broadcasterId, userId, first, cancellationToken);
+
+ public Task> CreateCustomReward(
+ long broadcasterId,
+ NewCustomReward body,
+ CancellationToken cancellationToken = default)
+ => _all.CreateCustomReward(broadcasterId, body, cancellationToken);
+
+ public Task DeleteCustomReward(
+ long broadcasterId,
+ string id,
+ CancellationToken cancellationToken = default)
+ => _all.DeleteCustomReward(broadcasterId, id, cancellationToken);
+
+ public Task> GetCustomReward(
+ long broadcasterId,
+ string? id = null,
+ bool onlyManageableRewards = false,
+ CancellationToken cancellationToken = default)
+ => _all.GetCustomReward(broadcasterId, id, onlyManageableRewards, cancellationToken);
+
+ public Task> GetCustomReward(
+ long broadcasterId,
+ IEnumerable? ids = null,
+ bool onlyManageableRewards = false,
+ CancellationToken cancellationToken = default)
+ => _all.GetCustomReward(broadcasterId, ids, onlyManageableRewards, cancellationToken);
+
+ public Task> GetCustomRewardRedemption(
+ long broadcasterId,
+ string rewardId,
+ RewardRedemptionStatus status,
+ string? id = null,
+ SortMethod? sort = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetCustomRewardRedemption(broadcasterId, rewardId, status, id, sort, first, cancellationToken);
+
+ public Task> GetCustomRewardRedemption(
+ long broadcasterId,
+ string rewardId,
+ RewardRedemptionStatus status,
+ IEnumerable? ids = null,
+ SortMethod? sort = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetCustomRewardRedemption(broadcasterId, rewardId, status, ids, sort, first, cancellationToken);
+
+ public Task> UpdateCustomReward(
+ long broadcasterId,
+ string id,
+ UpdatedCustomReward body,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateCustomReward(broadcasterId, id, body, cancellationToken);
+
+ public Task> UpdateRedemptionStatus(
+ long broadcasterId,
+ string id,
+ string rewardId,
+ RewardRedemptionStatus status,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateRedemptionStatus(broadcasterId, id, rewardId, status, cancellationToken);
+
+ public Task> UpdateRedemptionStatus(
+ long broadcasterId,
+ IEnumerable ids,
+ string rewardId,
+ RewardRedemptionStatus status,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateRedemptionStatus(broadcasterId, ids, rewardId, status, cancellationToken);
+
+ public Task> GetCharityCampaign(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.GetCharityCampaign(broadcasterId, cancellationToken);
+
+ public Task> GetCharityCampaignDonations(
+ long broadcasterId,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetCharityCampaignDonations(broadcasterId, first, cancellationToken);
+
+ public Task> GetChatters(
+ long broadcasterId,
+ long moderatorId,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetChatters(broadcasterId, moderatorId, first, cancellationToken);
+
+ public Task> GetChannelEmotes(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.GetChannelEmotes(broadcasterId, cancellationToken);
+
+ public Task> GetGlobalEmotes(
+ CancellationToken cancellationToken = default)
+ => _all.GetGlobalEmotes(cancellationToken);
+
+ public Task> GetEmoteSets(
+ string emoteSetId,
+ CancellationToken cancellationToken = default)
+ => _all.GetEmoteSets(emoteSetId, cancellationToken);
+
+ public Task> GetEmoteSets(
+ IEnumerable emoteSetIds,
+ CancellationToken cancellationToken = default)
+ => _all.GetEmoteSets(emoteSetIds, cancellationToken);
+
+ public Task> GetChatSettings(
+ long broadcasterId,
+ long? moderatorId = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetChatSettings(broadcasterId, moderatorId, cancellationToken);
+
+ public Task> UpdateChatSettings(
+ long broadcasterId,
+ long moderatorId,
+ NewChatSettings body,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateChatSettings(broadcasterId, moderatorId, body, cancellationToken);
+
+ public Task> GetUserBlockList(
+ long broadcasterId,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetUserBlockList(broadcasterId, first, cancellationToken);
+
+ public Task SendChatAnnouncement(
+ long broadcasterId,
+ long moderatorId,
+ Announcement body,
+ CancellationToken cancellationToken = default)
+ => _all.SendChatAnnouncement(broadcasterId, moderatorId, body, cancellationToken);
+
+ public Task SendAShoutout(
+ long fromBroadcasterId,
+ long toBroadcasterId,
+ long moderatorId,
+ CancellationToken cancellationToken = default)
+ => _all.SendAShoutout(fromBroadcasterId, toBroadcasterId, moderatorId, cancellationToken);
+
+ public Task> GetUserChatColor(
+ long userId,
+ CancellationToken cancellationToken = default)
+ => _all.GetUserChatColor(userId, cancellationToken);
+
+ public Task> GetUserChatColor(
+ IEnumerable userIds,
+ CancellationToken cancellationToken = default)
+ => _all.GetUserChatColor(userIds, cancellationToken);
+
+ public Task UpdateUserChatColor(
+ long userId,
+ ChatColor color,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateUserChatColor(userId, color, cancellationToken);
+
+ public Task UpdateUserChatColor(
+ long userId,
+ string hexColor,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateUserChatColor(userId, hexColor, cancellationToken);
+
+ public Task> CreateClip(
+ long broadcasterId,
+ bool? hasDelay = null,
+ CancellationToken cancellationToken = default)
+ => _all.CreateClip(broadcasterId, hasDelay, cancellationToken);
+
+ public Task> GetClips(
+ long broadcasterId,
+ long gameId,
+ string id,
+ DateTime? startedAt = null,
+ DateTime? endedAt = null,
+ int? first = null,
+ bool? isFeatured = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetClips(broadcasterId, gameId, id, startedAt, endedAt, first, isFeatured, cancellationToken);
+
+ public Task> GetClips(
+ long broadcasterId,
+ long gameId,
+ IEnumerable ids,
+ DateTime? startedAt = null,
+ DateTime? endedAt = null,
+ int? first = null,
+ bool? isFeatured = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetClips(broadcasterId, gameId, ids, startedAt, endedAt, first, isFeatured, cancellationToken);
+
+ public Task> GetContentClassificationLabels(
+ LabelLocale? locale = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetContentClassificationLabels(locale, cancellationToken);
+
+ public Task> GetDropsEntitlements(
+ string? id = null,
+ long? userId = null,
+ string? gameId = null,
+ FulfillmentStatus? fulfillmentStatus = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetDropsEntitlements(id, userId, gameId, fulfillmentStatus, first, cancellationToken);
+
+ public Task> GetDropsEntitlements(
+ IEnumerable? ids = null,
+ long? userId = null,
+ string? gameId = null,
+ FulfillmentStatus? fulfillmentStatus = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetDropsEntitlements(ids, userId, gameId, fulfillmentStatus, first, cancellationToken);
+
+ public Task> UpdateDropsEntitlements(
+ IEnumerable? entitlementIds = null,
+ FulfillmentStatus? fulfillmentStatus = null,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateDropsEntitlements(entitlementIds, fulfillmentStatus, cancellationToken);
+
+ public Task> GetExtensionConfigurationSegment(
+ string extensionId,
+ ConfigSegmentType segment,
+ long? broadcasterId = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetExtensionConfigurationSegment(extensionId, segment, broadcasterId, cancellationToken);
+
+ public Task> GetExtensionConfigurationSegment(
+ string extensionId,
+ IEnumerable segments,
+ long? broadcasterId = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetExtensionConfigurationSegment(extensionId, segments, broadcasterId, cancellationToken);
+
+ public Task SetExtensionConfigurationSegment(
+ ConfigurationSegment body,
+ CancellationToken cancellationToken = default)
+ => _all.SetExtensionConfigurationSegment(body, cancellationToken);
+
+ public Task SetExtensionRequiredConfiguration(
+ long broadcasterId,
+ ExtensionRequiredConfiguration body,
+ CancellationToken cancellationToken = default)
+ => _all.SetExtensionRequiredConfiguration(broadcasterId, body, cancellationToken);
+
+ public Task SendExtensionPubSubMessage(
+ ExtensionPubSubMessage body,
+ CancellationToken cancellationToken = default)
+ => _all.SendExtensionPubSubMessage(body, cancellationToken);
+
+ public Task> GetExtensionLiveChannels(
+ string extensionId,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetExtensionLiveChannels(extensionId, first, cancellationToken);
+
+ public Task> GetExtensionSecrets(
+ string extensionId,
+ CancellationToken cancellationToken = default)
+ => _all.GetExtensionSecrets(extensionId, cancellationToken);
+
+ public Task> CreateExtensionSecret(
+ string extensionId,
+ int? delay = null,
+ CancellationToken cancellationToken = default)
+ => _all.CreateExtensionSecret(extensionId, delay, cancellationToken);
+
+ public Task SendExtensionChatMessage(
+ long broadcasterId,
+ ExtensionChatMessage body,
+ CancellationToken cancellationToken = default)
+ => _all.SendExtensionChatMessage(broadcasterId, body, cancellationToken);
+
+ public Task> GetExtensions(
+ string extensionId,
+ string? extensionVersion = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetExtensions(extensionId, extensionVersion, cancellationToken);
+
+ public Task> GetReleasedExtensions(
+ string extensionId,
+ string? extensionVersion = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetReleasedExtensions(extensionId, extensionVersion, cancellationToken);
+
+ public Task> GetExtensionBitsProducts(
+ bool? shouldIncludeAll = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetExtensionBitsProducts(shouldIncludeAll, cancellationToken);
+
+ public Task> UpdateExtensionBitsProduct(
+ UpdatedBitsProduct body,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateExtensionBitsProduct(body, cancellationToken);
+
+ public Task> CreateEventSubSubscription(
+ NewSubscription body,
+ CancellationToken cancellationToken = default)
+ => _all.CreateEventSubSubscription(body, cancellationToken);
+
+ public Task DeleteEventSubSubscription(
+ string id,
+ CancellationToken cancellationToken = default)
+ => _all.DeleteEventSubSubscription(id, cancellationToken);
+
+ public Task> GetEventSubSubscriptions(
+ EventSubStatus? status = null,
+ string? type = null,
+ long? userId = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetEventSubSubscriptions(status, type, userId, cancellationToken);
+
+ public Task> GetTopGames(
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetTopGames(first, cancellationToken);
+
+ public Task> GetGames(
+ string? id = null,
+ string? name = null,
+ string? igdbId = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetGames(id, name, igdbId, cancellationToken);
+
+ public Task> GetGames(
+ IEnumerable? ids = null,
+ IEnumerable? names = null,
+ IEnumerable? igdbIds = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetGames(ids, names, igdbIds, cancellationToken);
+
+ public Task> GetCreatorGoals(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.GetCreatorGoals(broadcasterId, cancellationToken);
+
+ public Task> GetChannelGuestStarSettings(
+ long broadcasterId,
+ long moderatorId,
+ CancellationToken cancellationToken = default)
+ => _all.GetChannelGuestStarSettings(broadcasterId, moderatorId, cancellationToken);
+
+ public Task UpdateChannelGuestStarSettings(
+ NewGuestStarSettings body,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateChannelGuestStarSettings(body, cancellationToken);
+
+ public Task> GetGuestStarSession(
+ long broadcasterId,
+ long moderatorId,
+ CancellationToken cancellationToken = default)
+ => _all.GetGuestStarSession(broadcasterId, moderatorId, cancellationToken);
+
+ public Task> CreateGuestStarSession(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.CreateGuestStarSession(broadcasterId, cancellationToken);
+
+ public Task> EndGuestStarSession(
+ long broadcasterId,
+ string sessionId,
+ CancellationToken cancellationToken = default)
+ => _all.EndGuestStarSession(broadcasterId, sessionId, cancellationToken);
+
+ public Task> GetGuestStarInvites(
+ long broadcasterId,
+ long moderatorId,
+ string sessionId,
+ CancellationToken cancellationToken = default)
+ => _all.GetGuestStarInvites(broadcasterId, moderatorId, sessionId, cancellationToken);
+
+ public Task SendGuestStarInvite(
+ long broadcasterId,
+ long moderatorId,
+ string sessionId,
+ long guestId,
+ CancellationToken cancellationToken = default)
+ => _all.SendGuestStarInvite(broadcasterId, moderatorId, sessionId, guestId, cancellationToken);
+
+ public Task DeleteGuestStarInvite(
+ long broadcasterId,
+ long moderatorId,
+ string sessionId,
+ long guestId,
+ CancellationToken cancellationToken = default)
+ => _all.DeleteGuestStarInvite(broadcasterId, moderatorId, sessionId, guestId, cancellationToken);
+
+ public Task AssignGuestStarSlot(
+ long broadcasterId,
+ long moderatorId,
+ string sessionId,
+ long guestId,
+ string slotId,
+ CancellationToken cancellationToken = default)
+ => _all.AssignGuestStarSlot(broadcasterId, moderatorId, sessionId, guestId, slotId, cancellationToken);
+
+ public Task UpdateGuestStarSlot(
+ long broadcasterId,
+ long moderatorId,
+ string sessionId,
+ string sourceSlotId,
+ string? destinationSlotId = null,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateGuestStarSlot(broadcasterId, moderatorId, sessionId, sourceSlotId, destinationSlotId, cancellationToken);
+
+ public Task DeleteGuestStarSlot(
+ long broadcasterId,
+ long moderatorId,
+ string sessionId,
+ long guestId,
+ string slotId,
+ string? shouldReinviteGuest = null,
+ CancellationToken cancellationToken = default)
+ => _all.DeleteGuestStarSlot(broadcasterId, moderatorId, sessionId, guestId, slotId, shouldReinviteGuest, cancellationToken);
+
+ public Task UpdateGuestStarSlotSettings(
+ long broadcasterId,
+ long moderatorId,
+ string sessionId,
+ string slotId,
+ bool? isAudioEnabled = null,
+ bool? isVideoEnabled = null,
+ bool? isLive = null,
+ int? volume = null,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateGuestStarSlotSettings(broadcasterId, moderatorId, sessionId, slotId, isAudioEnabled, isVideoEnabled, isLive, volume, cancellationToken);
+
+ public Task> GetHypeTrainEvents(
+ long broadcasterId,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetHypeTrainEvents(broadcasterId, first, cancellationToken);
+
+ public Task> CheckAutoModStatus(
+ long broadcasterId,
+ MessageToCheck body,
+ CancellationToken cancellationToken = default)
+ => _all.CheckAutoModStatus(broadcasterId, body, cancellationToken);
+
+ public Task ManageHeldAutoModMessages(
+ long userId,
+ string msgId,
+ string action,
+ CancellationToken cancellationToken = default)
+ => _all.ManageHeldAutoModMessages(userId, msgId, action, cancellationToken);
+
+ public Task> GetAutoModSettings(
+ long broadcasterId,
+ long moderatorId,
+ CancellationToken cancellationToken = default)
+ => _all.GetAutoModSettings(broadcasterId, moderatorId, cancellationToken);
+
+ public Task> UpdateAutoModSettings(
+ long broadcasterId,
+ long moderatorId,
+ NewAutoModSettings body,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateAutoModSettings(broadcasterId, moderatorId, body, cancellationToken);
+
+ public Task> GetBannedUsers(
+ long broadcasterId,
+ long? userId = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetBannedUsers(broadcasterId, userId, first, cancellationToken);
+
+ public Task> GetBannedUsers(
+ long broadcasterId,
+ IEnumerable? userIds = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetBannedUsers(broadcasterId, userIds, first, cancellationToken);
+
+ public Task> BanUser(
+ long broadcasterId,
+ long moderatorId,
+ UserToBan body,
+ CancellationToken cancellationToken = default)
+ => _all.BanUser(broadcasterId, moderatorId, body, cancellationToken);
+
+ public Task UnbanUser(
+ long broadcasterId,
+ long moderatorId,
+ long userId,
+ CancellationToken cancellationToken = default)
+ => _all.UnbanUser(broadcasterId, moderatorId, userId, cancellationToken);
+
+ public Task> GetBlockedTerms(
+ long broadcasterId,
+ long moderatorId,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetBlockedTerms(broadcasterId, moderatorId, first, cancellationToken);
+
+ public Task> AddBlockedTerm(
+ long broadcasterId,
+ long moderatorId,
+ string text,
+ CancellationToken cancellationToken = default)
+ => _all.AddBlockedTerm(broadcasterId, moderatorId, text, cancellationToken);
+
+ public Task RemoveBlockedTerm(
+ long broadcasterId,
+ long moderatorId,
+ string id,
+ CancellationToken cancellationToken = default)
+ => _all.RemoveBlockedTerm(broadcasterId, moderatorId, id, cancellationToken);
+
+ public Task DeleteChatMessages(
+ long broadcasterId,
+ long moderatorId,
+ string? messageId = null,
+ CancellationToken cancellationToken = default)
+ => _all.DeleteChatMessages(broadcasterId, moderatorId, messageId, cancellationToken);
+
+ public Task> GetModerators(
+ long broadcasterId,
+ long? userId = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetModerators(broadcasterId, userId, first, cancellationToken);
+
+ public Task> GetModerators(
+ long broadcasterId,
+ IEnumerable? userIds = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetModerators(broadcasterId, userIds, first, cancellationToken);
+
+ public Task AddChannelModerator(
+ long broadcasterId,
+ long userId,
+ CancellationToken cancellationToken = default)
+ => _all.AddChannelModerator(broadcasterId, userId, cancellationToken);
+
+ public Task RemoveChannelModerator(
+ long broadcasterId,
+ long userId,
+ CancellationToken cancellationToken = default)
+ => _all.RemoveChannelModerator(broadcasterId, userId, cancellationToken);
+
+ public Task> GetVIPs(
+ long broadcasterId,
+ long? userId = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetVIPs(broadcasterId, userId, first, cancellationToken);
+
+ public Task> GetVIPs(
+ long broadcasterId,
+ IEnumerable? userIds = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetVIPs(broadcasterId, userIds, first, cancellationToken);
+
+ public Task AddChannelVIP(
+ long broadcasterId,
+ long userId,
+ CancellationToken cancellationToken = default)
+ => _all.AddChannelVIP(broadcasterId, userId, cancellationToken);
+
+ public Task RemoveChannelVIP(
+ long broadcasterId,
+ long userId,
+ CancellationToken cancellationToken = default)
+ => _all.RemoveChannelVIP(broadcasterId, userId, cancellationToken);
+
+ public Task> UpdateShieldModeStatus(
+ long broadcasterId,
+ long moderatorId,
+ bool isActive,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateShieldModeStatus(broadcasterId, moderatorId, isActive, cancellationToken);
+
+ public Task> GetShieldModeStatus(
+ long broadcasterId,
+ long moderatorId,
+ CancellationToken cancellationToken = default)
+ => _all.GetShieldModeStatus(broadcasterId, moderatorId, cancellationToken);
+
+ public Task> GetPolls(
+ long broadcasterId,
+ string? id = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetPolls(broadcasterId, id, first, cancellationToken);
+
+ public Task> GetPolls(
+ long broadcasterId,
+ IEnumerable? ids = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetPolls(broadcasterId, ids, first, cancellationToken);
+
+ public Task> CreatePoll(
+ NewPoll body,
+ CancellationToken cancellationToken = default)
+ => _all.CreatePoll(body, cancellationToken);
+
+ public Task> EndPoll(
+ long broadcasterId,
+ string id,
+ string status,
+ CancellationToken cancellationToken = default)
+ => _all.EndPoll(broadcasterId, id, status, cancellationToken);
+
+ public Task> GetPredictions(
+ long broadcasterId,
+ string? id = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetPredictions(broadcasterId, id, first, cancellationToken);
+
+ public Task> GetPredictions(
+ long broadcasterId,
+ IEnumerable? ids = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetPredictions(broadcasterId, ids, first, cancellationToken);
+
+ public Task> CreatePrediction(
+ NewPrediction body,
+ CancellationToken cancellationToken = default)
+ => _all.CreatePrediction(body, cancellationToken);
+
+ public Task> EndPrediction(
+ PredictionToEnd body,
+ CancellationToken cancellationToken = default)
+ => _all.EndPrediction(body, cancellationToken);
+
+ public Task> StartARaid(
+ long fromBroadcasterId,
+ long toBroadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.StartARaid(fromBroadcasterId, toBroadcasterId, cancellationToken);
+
+ public Task CancelARaid(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.CancelARaid(broadcasterId, cancellationToken);
+
+ public Task> GetChannelStreamSchedule(
+ long broadcasterId,
+ string? id = null,
+ DateTime? startTime = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetChannelStreamSchedule(broadcasterId, id, startTime, first, cancellationToken);
+
+ public Task> GetChannelStreamSchedule(
+ long broadcasterId,
+ IEnumerable? ids = null,
+ DateTime? startTime = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetChannelStreamSchedule(broadcasterId, ids, startTime, first, cancellationToken);
+
+ public Task UpdateChannelStreamSchedule(
+ long broadcasterId,
+ bool? isVacationEnabled = null,
+ DateTime? vacationStartTime = null,
+ DateTime? vacationEndTime = null,
+ string? timezone = null,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateChannelStreamSchedule(broadcasterId, isVacationEnabled, vacationStartTime, vacationEndTime, timezone, cancellationToken);
+
+ public Task> CreateChannelStreamScheduleSegment(
+ long broadcasterId,
+ NewScheduleSegment body,
+ CancellationToken cancellationToken = default)
+ => _all.CreateChannelStreamScheduleSegment(broadcasterId, body, cancellationToken);
+
+ public Task> UpdateChannelStreamScheduleSegment(
+ long broadcasterId,
+ string id,
+ Requests.UpdatedScheduleSegment Body,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateChannelStreamScheduleSegment(broadcasterId, id, Body, cancellationToken);
+
+ public Task DeleteChannelStreamScheduleSegment(
+ long broadcasterId,
+ string id,
+ CancellationToken cancellationToken = default)
+ => _all.DeleteChannelStreamScheduleSegment(broadcasterId, id, cancellationToken);
+
+ public Task> SearchCategories(
+ string query,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.SearchCategories(query, first, cancellationToken);
+
+ public Task> SearchChannels(
+ string query,
+ bool? liveOnly = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.SearchChannels(query, liveOnly, first, cancellationToken);
+
+ public Task> GetStreamKey(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.GetStreamKey(broadcasterId, cancellationToken);
+
+ public Task> GetStreams(
+ long? userId = null,
+ string? userLogin = null,
+ string? gameId = null,
+ StreamTypes? type = null,
+ string? language = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetStreams(userId, userLogin, gameId, type, language, first, cancellationToken);
+
+ public Task> GetStreams(
+ IEnumerable? userIds = null,
+ IEnumerable? userLogins = null,
+ IEnumerable? gameIds = null,
+ StreamTypes? type = null,
+ IEnumerable? languages = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetStreams(userIds, userLogins, gameIds, type, languages, first, cancellationToken);
+
+ public Task> GetFollowedStreams(
+ long userId,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetFollowedStreams(userId, first, cancellationToken);
+
+ public Task> CreateStreamMarker(
+ long userId,
+ string? description = null,
+ CancellationToken cancellationToken = default)
+ => _all.CreateStreamMarker(userId, description, cancellationToken);
+
+ public Task> GetStreamMarkers(
+ long userId,
+ string? videoId,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetStreamMarkers(userId, videoId, first, cancellationToken);
+
+ public Task> GetBroadcasterSubscriptions(
+ long broadcasterId,
+ long? userId = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetBroadcasterSubscriptions(broadcasterId, userId, first, cancellationToken);
+
+ public Task> GetBroadcasterSubscriptions(
+ long broadcasterId,
+ IEnumerable? userIds = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetBroadcasterSubscriptions(broadcasterId, userIds, first, cancellationToken);
+
+ public Task> CheckUserSubscription(
+ long broadcasterId,
+ long userId,
+ CancellationToken cancellationToken = default)
+ => _all.CheckUserSubscription(broadcasterId, userId, cancellationToken);
+
+ public Task> GetChannelTeams(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.GetChannelTeams(broadcasterId, cancellationToken);
+
+ public Task> GetTeams(
+ string name,
+ string id,
+ CancellationToken cancellationToken = default)
+ => _all.GetTeams(name, id, cancellationToken);
+
+ public Task> GetUsers(
+ long? id = null,
+ string? login = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetUsers(id, login, cancellationToken);
+
+ public Task> GetUsers(
+ IEnumerable? id = null,
+ IEnumerable? login = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetUsers(id, login, cancellationToken);
+
+ public Task> UpdateUser(
+ string? description = null,
+ CancellationToken cancellationToken = default)
+ => _all.UpdateUser(description, cancellationToken);
+
+ public Task BlockUser(
+ long targetUserId,
+ string? sourceContext = null,
+ string? reason = null,
+ CancellationToken cancellationToken = default)
+ => _all.BlockUser(targetUserId, sourceContext, reason, cancellationToken);
+
+ public Task UnblockUser(
+ long targetUserId,
+ CancellationToken cancellationToken = default)
+ => _all.UnblockUser(targetUserId, cancellationToken);
+
+ public Task> GetUserExtensions(
+ CancellationToken cancellationToken = default)
+ => _all.GetUserExtensions(cancellationToken);
+
+ public Task> GetUserActiveExtensions(
+ long? userId = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetUserActiveExtensions(userId, cancellationToken);
+
+ public Task> GetVideos(
+ string? id = null,
+ long? userId = null,
+ string? gameId = null,
+ string? language = null,
+ VideoPeriod? period = null,
+ VideoSortMethod? sort = null,
+ VideoType? type = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetVideos(id, userId, gameId, language, period, sort, type, first, cancellationToken);
+
+ public Task> GetVideos(
+ IEnumerable? ids = null,
+ long? userId = null,
+ string? gameId = null,
+ string? language = null,
+ VideoPeriod? period = null,
+ VideoSortMethod? sort = null,
+ VideoType? type = null,
+ int? first = null,
+ CancellationToken cancellationToken = default)
+ => _all.GetVideos(ids, userId, gameId, language, period, sort, type, first, cancellationToken);
+
+ public Task DeleteVideos(
+ string id,
+ CancellationToken cancellationToken = default)
+ => _all.DeleteVideos(id, cancellationToken);
+
+ public Task DeleteVideos(
+ IEnumerable ids,
+ CancellationToken cancellationToken = default)
+ => _all.DeleteVideos(ids, cancellationToken);
+
+ public Task SendWhisper(
+ long fromUserId,
+ long toUserId,
+ string message,
+ CancellationToken cancellationToken = default)
+ => _all.SendWhisper(fromUserId, toUserId, message, cancellationToken);
+
+ public Task> GetAdSchedule(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.GetAdSchedule(broadcasterId, cancellationToken);
+
+ public Task> SnoozeNextAd(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.SnoozeNextAd(broadcasterId, cancellationToken);
+
+ public Task> GetChannelChatBadges(
+ long broadcasterId,
+ CancellationToken cancellationToken = default)
+ => _all.GetChannelChatBadges(broadcasterId, cancellationToken);
+
+ public Task> GetGlobalChatBadges(
+ CancellationToken cancellationToken = default)
+ => _all.GetGlobalChatBadges(cancellationToken);
+
+}
diff --git a/MiniTwitch.Helix/Interfaces/IHelixResult.cs b/MiniTwitch.Helix/Interfaces/IHelixResult.cs
new file mode 100644
index 0000000..ebb094a
--- /dev/null
+++ b/MiniTwitch.Helix/Interfaces/IHelixResult.cs
@@ -0,0 +1,11 @@
+using System.Net;
+
+namespace MiniTwitch.Helix.Interfaces;
+
+public interface IHelixResult
+{
+ HttpStatusCode StatusCode { get; }
+ string Message { get; }
+ TimeSpan Elapsed { get; }
+ bool Success { get; }
+}
diff --git a/MiniTwitch.Helix/Interfaces/IPaginable.cs b/MiniTwitch.Helix/Interfaces/IPaginable.cs
new file mode 100644
index 0000000..803ab50
--- /dev/null
+++ b/MiniTwitch.Helix/Interfaces/IPaginable.cs
@@ -0,0 +1,8 @@
+using MiniTwitch.Helix.Models;
+
+namespace MiniTwitch.Helix.Interfaces;
+
+public interface IPaginable
+{
+ public Pagination Pagination { get; }
+}
diff --git a/MiniTwitch.Helix/Internal/HelixApiClient.cs b/MiniTwitch.Helix/Internal/HelixApiClient.cs
new file mode 100644
index 0000000..2c9ef2e
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/HelixApiClient.cs
@@ -0,0 +1,176 @@
+using System.Diagnostics;
+using System.Net.Http.Json;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Microsoft.Extensions.Logging;
+using MiniTwitch.Common;
+using MiniTwitch.Helix.Internal.Json;
+using MiniTwitch.Helix.Internal.Models;
+using MiniTwitch.Helix.Models;
+
+namespace MiniTwitch.Helix.Internal;
+
+internal sealed class HelixApiClient
+{
+ public DefaultMiniTwitchLogger Logger { get; } = new();
+ public JsonSerializerOptions SerializerOptions { get; init; } = new()
+ {
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ NumberHandling = JsonNumberHandling.AllowReadingFromString,
+ PropertyNamingPolicy = new SnakeCaseNamingPolicy()
+ };
+
+ private readonly HttpClient _httpClient = new();
+ private readonly string _tokenValidationUrl;
+ private readonly ILogger? _logger;
+ private ValidToken? _tokenInfo;
+
+ public HelixApiClient(string token, string clientId, ILogger? logger, string tokenValidationUrl)
+ {
+ _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
+ _httpClient.DefaultRequestHeaders.Add("Client-Id", $"{clientId}");
+ _tokenValidationUrl = tokenValidationUrl;
+ _logger = logger;
+ }
+
+ public Task<(HttpResponseMessage, long)> RequestAsync(RequestData requestObject, CancellationToken ct) => requestObject._method switch
+ {
+ "POST" => PostAsync(requestObject, ct),
+ "GET" => GetAsync(requestObject, ct),
+ "PUT" => PutAsync(requestObject, ct),
+ "DELETE" => DeleteAsync(requestObject, ct),
+ "PATCH" => PatchAsync(requestObject, ct),
+ _ => throw new NotImplementedException($"HTTP method {requestObject._method} is not supported")
+ };
+
+ private async Task<(HttpResponseMessage, long)> PostAsync(RequestData requestObject, CancellationToken ct)
+ {
+ await ValidateToken();
+ string url = requestObject.GetUrl();
+ var sw = Stopwatch.StartNew();
+ HttpResponseMessage response = await _httpClient.PostAsJsonAsync(url, requestObject.Body, this.SerializerOptions, ct);
+ sw.Stop();
+ long elapsedMs = sw.ElapsedMilliseconds;
+ LogLevel logLevel = response.IsSuccessStatusCode ? LogLevel.Debug : LogLevel.Warning;
+ Log(logLevel, "POST [{Code}] {Url} {ElapsedMs}ms", response.StatusCode, url, elapsedMs);
+ return (response, elapsedMs);
+ }
+
+ private async Task<(HttpResponseMessage, long)> GetAsync(RequestData requestObject, CancellationToken ct)
+ {
+ await ValidateToken();
+ string url = requestObject.GetUrl();
+ var sw = Stopwatch.StartNew();
+ HttpResponseMessage response = await _httpClient.GetAsync(url, ct);
+ sw.Stop();
+ long elapsedMs = sw.ElapsedMilliseconds;
+ LogLevel logLevel = response.IsSuccessStatusCode ? LogLevel.Debug : LogLevel.Warning;
+ Log(logLevel, "GET [{Code}] {Url} {ElapsedMs}ms", response.StatusCode, url, elapsedMs);
+ return (response, elapsedMs);
+ }
+
+ private async Task<(HttpResponseMessage, long)> PutAsync(RequestData requestObject, CancellationToken ct)
+ {
+ await ValidateToken();
+ string url = requestObject.GetUrl();
+ var sw = Stopwatch.StartNew();
+ HttpResponseMessage response = await _httpClient.PutAsJsonAsync(url, requestObject.Body, this.SerializerOptions, ct);
+ sw.Stop();
+ long elapsedMs = sw.ElapsedMilliseconds;
+ LogLevel logLevel = response.IsSuccessStatusCode ? LogLevel.Debug : LogLevel.Warning;
+ Log(logLevel, "PUT [{Code}] {Url} {ElapsedMs}ms", response.StatusCode, url, elapsedMs);
+ return (response, elapsedMs);
+ }
+
+ private async Task<(HttpResponseMessage, long)> DeleteAsync(RequestData requestObject, CancellationToken ct)
+ {
+ await ValidateToken();
+ string url = requestObject.GetUrl();
+ var sw = Stopwatch.StartNew();
+ HttpResponseMessage response = await _httpClient.DeleteAsync(url, ct);
+ sw.Stop();
+ long elapsedMs = sw.ElapsedMilliseconds;
+ LogLevel logLevel = response.IsSuccessStatusCode ? LogLevel.Debug : LogLevel.Warning;
+ Log(logLevel, "DELETE [{Code}] {Url} {ElapsedMs}ms", response.StatusCode, url, elapsedMs);
+ return (response, elapsedMs);
+ }
+
+ private async Task<(HttpResponseMessage, long)> PatchAsync(RequestData requestObject, CancellationToken ct)
+ {
+ await ValidateToken();
+ string url = requestObject.GetUrl();
+ string rawContent = JsonSerializer.Serialize(requestObject.Body, this.SerializerOptions);
+ var content = new StringContent(rawContent, Encoding.UTF8, "application/json");
+ var sw = Stopwatch.StartNew();
+ HttpResponseMessage response = await _httpClient.PatchAsync(url, content, ct);
+ sw.Stop();
+ long elapsedMs = sw.ElapsedMilliseconds;
+ LogLevel logLevel = response.IsSuccessStatusCode ? LogLevel.Debug : LogLevel.Warning;
+ Log(logLevel, "PATCH [{Code}] {Url} {ElapsedMs}ms", response.StatusCode, url, elapsedMs);
+ return (response, elapsedMs);
+ }
+
+ private async ValueTask ValidateToken()
+ {
+ long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
+ if (_tokenInfo is not null)
+ {
+ var expiresIn = TimeSpan.FromSeconds(_tokenInfo.ReceivedAt + _tokenInfo.ExpiresIn - now);
+ if (_tokenInfo.IsPermaToken)
+ {
+ Log(LogLevel.Trace, "Request sent with access token from user {Username} [No expiry]", _tokenInfo.Login);
+ return;
+ }
+
+ switch (expiresIn)
+ {
+ case { TotalSeconds: <= -1 }:
+ throw new InvalidTokenException(null, $"Access token for user \"{_tokenInfo.Login}\" has expired");
+ case { TotalHours: < 0 }:
+ Log(LogLevel.Warning, "Access token for user {Username} expires in {ExpiresInMinutes} minutes", expiresIn.Minutes);
+ break;
+ case { TotalDays: < 0 }:
+ Log(LogLevel.Warning, "Access token for user {Username} expires in {ExpiresInHours} hours", expiresIn.Hours);
+ break;
+ default:
+ Log(LogLevel.Trace, "Request sent with access token from user {Username} [Expires in: {ExpiresIn}]", expiresIn);
+ break;
+ }
+
+ return;
+ }
+
+ HttpResponseMessage response = await _httpClient.GetAsync(_tokenValidationUrl);
+ if (!response.IsSuccessStatusCode)
+ {
+ InvalidToken? invalid = await response.Content.ReadFromJsonAsync();
+ throw new InvalidTokenException(invalid?.Message, "Provided access token is either invalid or has expired");
+ }
+
+ _tokenInfo = await response.Content.ReadFromJsonAsync();
+ if (_tokenInfo is null)
+ return;
+
+ _tokenInfo.ReceivedAt = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
+ if (_tokenInfo.IsPermaToken)
+ {
+ Log(
+ LogLevel.Information,
+ "Validated permanent access token from user {Username} with {ScopeCount} scopes",
+ _tokenInfo.Login, _tokenInfo.Scopes.Count
+ );
+
+ return;
+ }
+
+ Log(
+ LogLevel.Information,
+ "Validated access token from user {Username} with {ScopeCount} scopes. The token expires at {ExpiresAt}",
+ _tokenInfo.Login, _tokenInfo.Scopes.Count, DateTimeOffset.FromUnixTimeSeconds(_tokenInfo.ReceivedAt + _tokenInfo.ExpiresIn)
+ );
+ }
+
+ private void Log(LogLevel level, string template, params object[] properties) => GetLogger().Log(level, "[MiniTwitch.Helix] " + template, properties);
+ private ILogger GetLogger() => _logger ?? this.Logger;
+}
diff --git a/MiniTwitch.Helix/Internal/HelixResultFactory.cs b/MiniTwitch.Helix/Internal/HelixResultFactory.cs
new file mode 100644
index 0000000..fb2a9e7
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/HelixResultFactory.cs
@@ -0,0 +1,125 @@
+using System.Net.Http.Json;
+using MiniTwitch.Helix.Internal.Models;
+using MiniTwitch.Helix.Models;
+
+namespace MiniTwitch.Helix.Internal;
+
+internal static class HelixResultFactory
+{
+ private const string HEADER_RL_LIMIT = "Ratelimit-Limit";
+ private const string HEADER_RL_REMAINING = "Ratelimit-Remaining";
+ private const string HEADER_RL_RESET = "Ratelimit-Reset";
+
+ public static async Task> Create(HelixApiClient client, RequestData request, HelixEndpoint endpoint,
+ CancellationToken cancellationToken)
+ {
+ (HttpResponseMessage response, long elapsedMs) = await client.RequestAsync(request, cancellationToken);
+ // Because some endpoints don't have appropriate success status codes, .IsSuccessStatusCode should be checked first
+ if (!response.IsSuccessStatusCode && response.StatusCode != endpoint.SuccessStatusCode)
+ {
+ return new HelixResult()
+ {
+ Success = false,
+ Message = endpoint.GetResponseMessage(response.StatusCode),
+ StatusCode = response.StatusCode,
+ Elapsed = TimeSpan.FromMilliseconds(elapsedMs),
+ Value = default!
+ };
+ }
+
+ T? toObject;
+ try
+ {
+ toObject = await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken);
+ if (toObject is null)
+ {
+ return new HelixResult()
+ {
+ Success = false,
+ Message = "Unknown deserialization failure.\n\n" +
+ await response.Content.ReadAsStringAsync(cancellationToken),
+ StatusCode = response.StatusCode,
+ Elapsed = TimeSpan.FromMilliseconds(elapsedMs),
+ Value = toObject!,
+ Ratelimit = GetRateLimit(response)
+ };
+ }
+ }
+ catch (Exception ex)
+ {
+ return new HelixResult()
+ {
+ Success = false,
+ Message = $"Deserialization failure.\n" +
+ $"{ex.Message}\n" +
+ $"{ex.StackTrace}\n\n" +
+ await response.Content.ReadAsStringAsync(cancellationToken),
+ StatusCode = response.StatusCode,
+ Elapsed = TimeSpan.FromMilliseconds(elapsedMs),
+ Value = default!
+ };
+ }
+
+ return new HelixResult()
+ {
+ Success = true,
+ Message = endpoint.GetResponseMessage(response.StatusCode),
+ StatusCode = response.StatusCode,
+ Elapsed = TimeSpan.FromMilliseconds(elapsedMs),
+ Value = toObject,
+ HelixTask = new() { Endpoint = endpoint, Client = client, Request = request },
+ Ratelimit = GetRateLimit(response)
+ };
+ }
+
+ public static async Task Create(HelixApiClient client, RequestData request, HelixEndpoint endpoint,
+ CancellationToken cancellationToken)
+ {
+ (HttpResponseMessage response, long elapsedMs) = await client.RequestAsync(request, cancellationToken);
+ return new HelixResult()
+ {
+ Success = response.StatusCode == endpoint.SuccessStatusCode,
+ Message = endpoint.GetResponseMessage(response.StatusCode),
+ StatusCode = response.StatusCode,
+ Elapsed = TimeSpan.FromMilliseconds(elapsedMs),
+ Ratelimit = GetRateLimit(response)
+ };
+ }
+
+ private static RequestRatelimit GetRateLimit(HttpResponseMessage response)
+ {
+ long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
+ int limit = 0;
+ int remaining = 0;
+ int resets = 0;
+ int val;
+ foreach (KeyValuePair> header in response.Headers)
+ {
+ switch (header.Key)
+ {
+ case HEADER_RL_LIMIT:
+ limit = int.TryParse(header.Value.FirstOrDefault(), out val) ? val : 0;
+ break;
+
+ case HEADER_RL_REMAINING:
+ remaining = int.TryParse(header.Value.FirstOrDefault(), out val) ? val : 0;
+ break;
+
+ case HEADER_RL_RESET:
+ resets = int.TryParse(header.Value.FirstOrDefault(), out val) ? val : 0;
+ break;
+
+ default:
+ continue;
+ }
+ }
+
+ TimeSpan resetsIn = resets - now < 0 ? TimeSpan.Zero : TimeSpan.FromSeconds(resets - now);
+ return new()
+ {
+ Limit = limit,
+ Remaining = remaining,
+ ResetsIn = resetsIn
+ };
+ }
+}
diff --git a/MiniTwitch.Helix/Internal/Json/EnumToString.cs b/MiniTwitch.Helix/Internal/Json/EnumToString.cs
new file mode 100644
index 0000000..e411739
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Json/EnumToString.cs
@@ -0,0 +1,30 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace MiniTwitch.Helix.Internal.Json;
+
+internal class EnumToString : JsonConverter
+ where ICase : ICaseConverter, new()
+{
+ private static readonly ICaseConverter _case = new ICase();
+
+ public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ if (reader.TokenType == JsonTokenType.String)
+ {
+ string? enumAsString = reader.GetString();
+ if (Enum.TryParse(typeof(TEnum), _case.ConvertFromCase(enumAsString), out object? enumMember))
+ return (TEnum)enumMember!;
+ }
+
+ throw new JsonException();
+ }
+
+ public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options)
+ {
+ if (value is null)
+ writer.WriteNullValue();
+ else
+ writer.WriteStringValue(_case.ConvertToCase(value.ToString()));
+ }
+}
diff --git a/MiniTwitch.Helix/Internal/Json/ICaseConverter.cs b/MiniTwitch.Helix/Internal/Json/ICaseConverter.cs
new file mode 100644
index 0000000..2cb8ff8
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Json/ICaseConverter.cs
@@ -0,0 +1,7 @@
+namespace MiniTwitch.Helix.Internal.Json;
+
+internal interface ICaseConverter
+{
+ string? ConvertToCase(string? str);
+ string? ConvertFromCase(string? str);
+}
diff --git a/MiniTwitch.Helix/Internal/Json/IntToString.cs b/MiniTwitch.Helix/Internal/Json/IntToString.cs
new file mode 100644
index 0000000..46593ff
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Json/IntToString.cs
@@ -0,0 +1,12 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace MiniTwitch.Helix.Internal.Json;
+
+internal class IntToString : JsonConverter
+{
+ public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ => throw new NotSupportedException("Converter should only be used for writing");
+
+ public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options) => writer.WriteStringValue(value.ToString());
+}
diff --git a/MiniTwitch.Helix/Internal/Json/LongToString.cs b/MiniTwitch.Helix/Internal/Json/LongToString.cs
new file mode 100644
index 0000000..8ae24c1
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Json/LongToString.cs
@@ -0,0 +1,12 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace MiniTwitch.Helix.Internal.Json;
+
+internal class LongToString : JsonConverter
+{
+ public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ => throw new NotSupportedException("Converter should only be used for writing");
+
+ public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options) => writer.WriteStringValue(value.ToString());
+}
diff --git a/MiniTwitch.Helix/Internal/Json/SnakeCase.cs b/MiniTwitch.Helix/Internal/Json/SnakeCase.cs
new file mode 100644
index 0000000..d96efe5
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Json/SnakeCase.cs
@@ -0,0 +1,56 @@
+namespace MiniTwitch.Helix.Internal.Json;
+
+internal class SnakeCase : ICaseConverter
+{
+ public static SnakeCase Instance { get; } = new();
+
+ public string? ConvertFromCase(string? str)
+ {
+ if (str is null)
+ return null;
+
+ const char underscore = '_';
+
+ ReadOnlySpan chars = str;
+ Span replacement = stackalloc char[chars.Length];
+ int i = 1;
+ int offset = 0;
+ replacement[0] = char.ToUpper(chars[0]);
+ for (; i < chars.Length - offset; i++)
+ {
+ char c = chars[i + offset];
+ replacement[i] = c == underscore ? char.ToUpper(chars[i + ++offset]) : c;
+ }
+
+ return replacement[..i].ToString();
+ }
+
+ public string? ConvertToCase(string? str)
+ {
+ if (str is null)
+ return null;
+
+ const char underscore = '_';
+
+ ReadOnlySpan chars = str;
+ Span replacement = stackalloc char[chars.Length * 2];
+ int i = 1;
+ int offset = 0;
+ replacement[0] = char.ToLower(chars[0]);
+ for (; i < chars.Length; i++)
+ {
+ char c = chars[i];
+ if (char.IsUpper(c))
+ {
+ replacement[i + offset++] = underscore;
+ replacement[i + offset] = char.ToLower(c);
+ }
+ else
+ {
+ replacement[i + offset] = c;
+ }
+ }
+
+ return replacement[..(i + offset)].ToString();
+ }
+}
diff --git a/MiniTwitch.Helix/Internal/Json/SnakeCaseNamingPolicy.cs b/MiniTwitch.Helix/Internal/Json/SnakeCaseNamingPolicy.cs
new file mode 100644
index 0000000..6e3f8d8
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Json/SnakeCaseNamingPolicy.cs
@@ -0,0 +1,32 @@
+using System.Text.Json;
+
+namespace MiniTwitch.Helix.Internal.Json;
+
+internal class SnakeCaseNamingPolicy : JsonNamingPolicy
+{
+ public override string ConvertName(string name)
+ {
+ const char underscore = '_';
+
+ ReadOnlySpan chars = name;
+ Span replacement = stackalloc char[chars.Length * 2];
+ int i = 1;
+ int offset = 0;
+ replacement[0] = char.ToLower(chars[0]);
+ for (; i < chars.Length; i++)
+ {
+ char c = chars[i];
+ if (char.IsUpper(c))
+ {
+ replacement[i + offset++] = underscore;
+ replacement[i + offset] = char.ToLower(c);
+ }
+ else
+ {
+ replacement[i + offset] = c;
+ }
+ }
+
+ return replacement[..(i + offset)].ToString();
+ }
+}
diff --git a/MiniTwitch.Helix/Internal/Json/TimeSpanToSeconds.cs b/MiniTwitch.Helix/Internal/Json/TimeSpanToSeconds.cs
new file mode 100644
index 0000000..8a7f508
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Json/TimeSpanToSeconds.cs
@@ -0,0 +1,12 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace MiniTwitch.Helix.Internal.Json;
+
+internal class TimeSpanToSeconds : JsonConverter
+{
+ public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ => throw new NotSupportedException("Converter should only be used for writing");
+
+ public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options) => writer.WriteNumberValue((int)value.TotalSeconds);
+}
diff --git a/MiniTwitch.Helix/Internal/Models/Endpoints.cs b/MiniTwitch.Helix/Internal/Models/Endpoints.cs
new file mode 100644
index 0000000..9383662
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Models/Endpoints.cs
@@ -0,0 +1,1901 @@
+using System.Net;
+
+namespace MiniTwitch.Helix.Internal.Models;
+
+// Values scraped from https://dev.twitch.tv/docs/api/reference/
+// If you see anything wrong, please open an issue!
+internal static class Endpoints
+{
+ public static readonly HelixEndpoint StartCommercial = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/channels/commercial",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully started the commercial.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe length query parameter is required.\r\nThe ID in broadcaster_id is not valid.\r\nTo start a commercial, the broadcaster must be streaming live.\r\nThe broadcaster may not run another commercial until the cooldown period expires.\r\n The retry_after field in the previous start commercial response specifies the amount of time the broadcaster must wait between running commercials.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID found in the request's OAuth token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:edit:commercial scope.\r\nThe OAuth token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ HttpStatusCode.NotFound => "The ID in broadcaster_id was not found.",
+ HttpStatusCode.TooManyRequests => "The broadcaster may not run another commercial until the cooldown period expires.\r\n The retry_after field in the previous start commercial response specifies the amount of time the broadcaster must wait between running commercials.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetExtensionAnalytics = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/analytics/extensions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's analytics reports.",
+ HttpStatusCode.BadRequest => "The start and end dates are optional but if you specify one, you must specify the other.\r\nThe end date must be equal to or later than the start date.\r\nThe cursor specified in the after query parameter is not valid.\r\nThe resource supports only forward pagination (use the after query parameter).\r\nThe first query parameter is outside the allowed range of values.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the analytics:read:extensions scope.\r\nThe OAuth token is not valid.\r\nThe Client-Id header is required.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ HttpStatusCode.NotFound => "The extension specified in the extension_id query parameter was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetGameAnalytics = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/analytics/games",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's analytics reports.",
+ HttpStatusCode.BadRequest => "The start and end dates are optional but if you specify one, you must specify the other.\r\nThe end date must be equal to or later than the start date.\r\nThe cursor specified in the after query parameter is not valid.\r\nThe resource supports only forward pagination (use the after query parameter).\r\nThe first query parameter is outside the allowed range of values.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the analytics:read:games scope.\r\nThe OAuth token is not valid.\r\nThe Client-Id header is required.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ HttpStatusCode.NotFound => "The game specified in the game_id query parameter was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetBitsLeaderboard = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/bits/leaderboard",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's Bits leaderboard.",
+ HttpStatusCode.BadRequest => "The time period specified in the period query parameter is not valid.\r\nThe started_at query parameter is required if period is not set to all.\r\nThe value in the count query parameter is outside the range of allowed values.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a user access token.\r\nThe user access token must include the the bits:read scope.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetCheermotes = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/bits/cheermotes",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the Cheermotes.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetExtensionTransactions = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/extensions/transactions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of transactions.",
+ HttpStatusCode.BadRequest => "The extension_id query parameter is required.\r\nThe request specified too many id query parameters.\r\nThe pagination cursor is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token.\r\nThe access token is not valid.\r\nThe ID in the extension_id query parameter must match the client ID in the access token.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ HttpStatusCode.NotFound => "One or more of the transaction IDs specified using the id query parameter were not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetChannelInformation = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/channels",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of channels.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe broadcaster ID is not valid.\r\nThe number of broadcaster_id query parameters exceeds the maximum allowed.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ HttpStatusCode.TooManyRequests => "The application exceeded the number of calls it may make per minute.\r\n For details, see Rate Limits.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint ModifyChannelInformation = new()
+ {
+ Method = HttpMethod.Patch,
+ Route = "/channels",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully updated the channel's properties.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe request must update at least one property.\r\nThe title field may not contain an empty string.\r\nThe ID in game_id is not valid.\r\nTo update the delay field, the broadcaster must have partner status.\r\nThe list in the tags field exceeds the maximum number of tags allowed.\r\nA tag in the tags field exceeds the maximum length allowed.\r\nA tag in the tags field is empty.\r\nA tag in the tags field contains special characters or spaces.\r\nOne or more tags in the tags field failed AutoMod review.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID found in the OAuth token.\r\nThe Authorization header is required and must specify a user access token.\r\nThe OAuth token must include the channel:manage:broadcast scope.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetChannelEditors = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/channels/editors",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's list of editors.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in the broadcaster_id query parameter must match the user ID found in the OAuth token.\r\nThe Authorization header is required and must specify a user access token.\r\nThe OAuth token must include the channel:read:editors scope.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetFollowedChannels = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/channels/followed",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's list of followers.",
+ HttpStatusCode.BadRequest => "Possible reasons:The user_id query parameter is required.\r\nThe broadcaster_id query parameter is not valid.\r\nThe user_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "Possible reasons:The ID in the user_id query parameter must match the user ID in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token is missing the user:read:follows scope.\r\nThe OAuth token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetChannelFollowers = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/channels/followers",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's list of followers.",
+ HttpStatusCode.BadRequest => "Possible reasons:The broadcaster_id query parameter is required.\r\nThe broadcaster_id query parameter is not valid.\r\nThe user_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "Possible reasons:The ID in the broadcaster_id query parameter must match the user ID in the access token or the user must be a moderator for the specified broadcaster.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token is missing the moderator:read:followers scope.\r\nThe OAuth token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CreateCustomRewards = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/channel_points/custom_rewards",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully created the custom reward.",
+ HttpStatusCode.BadRequest => "The request exceeds the maximum number of rewards allowed per channel.\r\nThe broadcaster_id query parameter is required.\r\nThe title field is required.\r\nThe title must contain a minimum of 1 character and a maximum of 45 characters.\r\nThe title must be unique amongst all of the broadcaster's custom rewards.\r\nThe cost field is required.\r\nThe cost field must contain a minimum of 1 point.\r\nThe prompt field is limited to a maximum of 200 characters.\r\nIf is_max_per_stream_enabled is true, the minimum value for max_per_stream is 1.\r\nIf is_max_per_user_per_stream_enabled is true, the minimum value for max_per_user_per_stream is 1.\r\nIf is_global_cooldown_enabled is true, the minimum value for global_cooldown_seconds is 1.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a user access token.\r\nThe user access token is missing the channel:manage:redemptions scope.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ HttpStatusCode.Forbidden => "The broadcaster is not a partner or affiliate.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint DeleteCustomReward = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/channel_points/custom_rewards",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully deleted the custom reward.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a user access token.\r\nThe user access token must include the channel:manage:redemptions scope.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ HttpStatusCode.Forbidden => "The ID in the Client-Id header must match the client ID used to create the custom reward.\r\nThe broadcaster is not a partner or affiliate.",
+ HttpStatusCode.NotFound => "The custom reward specified in the id query parameter was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetCustomReward = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/channel_points/custom_rewards",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's list of custom rewards.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe request exceeds the maximum number of id query parameters that you may specify.",
+ HttpStatusCode.Unauthorized => "The Authorization header must specify a user access token.\r\nThe user access token must include the channel:read:redemptions scope.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ HttpStatusCode.Forbidden => "The broadcaster is not a partner or affiliate.",
+ HttpStatusCode.NotFound => "All of the custom rewards specified using the id query parameter were not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetCustomRewardRedemption = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/channel_points/custom_rewards/redemptions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of redeemed custom rewards.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe reward_id query parameter is required.\r\nThe status query parameter is required if you didn't specify the id query parameter.\r\nThe value in the status query parameter is not valid.\r\nThe value in the sort query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a user access token.\r\nThe user access token must include the channel:read:redemptions scope.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ HttpStatusCode.Forbidden => "The ID in the Client-Id header must match the client ID used to create the custom reward.\r\nThe broadcaster is not a partner or affiliate.",
+ HttpStatusCode.NotFound => "All of the redemptions specified using the id query parameter were not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateCustomReward = new()
+ {
+ Method = HttpMethod.Patch,
+ Route = "/channel_points/custom_rewards",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully updated the custom reward.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe id query parameter is required.\r\nThe title must contain a minimum of 1 character and a maximum of 45 characters.\r\nThe title must be unique amongst all of the broadcaster's custom rewards.\r\nThe cost field must contain a minimum of 1 point.\r\nThe prompt field is limited to a maximum of 200 characters.\r\nIf is_max_per_stream_enabled is true, the minimum value for max_per_stream is 1.\r\nIf is_max_per_user_per_stream_enabled is true, the minimum value for max_per_user_per_stream is 1.\r\nIf is_global_cooldown_enabled is true, the minimum value for global_cooldown_seconds is 1 and the maximum is 604800.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a user access token.\r\nThe user access token must include the channel:manage:redemptions scope.\r\nThe OAuth token is not valide.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ HttpStatusCode.Forbidden => "The ID in the Client-Id header must match the client ID used to create the custom reward.\r\nThe broadcaster is not a partner or affiliate.",
+ HttpStatusCode.NotFound => "The custom reward specified in the id query parameter was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateRedemptionStatus = new()
+ {
+ Method = HttpMethod.Patch,
+ Route = "/channel_points/custom_rewards/redemptions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully updated the redemption's status.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe reward_id query parameter is required.\r\nThe id query parameter is required.\r\nThe value in the status query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a user access token.\r\nThe user access token must include the channel:manage:redemptions scope.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ HttpStatusCode.Forbidden => "The ID in the Client-Id header must match the client ID used to create the custom reward.\r\nThe broadcaster is not a partner or affiliate.",
+ HttpStatusCode.NotFound => "The custom reward specified in the reward_id query parameter was not found.\r\nThe redemptions specified using the id query parameter were not found or their statuses weren't marked as UNFULFILLED.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetCharityCampaign = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/charity/campaigns",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved information about the broadcaster's active charity campaign.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe broadcaster_id query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The ID in the broadcaster_id query parameter must match the user ID in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:read:charity scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header must match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The broadcaster is not a partner or affiliate.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetCharityCampaignDonations = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/charity/donations",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of donations that users contributed to the broadcaster's charity campaign.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe broadcaster_id query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The ID in the broadcaster_id query parameter must match the user ID in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:read:charity scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header must match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The broadcaster is not a partner or affiliate.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetChatters = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/chat/chatters",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's list of chatters.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe ID in the broadcaster_id query parameter is not valid.\r\nThe moderator_id query parameter is required.\r\nThe ID in the moderator_id query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The ID in the moderator_id query parameter must match the user ID in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:read:chatters scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in the moderator_id query parameter is not one of the broadcaster's moderators.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetChannelEmotes = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/chat/emotes",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved broadcaster's list of custom emotes.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a valid app access token or user access token.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetGlobalEmotes = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/chat/emotes/global",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved Twitch's list of global emotes.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a valid app access token or user access token.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetEmoteSets = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/chat/emotes/set",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the emotes for the specified emote sets.",
+ HttpStatusCode.BadRequest => "The emote_set_id query parameter is required.\r\nThe number of emote_set_id query parameters exceeds the maximum allowed.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a valid app access token or user access token.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetChannelChatBadges = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/chat/badges",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's custom chat badges.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a valid app access token or user access token.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetGlobalChatBadges = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/chat/badges/global",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of global chat badges.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a valid app access token or user access token.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetChatSettings = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/chat/settings",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's chat settings.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a valid app access token or user access token.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateChatSettings = new()
+ {
+ Method = HttpMethod.Patch,
+ Route = "/chat/settings",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully updated the broadcaster's chat settings.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe moderator_id query parameter is required.\r\nIf slow_mode is true, the slow_mode_wait_time field must be set to a valid value.\r\nIf follower_mode is true, the follower_mode_duration field must be set to a valid value.\r\nIf non_moderator_chat_delay is true, the non_moderator_chat_delay_duration field must be set to a valid value.",
+ HttpStatusCode.Unauthorized => "The ID in the moderator_id query parameter must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:manage:chat_settings scope.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ HttpStatusCode.Forbidden => "The user in the moderator_id query parameter must have moderator privileges in the broadcaster's channel.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint SendChatAnnouncement = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/chat/announcements",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully sent the announcement.",
+ HttpStatusCode.BadRequest => "The message field in the request's body is required.\r\nThe message field may not contain an empty string.\r\nThe message field may not contain an empty string.\r\nThe string in the message field failed review.\r\nThe specified color is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token is missing the moderator:manage:announcements scope.\r\nThe OAuth token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint SendAShoutout = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/chat/shoutouts",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully sent the specified broadcaster a Shoutout.",
+ HttpStatusCode.BadRequest => "The from_broadcaster_id query parameter is required.\r\nThe ID in the from_broadcaster_id query parameter is not valid.\r\nThe to_broadcaster_id query parameter is required.\r\nThe ID in the to_broadcaster_id query parameter is not valid.\r\nThe broadcaster may not give themselves a Shoutout.\r\nThe broadcaster is not streaming live or does not have one or more viewers.",
+ HttpStatusCode.Unauthorized => "The ID in moderator_id must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:manage:shoutouts scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in moderator_id is not one of the broadcaster's moderators.\r\nThe broadcaster may not send the specified broadcaster a Shoutout.",
+ HttpStatusCode.TooManyRequests => "The broadcaster exceeded the number of Shoutouts they may send within a given window.\r\n See the endpoint's Rate Limits.\r\nThe broadcaster exceeded the number of Shoutouts they may send the same broadcaster within a given window.\r\n See the endpoint's Rate Limits.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetUserChatColor = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/chat/color",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the chat color used by the specified users.",
+ HttpStatusCode.BadRequest => "The ID in the user_id query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain an app access token or user access token.\r\nThe OAuth token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateUserChatColor = new()
+ {
+ Method = HttpMethod.Put,
+ Route = "/chat/color",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully updated the user's chat color.",
+ HttpStatusCode.BadRequest => "The ID in the user_id query parameter is not valid.\r\nThe color query parameter is required.\r\nThe named color in the color query parameter is not valid.\r\nTo specify a Hex color code, the user must be a Turbo or Prime user.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:manage:chat_color scope.\r\nThe OAuth token is not valid.\r\nThe ID in the user_id query parameter must match the user ID in the access token.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CreateClip = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/clips",
+ SuccessStatusCode = HttpStatusCode.Accepted,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.Accepted => "Successfully started the clip process.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe ID in the broadcaster_id query parameter was not found.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify user access token.\r\nThe user access token must include the clips:edit scope.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ HttpStatusCode.Forbidden => "The broadcaster has restricted the ability to capture clips to followers and/or subscribers only.\r\nThe specified broadcaster has not enabled clips on their channel.",
+ HttpStatusCode.NotFound => "The broadcaster in the broadcaster_id query parameter must be broadcasting live.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetClips = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/clips",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of video clips.",
+ HttpStatusCode.BadRequest => "The id or game_id or broadcaster_id query parameter is required.\r\nThe id, game_id, and broadcaster_id query parameters are mutually exclusive; you may specify only one of them.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain an app access token or user access token.\r\nThe OAuth token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ HttpStatusCode.NotFound => "The ID in game_id was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetContentClassificationLabels = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/content_classification_labels",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code.ToString()
+ };
+
+ public static readonly HelixEndpoint GetDropsEntitlements = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/entitlements/drops",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the entitlements.",
+ HttpStatusCode.BadRequest => "The value in the fulfillment_status query parameter is not valid.\r\nThe ID in the user_id query parameter must match the user ID in the user access token.\r\nThe client in the access token is not associated with a known organization.\r\nThe owner of the client in the access token is not a member of the organization.",
+ HttpStatusCode.Unauthorized => "The ID in the Client-Id header must match the Client ID in the access token.\r\nThe Authorization header is required and must specify an app access token or user access token.\r\nThe access token is not valid.",
+ HttpStatusCode.Forbidden => "The organization associated with the client in the access token must own the game specified in the game_id query parameter.\r\nThe organization associated with the client in the access token must own the entitlements specified in the id query parameter.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateDropsEntitlements = new()
+ {
+ Method = HttpMethod.Patch,
+ Route = "/entitlements/drops",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully requested the updates.\r\n Check the response to determine which updates succeeded.",
+ HttpStatusCode.BadRequest => "The value in the fulfillment_status field is not valid.\r\nThe client in the access token is not associated with a known organization.\r\nThe owner of the client in the access token is not a member of the organization.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetExtensionConfigurationSegment = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/extensions/configurations",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the configurations.",
+ HttpStatusCode.BadRequest => "The extension_id query parameter is required.\r\nThe value in the segment query parameter is not valid.\r\nThe broadcaster_id query parameter is required if the segment query parameter is set to broadcaster or developer.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a JWT token.\r\nThe JWT token is not valid.\r\nThe Client-Id header is required.",
+ HttpStatusCode.TooManyRequests => "The app exceeded the number of requests that it may make per minute.\r\n See Rate Limits above.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint SetExtensionConfigurationSegment = new()
+ {
+ Method = HttpMethod.Put,
+ Route = "/extensions/configurations",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully updated the configuration.",
+ HttpStatusCode.BadRequest => "The broadcaster_id field is required if segment is set to developer or broadcaster.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a JWT token.\r\nThe JWT token is not valid.\r\nThe Client-Id header is required.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint SetExtensionRequiredConfiguration = new()
+ {
+ Method = HttpMethod.Put,
+ Route = "/extensions/required_configuration",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully updated the extension's required_configuration string.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe extension_id field is required.\r\nThe extension_version field is required.\r\nThe required_configuration field is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a JWT token.\r\nThe JWT token is not valid.\r\nThe Client-Id header is required.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint SendExtensionPubSubMessage = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/extensions/pubsub",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully sent the message.",
+ HttpStatusCode.BadRequest => "The broadcaster_id field in the request's body may only be set if the is_global_broadcast field is set to false.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a JWT token.\r\nThe JWT token is not valid.\r\nThe Client-Id header is required.",
+ HttpStatusCode.UnprocessableEntity => "The message is too large.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetExtensionLiveChannels = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/extensions/live",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of broadcasters.",
+ HttpStatusCode.BadRequest => "The extension_id query parameter is required.\r\nThe pagination cursor is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ HttpStatusCode.NotFound => "The extension specified in the extension_id query parameter was not found or it's not being used in a live stream.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetExtensionSecrets = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/extensions/jwt/secrets",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of secrets.",
+ HttpStatusCode.BadRequest => "The extension_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a JWT token.\r\nThe JWT token is not valid.\r\nThe Client-Id header is required.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CreateExtensionSecret = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/extensions/jwt/secrets",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully created the new secret.",
+ HttpStatusCode.BadRequest => "The extension_id query parameter is required.\r\nThe delay specified in the delay query parameter is too short.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a JWT token.\r\nThe JWT token is not valid.\r\nThe Client-Id header is required.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint SendExtensionChatMessage = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/extensions/chat",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully sent the chat message.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe extension_id field in the request's body is required.\r\nThe extension_version field in the request's body is required.\r\nThe text field in the request's body is required.\r\nThe message is too long.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a JWT token.\r\nThe ID in the broadcaster_id query parameter must match the channel_id claim in the JWT.\r\nThe JWT token is not valid.\r\nThe Client-Id header is required.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetExtensions = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/extensions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of extensions.",
+ HttpStatusCode.BadRequest => "The extension_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The request must specify the Authorization header.\r\nThe Authorization header is required and must specify a JWT token.\r\nThe JWT token is not valid.\r\nThe request must specify the Client-Id header.",
+ HttpStatusCode.NotFound => "The extension in the extension_id query parameter was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetReleasedExtensions = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/extensions/released",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the extension.",
+ HttpStatusCode.BadRequest => "The extension_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header must specify an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ HttpStatusCode.NotFound => "The extension specified in the extension_id query parameter was not found or is not released.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetExtensionBitsProducts = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/bits/extensions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of products.",
+ HttpStatusCode.BadRequest => "The ID in the Client-Id header must belong to an extension.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token; you may not specify a user access token.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateExtensionBitsProduct = new()
+ {
+ Method = HttpMethod.Put,
+ Route = "/bits/extensions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully created the product.",
+ HttpStatusCode.BadRequest => "The sku field is required.\r\nThe value in the sku field is not valid.\r\n The SKU may contain only alphanumeric characters, dashes (-), underscores (_), and periods (.\r\n).\r\nThe cost object's amount field is required.\r\nThe value in the cost object's amount field is not valid.\r\nThe cost object's type field is required.\r\nThe value in the cost object's type field is not valid.\r\nThe display_name field is required.\r\nThe ID in the Client-Id header must belong to the extension.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token; you may not specify a user access token.\r\nThe OAuth token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CreateEventSubSubscription = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/eventsub/subscriptions",
+ SuccessStatusCode = HttpStatusCode.Accepted,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.Accepted => "Successfully accepted the subscription request.",
+ HttpStatusCode.BadRequest => "The condition field is required.\r\nThe user specified in the condition object does not exist.\r\nThe condition object is missing one or more required fields.\r\nThe combination of values in the version and type fields is not valid.\r\nThe length of the string in the secret field is not valid.\r\nThe URL in the transport's callback field is not valid.\r\n The URL must use the HTTPS protocol and the 443 port number.\r\nThe value specified in the method field is not valid.\r\nThe callback field is required if you specify the webhook transport method.\r\nThe session_id field is required if you specify the WebSocket transport method.\r\nThe combination of subscription type and version is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token if the transport method is webhook.\r\nThe Authorization header is required and must specify a user access token if the transport method is WebSocket.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ HttpStatusCode.Forbidden => "The access token is missing the required scopes.",
+ HttpStatusCode.Conflict => "A subscription already exists for the specified event type and condition combination.",
+ HttpStatusCode.TooManyRequests => "The request exceeds the number of subscriptions that you may create with the same combination of type and condition values.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint DeleteEventSubSubscription = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/eventsub/subscriptions",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully deleted the subscription.",
+ HttpStatusCode.BadRequest => "The id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ HttpStatusCode.NotFound => "The subscription was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetEventSubSubscriptions = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/eventsub/subscriptions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the subscriptions.",
+ HttpStatusCode.BadRequest => "The request may specify only one filter query parameter.\r\n For example, either type or status or user_id.\r\nThe value in the type query parameter is not valid.\r\nThe value in the status query parameter is not valid.\r\nThe cursor specified in the after query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetTopGames = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/games/top",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of broadcasts.",
+ HttpStatusCode.BadRequest => "The value in the first query parameter is not valid.\r\nThe cursor in the after or before query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetGames = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/games",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the specified games.",
+ HttpStatusCode.BadRequest => "The request must specify the id or name or igdb_id query parameter.\r\nThe combined number of game IDs (id and igdb_id) and game names that you specify in the request must not exceed 100.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetCreatorGoals = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/goals",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's goals.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:read:goals scope.\r\nThe ID in broadcaster_id must match the user ID in the user access token.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetChannelGuestStarSettings = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/guest_star/channel_settings",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.BadRequest => "Missing broadcaster_id Missing moderator_id",
+ HttpStatusCode.Forbidden => "Insufficient authorization for viewing channel's Guest Star settings",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateChannelGuestStarSettings = new()
+ {
+ Method = HttpMethod.Put,
+ Route = "/guest_star/channel_settings",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully updated channel settings",
+ HttpStatusCode.BadRequest => "Missing broadcaster_id Invalid slot_count Invalid group_layout",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetGuestStarSession = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/guest_star/session",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.BadRequest => "Missing broadcaster_id Missing moderator_id",
+ HttpStatusCode.Unauthorized => "moderator_id and user token do not match",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CreateGuestStarSession = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/guest_star/session",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.BadRequest => "Missing broadcaster_id Session limit reached (1 active call)",
+ HttpStatusCode.Unauthorized => "Phone verification missing",
+ HttpStatusCode.Forbidden => "Insufficient authorization for creating session",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint EndGuestStarSession = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/guest_star/session",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.BadRequest => "Missing or invalid broadcaster_id Missing or invalid session_id Session has already been ended",
+ HttpStatusCode.Forbidden => "Insufficient authorization for ending session",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetGuestStarInvites = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/guest_star/invites",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.BadRequest => "Missing broadcaster_id Missing session_id",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint SendGuestStarInvite = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/guest_star/invites",
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.BadRequest => "Missing broadcaster_id Missing moderator_id Missing session_id Missing guest_id Invalid session_id",
+ HttpStatusCode.Forbidden => "Unauthorized guest invited Guest already invited",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint DeleteGuestStarInvite = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/guest_star/invites",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.BadRequest => "Missing broadcaster_id Missing session_id Missing guest_id Invalid session_id",
+ HttpStatusCode.NotFound => "No invite exists for specified guest_id",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint AssignGuestStarSlot = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/guest_star/slot",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfuly assigned guest to slot",
+ HttpStatusCode.BadRequest => "Missing broadcaster_id Missing moderator_id Missing guest_id Missing or invalid session_id Missing or invalid slot_id",
+ HttpStatusCode.Unauthorized => "moderator_id is not a guest star moderator",
+ HttpStatusCode.Forbidden => "Cannot assign host slot Guest not invited to session Guest already assigned to slot Guest is not ready to join",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateGuestStarSlot = new()
+ {
+ Method = HttpMethod.Patch,
+ Route = "/guest_star/slot",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfuly updated slot(s)",
+ HttpStatusCode.BadRequest => "Missing broadcaster_id Missing or invalid session_id Missing or invalid slot_id",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint DeleteGuestStarSlot = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/guest_star/slot",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfuly removed user from slot",
+ HttpStatusCode.BadRequest => "Missing broadcaster_id Missing moderator_id Missing or invalid session_id Missing or invalid slot_id",
+ HttpStatusCode.Forbidden => "moderator_id is not a Guest Star moderator The request is attempting to modify a restricted slot",
+ HttpStatusCode.NotFound => "guest_id or slot_id not found",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateGuestStarSlotSettings = new()
+ {
+ Method = HttpMethod.Patch,
+ Route = "/guest_star/slot_settings",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfuly updated slot settings",
+ HttpStatusCode.BadRequest => "Missing broadcaster_id Missing moderator_id Missing or invalid session_id Missing or invalid slot_id",
+ HttpStatusCode.Forbidden => "moderator_id is not a Guest Star moderator The request is attempting to modify a restricted slot",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetHypeTrainEvents = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/hypetrain/events",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's Hype Train events.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user_id in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:read:hype_train scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CheckAutoModStatus = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/moderation/enforcements/status",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully checked the messages.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe data field is required and the list must contain one or more messages to check.\r\nThe msg_id field is required.\r\nThe msg_text field is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderation:read scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The ID in broadcaster_id must match the user ID in the user access token.",
+ HttpStatusCode.TooManyRequests => "The broadcaster exceeded the number of chat message checks that they may make.\r\n See the endpoint's rate limits.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint ManageHeldAutoModMessages = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/moderation/automod/message",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully approved or denied the message.",
+ HttpStatusCode.BadRequest => "The value in the action field is not valid.\r\nThe user_id field is required.\r\nThe msg_id field is required.\r\nThe action field is required.",
+ HttpStatusCode.Unauthorized => "The ID in user_id must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:manage:automod scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in user_id is not one of the broadcaster's moderators.",
+ HttpStatusCode.NotFound => "The message specified in the msg_id field was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetAutoModSettings = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/moderation/automod/settings",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's AutoMod settings.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe moderator_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in moderator_id must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:read:automod_settings scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in moderator_id is not one of the broadcaster's moderators.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateAutoModSettings = new()
+ {
+ Method = HttpMethod.Put,
+ Route = "/moderation/automod/settings",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully updated the broadcaster's AutoMod settings.",
+ HttpStatusCode.BadRequest => "The broadcaster_id is required.\r\nThe moderator_id is required.\r\nThe overall_level setting or one or more individual settings like aggression is required; the overall and individual settings are mutually exclusive, so don't set both.\r\nThe value of one or more AutoMod settings is not valid.",
+ HttpStatusCode.Unauthorized => "The ID in moderator_id must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:manage:automod_settings scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in moderator_id is not one of the broadcaster's moderators.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetBannedUsers = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/moderation/banned",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of banned users.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderation:read scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint BanUser = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/moderation/bans",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully banned the user or placed them in a timeout.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe moderator_id query parameter is required.\r\nThe user_id field is required.\r\nThe text in the reason field is too long.\r\nThe value in the duration field is not valid.\r\nThe user specified in the user_id field may not be banned.\r\nThe user specified in the user_id field may not be put in a timeout.\r\nThe user specified in the user_id field is already banned.",
+ HttpStatusCode.Unauthorized => "The ID in moderator_id must match the user ID in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:manage:banned_users scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in moderator_id is not one of the broadcaster's moderators.",
+ HttpStatusCode.Conflict => "You may not update the user's ban state while someone else is updating the state.\r\n For example, someone else is currently banning the user or putting them in a timeout, moving the user from a timeout to a ban, or removing the user from a ban or timeout.\r\n Please retry your request.",
+ HttpStatusCode.TooManyRequests => "The app has exceeded the number of requests it may make per minute for this broadcaster.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UnbanUser = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/moderation/bans",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully removed the ban or timeout.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe moderator_id query parameter is required.\r\nThe user_id query parameter is required.\r\nThe user specified in the user_id query parameter is not banned.",
+ HttpStatusCode.Unauthorized => "The ID in moderator_id must match the user ID in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:manage:banned_users scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in moderator_id is not one of the broadcaster's moderators.",
+ HttpStatusCode.Conflict => "You may not update the user's ban state while someone else is updating the state.\r\n For example, someone else is currently removing the ban or timeout, or they're moving the user from a timeout to a ban.\r\n Please retry your request.",
+ HttpStatusCode.TooManyRequests => "The app has exceeded the number of requests it may make per minute for this broadcaster.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetBlockedTerms = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/moderation/blocked_terms",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of blocked terms.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe moderator_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in moderator_id must match the user ID in the user access token.\r\nThe Authorization header must contain a user access token.\r\nThe user access token must include the moderator:read:blocked_terms scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in moderator_id is not one of the broadcaster's moderators.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint AddBlockedTerm = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/moderation/blocked_terms",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of blocked terms.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe moderator_id query parameter is required.\r\nThe text field is required.\r\nThe length of the term in the text field is either too short or too long.",
+ HttpStatusCode.Unauthorized => "The ID in moderator_id must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:manage:blocked_terms scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in moderator_id is not one of the broadcaster's moderators.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint RemoveBlockedTerm = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/moderation/blocked_terms",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully removed the blocked term.\r\n Also returned if the ID is not found.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe moderator_id query parameter is required.\r\nThe id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in moderator_id must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:manage:blocked_terms scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in moderator_id is not one of the broadcaster's moderators.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint DeleteChatMessages = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/moderation/chat",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully removed the specified messages.",
+ HttpStatusCode.BadRequest => "You may not delete another moderator's messages.\r\nYou may not delete the broadcaster's messages.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token is missing the moderator:manage:chat_messages scope.\r\nThe OAuth token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ HttpStatusCode.Forbidden => "The user in moderator_id is not one of the broadcaster's moderators.",
+ HttpStatusCode.NotFound => "The ID in message_id was not found.\r\nThe specified message was created more than 6 hours ago.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetModerators = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/moderation/moderators",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of moderators.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID found in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderation:read scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint AddChannelModerator = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/moderation/moderators",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully added the moderator.",
+ HttpStatusCode.BadRequest => "The ID in broadcaster_id was not found.\r\nThe ID in user_id was not found.\r\nThe user in user_id is already a moderator in the broadcaster's chat room.\r\nThe user in user_id cannot become a moderator because they're banned from the channel.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:moderators scope.\r\nThe access token is not valid.\r\nThe ID in the broadcaster_id query parameter must match the user ID in the access token.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.UnprocessableEntity => "The user in user_id is a VIP.\r\n To make them a moderator, you must first remove them as a VIP (see Remove Channel VIP).",
+ HttpStatusCode.TooManyRequests => "The broadcaster has exceeded the number of requests allowed within a 10-second window.\r\n See this endpoint's rate limits.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint RemoveChannelModerator = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/moderation/moderators",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully removed the moderator.",
+ HttpStatusCode.BadRequest => "The ID in broadcaster_id was not found.\r\nThe ID in user_id was not found.\r\nThe user in user_id is not a moderator in the broadcaster's chat room.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:moderators scope.\r\nThe access token is not valid.\r\nThe ID in the broadcaster_id query parameter must match the user ID in the access token.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.TooManyRequests => "The broadcaster has exceeded the number of requests allowed within a 10-second window.\r\n See this endpoint's rate limits.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetVIPs = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/channels/vips",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's list of VIPs.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe ID in the user_id query parameter is not valid.\r\nThe number of user_id query parameters exceeds the maximum allowed.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:read:vips or channel:manage:vips scope.\r\nThe OAuth token is not valid.\r\nThe ID in the broadcaster_id query parameter must match the user ID in the access token.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint AddChannelVIP = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/channels/vips",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => (int)code switch
+ {
+ (int)HttpStatusCode.NoContent => "Successfully added the VIP.",
+ (int)HttpStatusCode.BadRequest => "The user in the user_id query parameter is blocked from the broadcaster's channel.\r\nThe ID in the broadcaster_id query parameter is not valid.\r\nThe ID in the user_id query parameter is not valid.",
+ (int)HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:vips scope.\r\nThe OAuth token is not valid.\r\nThe ID in the broadcaster_id query parameter must match the user ID in the access token.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ (int)HttpStatusCode.Forbidden => "The ID in the broadcaster_id query parameter must match the user ID in the access token.",
+ (int)HttpStatusCode.NotFound => "The ID in broadcaster_id was not found.\r\nThe ID in user_id was not found.",
+ (int)HttpStatusCode.Conflict => "The broadcaster doesn't have available VIP slots.\r\n Read More",
+ (int)HttpStatusCode.UnprocessableEntity => "The user in user_id is a moderator.\r\n To make them a VIP, you must first remove them as a moderator (see Remove Channel Moderator).\r\nThe user in the user_id query parameter is already a VIP.",
+ 425 => "The broadcaster must complete the Build a Community requirement before they may assign VIPs.",
+ (int)HttpStatusCode.TooManyRequests => "The broadcaster exceeded the number of VIP that they may add within a 10-second window.\r\n See Rate Limits for this endpoint above.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint RemoveChannelVIP = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/channels/vips",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully removed the VIP status from the user.",
+ HttpStatusCode.BadRequest => "The ID in broadcaster_id is not valid.\r\nThe ID in user_id is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:vips scope.\r\nThe OAuth token is not valid.\r\nThe ID in the broadcaster_id query parameter must match the user ID in the access token.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the OAuth token.",
+ HttpStatusCode.Forbidden => "The user in broadcaster_id doesn't have permission to remove the user's VIP status.",
+ HttpStatusCode.NotFound => "The ID in broadcaster_id was not found.\r\nThe ID in user_id was not found.",
+ HttpStatusCode.UnprocessableEntity => "The user in user_id is not a VIP in the broadcaster's channel.",
+ HttpStatusCode.TooManyRequests => "The broadcaster exceeded the number of VIPs that they may remove within a 10-second window.\r\n See Rate Limits for this endpoint above.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateShieldModeStatus = new()
+ {
+ Method = HttpMethod.Put,
+ Route = "/moderation/shield_mode",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully updated the broadcaster's Shield Mode status.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe ID in the broadcaster_id query parameter is not valid.\r\nThe is_active field is required.\r\nThe value in the is_active field is not valid.",
+ HttpStatusCode.Unauthorized => "The ID in moderator_id must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:manage:shield_mode scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in moderator_id is not one of the broadcaster's moderators.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetShieldModeStatus = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/moderation/shield_mode",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's Shield Mode activation status.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe ID in the broadcaster_id query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The ID in moderator_id must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the moderator:read:shield_mode or moderator:manage:shield_mode scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in moderator_id is not one of the broadcaster's moderators.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetPolls = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/polls",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's polls.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token is missing the channel:read:polls scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header must match the client ID specified in the access token.",
+ HttpStatusCode.NotFound => "None of the IDs in the id query parameters were found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CreatePoll = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/polls",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully created the poll.",
+ HttpStatusCode.BadRequest => "The broadcaster_id field is required.\r\nThe title field is required.\r\nThe choices field is required.\r\nThe duration field is required.\r\nThe value in duration is outside the allowed range of values.\r\nThe value in channel_points_per_vote is outside the allowed range of values.\r\nThe value in bits_per_vote is outside the allowed range of values.\r\nThe poll's title is too long.\r\nThe choice's title is too long.\r\nThe choice's title failed AutoMod checks.\r\nThe number of choices in the poll may not be less than 2 or greater that 5.\r\nThe broadcaster already has a poll that's running; you may not create another poll until the current poll completes.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token is missing the channel:manage:polls scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint EndPoll = new()
+ {
+ Method = HttpMethod.Patch,
+ Route = "/polls",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully ended the poll.",
+ HttpStatusCode.BadRequest => "The broadcaster_id field is required.\r\nThe id field is required.\r\nThe status field is required.\r\nThe value in the status field is not valid.\r\nThe poll must be active to terminate or archive it.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:polls scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header must match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetPredictions = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/predictions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of predictions.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:read:predictions scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CreatePrediction = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/predictions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully created the Channel Points Prediction.",
+ HttpStatusCode.BadRequest => "The broadcaster_id field is required.\r\nThe title field is required.\r\nThe outcomes field is required.\r\nThe prediction_window field is required.\r\nThe value in prediction_window is outside the allowed range of values.\r\nThe prediction's title is too long.\r\nThe outcome's title is too long.\r\nThe outcome's title failed AutoMod checks.\r\nThere must be 2 outcomes in the prediction.\r\nThe broadcaster already has a prediction that's running; you may not create another prediction until the current prediction is resolved or canceled.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:predictions scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint EndPrediction = new()
+ {
+ Method = HttpMethod.Patch,
+ Route = "/predictions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully ended the prediction.",
+ HttpStatusCode.BadRequest => "The broadcaster_id field is required.\r\nThe id field is required.\r\nThe status field is required.\r\nThe winning_outcome_id field is required if status is RESOLVED.\r\nThe value in the status field is not valid.\r\nTo update the prediction's status to RESOLVED or CANCELED, its current status must be ACTIVE or LOCKED.\r\nTo update the prediction's status to LOCKED, its current status must be ACTIVE.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID in the OAuth token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:predictions scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.NotFound => "The prediction in the id field was not found.\r\nThe outcome in the winning_outcome_id field was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint StartARaid = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/raids",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully requested to start a raid.\r\n To determine whether the raid successfully occurred (that is, the broadcaster clicked Raid Now or the countdown expired), you must subscribe to the Channel Raid event.",
+ HttpStatusCode.BadRequest => "The raiding broadcaster is blocked from the targeted channel.\r\nThe targeted channel doesn't accept raids from this broadcaster.\r\nThere are too many viewers in the raiding party.\r\nThe IDs in from_broadcaster_id and to_broadcaster_id cannot be the same ID.\r\nThe ID in the from_broadcaster_id query parameter is not valid.\r\nThe ID in the to_broadcaster_id query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The ID in from_broadcaster_id must match the user ID found in the request's OAuth token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:raids scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.NotFound => "The targeted channel was not found.",
+ HttpStatusCode.Conflict => "The broadcaster is already in the process of raiding another channel.",
+ HttpStatusCode.TooManyRequests => "The broadcaster exceeded the number of raid requests that they may make.\r\n The limit is 10 requests within a 10-minute window.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CancelARaid = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/raids",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "The pending raid was successfully canceled.",
+ HttpStatusCode.BadRequest => "The ID in the broadcaster_id query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID found in the request's OAuth token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:raids scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.NotFound => "The broadcaster doesn't have a pending raid to cancel.",
+ HttpStatusCode.TooManyRequests => "The broadcaster exceeded the number of raid requests that they may make.\r\n The limit is 10 requests within a 10-minute window.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetChannelStreamSchedule = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/schedule",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's streaming schedule.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe ID in the broadcaster_id query parameter is not valid.\r\nThe ID in the id query parameter is not valid.\r\nThe format of the date and time in the start_time query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify a valid app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the access token.",
+ HttpStatusCode.Forbidden => "Only partners and affiliates may add non-recurring broadcast segments.",
+ HttpStatusCode.NotFound => "The broadcaster has not created a streaming schedule.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetChannelICalendar = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/schedule/icalendar",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's schedule as an iCalendar.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe ID in the broadcaster_id query parameter is not valid.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateChannelStreamSchedule = new()
+ {
+ Method = HttpMethod.Patch,
+ Route = "/schedule/settings",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully updated the broadcaster's schedule settings.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe ID in the broadcaster_id query parameter is not valid.\r\nThe format of the string in vacation_start_time is not valid.\r\nThe format of the string in vacation_end_time is not valid.\r\nThe date in vacation_end_time must be later than the date in vacation_start_time.",
+ HttpStatusCode.Unauthorized => "The ID in the broadcaster_id query parameter must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:schedule scope.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ HttpStatusCode.NotFound => "The broadcaster's schedule was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CreateChannelStreamScheduleSegment = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/schedule/segment",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully added the broadcast segment.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe ID in the broadcaster_id query parameter is not valid.\r\nThe format of the date and time in the start_time field is not valid.\r\nThe value in the timezone field is not valid.\r\nThe value in the duration field is not valid.\r\nThe ID in the category_id field is not valid.\r\nThe string in the title field is too long.",
+ HttpStatusCode.Unauthorized => "The ID in the broadcaster_id query parameter must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:schedule scope.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ HttpStatusCode.Forbidden => "Only partners and affiliates may add non-recurring broadcast segments.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateChannelStreamScheduleSegment = new()
+ {
+ Method = HttpMethod.Patch,
+ Route = "/schedule/segment",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully updated the broadcast segment.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe ID in the broadcaster_id query parameter is not valid.\r\nThe id query parameter is required.\r\nThe ID in the id query parameter is not valid.\r\nThe format of the date and time in the start_time field is not valid.\r\nThe value in the timezone field is not valid.\r\nThe value in the duration field is not valid.\r\nThe ID in the category_id field is not valid.\r\nThe string in the title field is too long.",
+ HttpStatusCode.Unauthorized => "The ID in the broadcaster_id query parameter must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:schedule scope.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ HttpStatusCode.NotFound => "The specified broadcast segment was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint DeleteChannelStreamScheduleSegment = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/schedule/segment",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully removed the broadcast segment.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe ID in the broadcaster_id query parameter is not valid.\r\nThe id query parameter is required.\r\nThe ID in the id query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The ID in the broadcaster_id query parameter must match the user ID in the user access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:schedule scope.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the OAuth token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint SearchCategories = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/search/categories",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of category names that matched the specified query string.",
+ HttpStatusCode.BadRequest => "The query query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain an app access token or user access token.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint SearchChannels = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/search/channels",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of category names that matched the specified query string.",
+ HttpStatusCode.BadRequest => "The query query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain an app access token or user access token.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetSoundtrackCurrentTrack = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/soundtrack/current_track",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the track that the broadcaster is playing.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ HttpStatusCode.NotFound => "The broadcaster is not playing a track.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetSoundtrackPlaylist = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/soundtrack/playlist",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the playlist.",
+ HttpStatusCode.BadRequest => "The id query parameter is required.\r\nThe ID in the id query parameter is not a valid playlist ASIN.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ HttpStatusCode.NotFound => "The specified playlist was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetSoundtrackPlaylists = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/soundtrack/playlists",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of playlists.",
+ HttpStatusCode.BadRequest => "The ID in the id query parameter is not a valid playlist ASIN.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the client ID in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetStreamKey = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/streams/key",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the stream's key.",
+ HttpStatusCode.BadRequest => "The broadcaster_id field is required.\r\nThe ID in the broadcaster_id field is not valid.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:read:stream_key scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header must match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetStreams = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/streams",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of streams.",
+ HttpStatusCode.BadRequest => "The value in the type query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetFollowedStreams = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/streams/followed",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of broadcasters that the user follows and that are streaming live.",
+ HttpStatusCode.BadRequest => "The user_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in user_id must match the user ID found in the access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:read:follows scope.\r\nThe OAuth token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CreateStreamMarker = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/streams/markers",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully created the marker.",
+ HttpStatusCode.BadRequest => "The user_id field is required.\r\nThe length of the string in the description field is too long.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:manage:broadcast scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in the access token is not authorized to create video markers for the user in the user_id field.\r\n The user in the access token must own the video or they must be one of the broadcaster's editors.",
+ HttpStatusCode.NotFound => "The user in the user_id field is not streaming live.\r\nThe ID in the user_id field is not valid.\r\nThe user hasn't enabled video on demand (VOD).",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetStreamMarkers = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/streams/markers",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of markers.",
+ HttpStatusCode.BadRequest => "The request must specify either the user_id or video_id query parameter, but not both.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:read:broadcast or user:manage:broadcast scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "The user in the access token is not authorized to get the video's markers.\r\n The user in the access token must own the video or be one of the broadcaster's editors.",
+ HttpStatusCode.NotFound => "The user specified in the user_id query parameter doesn't have videos.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetBroadcasterSubscriptions = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/subscriptions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's list of subscribers.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID found in the request's OAuth token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:read:subscriptions scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint CheckUserSubscription = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/subscriptions/user",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "The user subscribes to the broadcaster.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.\r\nThe user_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in user_id must match the user ID found in the request's OAuth token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:read:subscriptions scope.\r\nThe access token is not valid.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.NotFound => "The user in user_id does not subscribe to the broadcaster in broadcaster_id.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetAllStreamTags = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/tags/streams",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of tags.",
+ HttpStatusCode.BadRequest => "The tag_id query parameter is empty (for example, &tag_id=).\r\nThe list of tag IDs is too long.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetStreamTags = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/streams/tags",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of tags.",
+ HttpStatusCode.BadRequest => "The broadcaster_id field is required.\r\nThe ID in the broadcaster_id field is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must specify an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID in the Client-Id header must match the Client ID in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetChannelTeams = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/teams/channel",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of teams.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header must contain an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.NotFound => "The broadcaster was not found.\r\nThe broadcaster is not a member of a team.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetTeams = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/teams",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the team's information.",
+ HttpStatusCode.BadRequest => "The name or id query parameter is required.\r\nSpecify either the name or id query parameter but not both.\r\nThe ID in the id query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header must contain an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.NotFound => "The specified team was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetUsers = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/users",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the specified users' information.",
+ HttpStatusCode.BadRequest => "The id or login query parameter is required unless the request uses a user access token.\r\nThe request exceeded the maximum allowed number of id and/or login query parameters.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateUser = new()
+ {
+ Method = HttpMethod.Put,
+ Route = "/users",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully updated the specified user's information.",
+ HttpStatusCode.BadRequest => "The string in the description query parameter is too long.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:edit scope.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetUsersFollows = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/users/follows",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the follows information.",
+ HttpStatusCode.BadRequest => "The from_id query parameter, to_id query parameter, or both parameters are required.\r\nThe ID in the from_id query parameter is not validThe ID in the to_id query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetUserBlockList = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/users/blocks",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the broadcaster's list of blocked users.",
+ HttpStatusCode.BadRequest => "The broadcaster_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The ID in broadcaster_id must match the user ID found in the request's access token.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:read:blocked_users scope.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint BlockUser = new()
+ {
+ Method = HttpMethod.Put,
+ Route = "/users/blocks",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully blocked the user.",
+ HttpStatusCode.BadRequest => "The target_user_id query parameter is required.\r\nThe ID in target_user_id cannot be the same as the user ID in the access token.\r\nThe value in source_context is not valid.\r\nThe value in reason is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:manage:blocked_users scope.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UnblockUser = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/users/blocks",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully removed the block.",
+ HttpStatusCode.BadRequest => "The target_user_id query parameter is required.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:read:blocked_users scope.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetUserExtensions = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/users/extensions/list",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the user's installed extensions.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:read:broadcast scope.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetUserActiveExtensions = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/users/extensions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the user's active extensions.",
+ HttpStatusCode.BadRequest => "The user_id query parameter is required if you specify an app access token.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint UpdateUserExtensions = new()
+ {
+ Method = HttpMethod.Put,
+ Route = "/users/extensions",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully updated the active extensions.",
+ HttpStatusCode.BadRequest => "The JSON payload is malformed.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:edit:broadcast scope.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.NotFound => "An extension with the specified id and version values was not found.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetVideos = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/videos",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully retrieved the list of videos.",
+ HttpStatusCode.BadRequest => "The request must specify either the id or user_id or game_id query parameter.\r\nThe id, user_id, and game_id query parameters are mutually exclusive; you must specify only one of them.\r\nThe value in the id query parameter is not valid.\r\nThe ID in the game_id query parameter is not valid.\r\nThe value in the type query parameter is not valid.\r\nThe value in the period query parameter is not valid.\r\nThe value in the sort query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The Authorization header is required and must contain an app access token or user access token.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.NotFound => "The ID in the game_id query parameter was not found.\r\nThe ID in the id query parameter was not found.\r\n Returned only if all the IDs were not found; otherwise, the ID is ignored.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint DeleteVideos = new()
+ {
+ Method = HttpMethod.Delete,
+ Route = "/videos",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Successfully deleted the list of videos.",
+ HttpStatusCode.BadRequest => "The id query parameter is required.\r\nThe request exceeded the number of allowed id query parameters.",
+ HttpStatusCode.Unauthorized => "The caller is not authorized to delete the specified video.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the channel:manage:videos scope.\r\nThe access token is not valid.\r\nThe ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint SendWhisper = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/whispers",
+ SuccessStatusCode = HttpStatusCode.NoContent,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.NoContent => "Successfully sent the whisper message or the message was silently dropped.",
+ HttpStatusCode.BadRequest => "The ID in the from_user_id and to_user_id query parameters must be different.\r\nThe message field must not contain an empty string.\r\nThe user that you're sending the whisper to doesn't allow whisper messages (see the Block Whispers from Strangers setting in your Security and Privacy settings).\r\nWhisper messages may not be sent to suspended users.\r\nThe ID in the from_user_id query parameter is not valid.\r\nThe ID in the to_user_id query parameter is not valid.",
+ HttpStatusCode.Unauthorized => "The user in the from_user_id query parameter must have a verified phone number.\r\nThe Authorization header is required and must contain a user access token.\r\nThe user access token must include the user:manage:whispers scope.\r\nThe access token is not valid.\r\nThis ID in from_user_id must match the user ID in the user access token.\r\nThe client ID specified in the Client-Id header does not match the client ID specified in the access token.",
+ HttpStatusCode.Forbidden => "Suspended users may not send whisper messages.\r\nThe account that's sending the message doesn't allow sending whispers.",
+ HttpStatusCode.NotFound => "The ID in to_user_id was not found.",
+ HttpStatusCode.TooManyRequests => "The sending user exceeded the number of whisper requests that they may make.\r\n See Rate Limits for this endpoint above.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint SnoozeNextAd = new()
+ {
+ Method = HttpMethod.Post,
+ Route = "/channels/ads/schedule/snooze",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "User’s next ad is successfully snoozed. Their snooze_count is decremented and snooze_refresh_time and next_ad_at are both updated.",
+ HttpStatusCode.BadRequest => "The channel is not currently live.\r\nThe broadcaster ID is not valid.\r\nChannel does not have an upcoming scheduled ad break.",
+ HttpStatusCode.TooManyRequests => "Channel has no snoozes left.",
+ _ => "Unknown response code"
+ }
+ };
+
+ public static readonly HelixEndpoint GetAdSchedule = new()
+ {
+ Method = HttpMethod.Get,
+ Route = "/channels/ads",
+ SuccessStatusCode = HttpStatusCode.OK,
+ GetResponseMessage = code => code switch
+ {
+ HttpStatusCode.OK => "Returns the ad schedule information for the channel.",
+ HttpStatusCode.BadRequest => "The broadcaster ID is not valid.",
+ _ => "Unknown response code"
+ }
+ };
+}
diff --git a/MiniTwitch.Helix/Internal/Models/HelixEndpoint.cs b/MiniTwitch.Helix/Internal/Models/HelixEndpoint.cs
new file mode 100644
index 0000000..a8ae628
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Models/HelixEndpoint.cs
@@ -0,0 +1,11 @@
+using System.Net;
+
+namespace MiniTwitch.Helix.Internal.Models;
+
+internal class HelixEndpoint
+{
+ public HttpMethod Method { get; init; } = default!;
+ public string Route { get; init; } = default!;
+ public HttpStatusCode SuccessStatusCode { get; init; } = HttpStatusCode.OK;
+ public Func GetResponseMessage { get; init; } = default!;
+}
diff --git a/MiniTwitch.Helix/Internal/Models/HelixTask.cs b/MiniTwitch.Helix/Internal/Models/HelixTask.cs
new file mode 100644
index 0000000..84a7130
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Models/HelixTask.cs
@@ -0,0 +1,8 @@
+namespace MiniTwitch.Helix.Internal.Models;
+
+internal readonly struct HelixTask
+{
+ internal HelixEndpoint Endpoint { get; init; }
+ internal RequestData Request { get; init; }
+ internal HelixApiClient Client { get; init; }
+}
diff --git a/MiniTwitch.Helix/Internal/Models/InvalidToken.cs b/MiniTwitch.Helix/Internal/Models/InvalidToken.cs
new file mode 100644
index 0000000..3cd7e3d
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Models/InvalidToken.cs
@@ -0,0 +1,8 @@
+using System.Text.Json.Serialization;
+
+namespace MiniTwitch.Helix.Internal.Models;
+
+public record InvalidToken(
+ [property: JsonPropertyName("status")] int Status,
+ [property: JsonPropertyName("message")] string Message
+ );
diff --git a/MiniTwitch.Helix/Internal/Models/QueryParams.cs b/MiniTwitch.Helix/Internal/Models/QueryParams.cs
new file mode 100644
index 0000000..2c0807a
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Models/QueryParams.cs
@@ -0,0 +1,65 @@
+namespace MiniTwitch.Helix.Internal.Models;
+
+internal static class QueryParams
+{
+ public const string ExtensionId = "extension_id";
+ public const string Type = "type";
+ public const string StartedAt = "started_at";
+ public const string EndedAt = "ended_at";
+ public const string First = "first";
+ public const string GameId = "game_id";
+ public const string Count = "count";
+ public const string Period = "period";
+ public const string UserId = "user_id";
+ public const string BroadcasterId = "broadcaster_id";
+ public const string Id = "id";
+ public const string OnlyManageableRewards = "only_manageable_rewards";
+ public const string RewardId = "reward_id";
+ public const string Status = "status";
+ public const string Sort = "sort";
+ public const string ModeratorId = "moderator_id";
+ public const string FromBroadcasterId = "from_broadcaster_id";
+ public const string ToBroadcasterId = "to_broadcaster_id";
+ public const string Color = "color";
+ public const string HasDelay = "has_delay";
+ public const string IsFeatured = "is_featured";
+ public const string Locale = "locale";
+ public const string FulfillmentStatus = "fulfillment_status";
+ public const string EntitlementIds = "entitlement_ids";
+ public const string Segment = "segment";
+ public const string Delay = "delay";
+ public const string ExtensionVersion = "extension_version";
+ public const string ShouldIncludeAll = "should_include_all";
+ public const string Name = "name";
+ public const string IgdbId = "igdb_id";
+ public const string SessionId = "session_id";
+ public const string GuestId = "guest_id";
+ public const string SlotId = "slot_id";
+ public const string SourceSlotId = "source_slot_id";
+ public const string DestinationSlotId = "destination_slot_id";
+ public const string ShouldReinviteGuest = "should_reinvite_guest";
+ public const string IsAudioEnabled = "is_audio_enabled";
+ public const string IsVideoEnabled = "is_video_enabled";
+ public const string IsLive = "is_live";
+ public const string Volume = "volume";
+ public const string MsgId = "msg_id";
+ public const string Action = "action";
+ public const string MessageId = "message_id";
+ public const string StartTime = "start_time";
+ public const string IsVacationEnabled = "is_vacation_enabled";
+ public const string VacationStartTime = "vacation_start_time";
+ public const string VacationEndTime = "vacation_end_time";
+ public const string Timezone = "timezone";
+ public const string Query = "query";
+ public const string LiveOnly = "live_only";
+ public const string UserLogin = "user_login";
+ public const string Language = "language";
+ public const string VideoId = "video_id";
+ public const string Login = "login";
+ public const string TargetUserId = "target_user_id";
+ public const string SourceContext = "source_context";
+ public const string Reason = "reason";
+ public const string FromUserId = "from_user_id";
+ public const string ToUserId = "to_user_id";
+ public const string After = "after";
+}
diff --git a/MiniTwitch.Helix/Internal/Models/RequestData.cs b/MiniTwitch.Helix/Internal/Models/RequestData.cs
new file mode 100644
index 0000000..380bfd1
--- /dev/null
+++ b/MiniTwitch.Helix/Internal/Models/RequestData.cs
@@ -0,0 +1,72 @@
+using System.Text;
+
+namespace MiniTwitch.Helix.Internal.Models;
+
+internal class RequestData
+{
+ public object Body { get; set; } = default!;
+
+ internal readonly string _method;
+ private readonly string _url;
+ private readonly StringBuilder _paramBuilder = new();
+
+ public RequestData(string requestUrl, HelixEndpoint endpoint)
+ {
+ _url = requestUrl + endpoint.Route;
+ _method = endpoint.Method.Method;
+ }
+
+ public string GetUrl() => _url + _paramBuilder.ToString();
+
+ public RequestData AddParam(string key, object? value)
+ {
+ if (value is null)
+ return this;
+
+ if (_paramBuilder.Length == 0)
+ _paramBuilder.Append('?');
+ else
+ _paramBuilder.Append('&');
+
+ _paramBuilder.Append($"{key}={value}");
+ return this;
+ }
+
+ public RequestData AddMultiParam(string key, IEnumerable