mirror of https://git.sr.ht/~ashkeel/strimertul
389 lines
12 KiB
TypeScript
389 lines
12 KiB
TypeScript
export enum EventSubNotificationType {
|
|
ChannelUpdated = 'channel.update',
|
|
UserUpdated = 'user.update',
|
|
Cheered = 'channel.cheer',
|
|
Raided = 'channel.raid',
|
|
CustomRewardAdded = 'channel.channel_points_custom_reward.add',
|
|
CustomRewardRemoved = 'channel.channel_points_custom_reward.remove',
|
|
CustomRewardUpdated = 'channel.channel_points_custom_reward.update',
|
|
CustomRewardRedemptionAdded = 'channel.channel_points_custom_reward_redemption.add',
|
|
CustomRewardRedemptionUpdated = 'channel.channel_points_custom_reward_redemption.update',
|
|
Followed = 'channel.follow',
|
|
GoalBegan = 'channel.goal.begin',
|
|
GoalEnded = 'channel.goal.end',
|
|
GoalProgress = 'channel.goal.progress',
|
|
HypeTrainBegan = 'channel.hype_train.begin',
|
|
HypeTrainEnded = 'channel.hype_train.end',
|
|
HypeTrainProgress = 'channel.hype_train.progress',
|
|
ModeratorAdded = 'channel.moderator.add',
|
|
ModeratorRemoved = 'channel.moderator.remove',
|
|
PollBegan = 'channel.poll.begin',
|
|
PollEnded = 'channel.poll.end',
|
|
PollProgress = 'channel.poll.progress',
|
|
PredictionBegan = 'channel.prediction.begin',
|
|
PredictionEnded = 'channel.prediction.end',
|
|
PredictionLocked = 'channel.prediction.lock',
|
|
PredictionProgress = 'channel.prediction.progress',
|
|
StreamWentOffline = 'stream.offline',
|
|
StreamWentOnline = 'stream.online',
|
|
Subscription = 'channel.subscribe',
|
|
SubscriptionEnded = 'channel.subscription.end',
|
|
SubscriptionGifted = 'channel.subscription.gift',
|
|
SubscriptionWithMessage = 'channel.subscription.message',
|
|
ViewerBanned = 'channel.ban',
|
|
ViewerUnbanned = 'channel.unban',
|
|
}
|
|
|
|
export interface EventSubSubscription {
|
|
id: string;
|
|
type: EventSubNotificationType;
|
|
version: string;
|
|
status: string;
|
|
created_at: string;
|
|
cost: number;
|
|
}
|
|
|
|
export interface EventSubNotification {
|
|
subscription: EventSubSubscription;
|
|
event: unknown;
|
|
date?: string;
|
|
}
|
|
|
|
export const unwrapEvent = (message: EventSubNotification) =>
|
|
({
|
|
type: message.subscription.type,
|
|
subscription: message.subscription,
|
|
event: message.event,
|
|
}) as EventSubMessage;
|
|
|
|
interface TypedEventSubNotification<T extends EventSubNotificationType, Payload> {
|
|
type: T;
|
|
subscription: EventSubSubscription;
|
|
event: Payload;
|
|
}
|
|
|
|
export type EventSubMessage =
|
|
| TypedEventSubNotification<EventSubNotificationType.ChannelUpdated, ChannelUpdatedEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.UserUpdated, UserUpdatedEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.Cheered, CheerEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.Raided, RaidEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.CustomRewardAdded, ChannelRewardEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.CustomRewardRemoved, ChannelRewardEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.CustomRewardUpdated, ChannelRewardEventData>
|
|
| TypedEventSubNotification<
|
|
EventSubNotificationType.CustomRewardRedemptionAdded,
|
|
ChannelRedemptionEventData<false>
|
|
>
|
|
| TypedEventSubNotification<
|
|
EventSubNotificationType.CustomRewardRedemptionUpdated,
|
|
ChannelRedemptionEventData<true>
|
|
>
|
|
| TypedEventSubNotification<EventSubNotificationType.Followed, FollowEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.GoalBegan, GoalEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.GoalEnded, GoalEndedEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.GoalProgress, GoalEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.HypeTrainBegan, HypeTrainEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.HypeTrainProgress, HypeTrainEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.HypeTrainEnded, HypeTrainEndedEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.ModeratorAdded, ModeratorEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.ModeratorRemoved, ModeratorEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.PollBegan, PollEventData<false>>
|
|
| TypedEventSubNotification<EventSubNotificationType.PollProgress, PollEventData<true>>
|
|
| TypedEventSubNotification<EventSubNotificationType.PollEnded, PollEndedEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.PredictionBegan, PredictionEventData<false>>
|
|
| TypedEventSubNotification<
|
|
EventSubNotificationType.PredictionProgress,
|
|
PredictionEventData<true>
|
|
>
|
|
| TypedEventSubNotification<EventSubNotificationType.PredictionLocked, PredictionLockedEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.PredictionEnded, PredictionEndedEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.StreamWentOffline, StreamEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.StreamWentOnline, StreamWentOnlineEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.Subscription, SubscriptionEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.SubscriptionEnded, SubscriptionEventData>
|
|
| TypedEventSubNotification<
|
|
EventSubNotificationType.SubscriptionGifted,
|
|
SubscriptionGiftedEventData
|
|
>
|
|
| TypedEventSubNotification<
|
|
EventSubNotificationType.SubscriptionWithMessage,
|
|
SubscriptionMessageEventData
|
|
>
|
|
| TypedEventSubNotification<EventSubNotificationType.ViewerBanned, UserBannedEventData>
|
|
| TypedEventSubNotification<EventSubNotificationType.ViewerUnbanned, UserUnbannedEventData>;
|
|
|
|
export interface StreamEventData {
|
|
broadcaster_user_id: string;
|
|
broadcaster_user_login: string;
|
|
broadcaster_user_name: string;
|
|
}
|
|
|
|
export interface StreamWentOnlineEventData extends StreamEventData {
|
|
id: string;
|
|
type: 'live' | 'playlist' | 'watch_party' | 'premiere' | 'rerun';
|
|
started_at: string;
|
|
}
|
|
|
|
type Optional<field extends string, Extra> =
|
|
| ({ [key in field]: true } & Extra)
|
|
| { [key in field]: false };
|
|
|
|
type UserBannedEventData = StreamEventData & {
|
|
user_id: string;
|
|
user_login: string;
|
|
user_name: string;
|
|
moderator_user_id: string;
|
|
moderator_user_login: string;
|
|
moderator_user_name: string;
|
|
reason: string;
|
|
banned_at: string;
|
|
} & Optional<'is_permanent', { ends_at: string }>;
|
|
|
|
export interface UserUnbannedEventData {
|
|
user_id: string;
|
|
user_login: string;
|
|
user_name: string;
|
|
moderator_user_id: string;
|
|
moderator_user_login: string;
|
|
moderator_user_name: string;
|
|
}
|
|
|
|
export interface ChannelUpdatedEventData extends StreamEventData {
|
|
title: string;
|
|
language: string;
|
|
category_id: string;
|
|
category_name: string;
|
|
is_mature: boolean;
|
|
}
|
|
|
|
export interface FollowEventData extends StreamEventData {
|
|
user_id: string;
|
|
user_login: string;
|
|
user_name: string;
|
|
followed_at: string;
|
|
}
|
|
|
|
export interface UserUpdatedEventData {
|
|
user_id: string;
|
|
user_login: string;
|
|
user_name: string;
|
|
email?: string;
|
|
email_verified: boolean;
|
|
description: string;
|
|
}
|
|
|
|
export interface CheerEventData extends StreamEventData {
|
|
is_anonymous: boolean;
|
|
user_id: string | null;
|
|
user_login: string | null;
|
|
user_name: string | null;
|
|
message: string;
|
|
bits: number;
|
|
}
|
|
|
|
export interface RaidEventData {
|
|
from_broadcaster_user_id: string;
|
|
from_broadcaster_user_login: string;
|
|
from_broadcaster_user_name: string;
|
|
to_broadcaster_user_id: string;
|
|
to_broadcaster_user_login: string;
|
|
to_broadcaster_user_name: string;
|
|
viewers: number;
|
|
}
|
|
|
|
export interface ChannelRewardEventData extends StreamEventData {
|
|
id: string;
|
|
is_enabled: boolean;
|
|
is_paused: boolean;
|
|
is_in_stock: boolean;
|
|
title: string;
|
|
cost: number;
|
|
prompt: string;
|
|
is_user_input_required: boolean;
|
|
should_redemptions_skip_request_queue: boolean;
|
|
cooldown_expires_at: string | null;
|
|
redemptions_redeemed_current_stream: number | null;
|
|
max_per_stream: Optional<'is_enabled', { value: number }>;
|
|
max_per_user_per_stream: Optional<'is_enabled', { value: number }>;
|
|
global_cooldown: Optional<'is_enabled', { seconds: number }>;
|
|
background_color: string;
|
|
image: {
|
|
url_1x: string;
|
|
url_2x: string;
|
|
url_4x: string;
|
|
} | null;
|
|
default_image: {
|
|
url_1x: string;
|
|
url_2x: string;
|
|
url_4x: string;
|
|
};
|
|
}
|
|
|
|
export interface ChannelRedemptionEventData<Updated extends boolean> extends StreamEventData {
|
|
id: string;
|
|
user_id: string;
|
|
user_login: string;
|
|
user_name: string;
|
|
user_input: string;
|
|
status: Updated extends true
|
|
? 'fulfilled' | 'canceled'
|
|
: 'unfulfilled' | 'unknown' | 'fulfilled' | 'canceled';
|
|
reward: ChannelRewardEventData;
|
|
redeemed_at: string;
|
|
}
|
|
|
|
export interface GoalEventData extends StreamEventData {
|
|
id: string;
|
|
type: 'follower' | 'subscription';
|
|
description: string;
|
|
current_amount: number;
|
|
target_amount: number;
|
|
started_at: Date;
|
|
}
|
|
|
|
export interface GoalEndedEventData extends GoalEventData {
|
|
is_achieved: boolean;
|
|
ended_at: Date;
|
|
}
|
|
|
|
export interface HypeTrainContribution {
|
|
user_id: string;
|
|
user_login: string;
|
|
user_name: string;
|
|
type: 'bits' | 'subscription' | 'other';
|
|
total: number;
|
|
}
|
|
|
|
interface HypeTrainBaseData extends StreamEventData {
|
|
id: string;
|
|
level: number;
|
|
total: number;
|
|
top_contributions:
|
|
| [HypeTrainContribution]
|
|
| [HypeTrainContribution, HypeTrainContribution]
|
|
| null;
|
|
started_at: string;
|
|
}
|
|
|
|
export interface HypeTrainEventData extends HypeTrainBaseData {
|
|
progress: number;
|
|
goal: number;
|
|
last_contribution: HypeTrainContribution;
|
|
expires_at: string;
|
|
}
|
|
|
|
export interface HypeTrainEndedEventData extends HypeTrainBaseData {
|
|
ended_at: string;
|
|
cooldown_ends_at: string;
|
|
}
|
|
|
|
export interface ModeratorEventData extends StreamEventData {
|
|
user_id: string;
|
|
user_login: string;
|
|
user_name: string;
|
|
}
|
|
|
|
interface PollBaseData<Running extends boolean> extends StreamEventData {
|
|
id: string;
|
|
title: string;
|
|
choices: Running extends true
|
|
? {
|
|
id: string;
|
|
title: string;
|
|
bits_votes: number;
|
|
channel_points_votes: number;
|
|
votes: number;
|
|
}
|
|
: {
|
|
id: string;
|
|
title: string;
|
|
};
|
|
bits_voting: Optional<'is_enabled', { amount_per_vote: number }>;
|
|
channel_points_voting: Optional<'is_enabled', { amount_per_vote: number }>;
|
|
started_at: string;
|
|
}
|
|
|
|
export interface PollEventData<Running extends boolean> extends PollBaseData<Running> {
|
|
started_at: string;
|
|
ends_at: string;
|
|
}
|
|
|
|
export interface PollEndedEventData extends PollBaseData<true> {
|
|
status: 'completed' | 'archived' | 'terminated';
|
|
ended_at: string;
|
|
}
|
|
|
|
type PredictionColor = 'blue' | 'pink';
|
|
interface Outcome<Color extends PredictionColor> {
|
|
id: string;
|
|
title: string;
|
|
color: Color;
|
|
}
|
|
interface RunningOutcome<Color extends PredictionColor> extends Outcome<Color> {
|
|
users: number;
|
|
channel_points: number;
|
|
top_predictors: {
|
|
user_name: string;
|
|
user_login: string;
|
|
user_id: string;
|
|
channel_points_won: number | null;
|
|
channel_points_used: number;
|
|
}[];
|
|
}
|
|
|
|
type UnorderedTuple<A, B> = [A, B] | [B, A];
|
|
|
|
interface PredictionBaseData<Running extends boolean> extends StreamEventData {
|
|
id: string;
|
|
title: string;
|
|
started_at: string;
|
|
outcomes: Running extends true
|
|
? UnorderedTuple<RunningOutcome<'blue'>, RunningOutcome<'pink'>>
|
|
: UnorderedTuple<Outcome<'blue'>, Outcome<'pink'>>;
|
|
}
|
|
|
|
export interface PredictionEventData<Running extends boolean> extends PredictionBaseData<Running> {
|
|
locks_at: string;
|
|
}
|
|
|
|
export interface PredictionLockedEventData extends PredictionBaseData<true> {
|
|
locked_at: string;
|
|
}
|
|
|
|
export interface PredictionEndedEventData extends PredictionBaseData<true> {
|
|
winning_outcome_id: string | null;
|
|
status: 'resolved' | 'canceled';
|
|
ended_at: string;
|
|
}
|
|
|
|
interface SubscriptionBaseData extends StreamEventData {
|
|
user_id: string;
|
|
user_login: string;
|
|
user_name: string;
|
|
tier: '1000' | '2000' | '3000';
|
|
}
|
|
|
|
export interface SubscriptionEventData extends SubscriptionBaseData {
|
|
is_gift: boolean;
|
|
}
|
|
|
|
export interface SubscriptionGiftedEventData extends SubscriptionBaseData {
|
|
total: number;
|
|
cumulative_total: number | null;
|
|
is_anonymous: boolean;
|
|
}
|
|
|
|
export interface SubscriptionMessageEventData extends SubscriptionBaseData {
|
|
message: {
|
|
text: string;
|
|
emotes: {
|
|
begin: number;
|
|
end: number;
|
|
id: string;
|
|
}[]; // Oh god not this again
|
|
};
|
|
cumulative_months: number;
|
|
streak_months: number | null;
|
|
duration_months: number;
|
|
}
|