diff --git a/twitchio/eventsub/payloads.py b/twitchio/eventsub/payloads.py index 4211a840..55319c0d 100644 --- a/twitchio/eventsub/payloads.py +++ b/twitchio/eventsub/payloads.py @@ -68,6 +68,9 @@ "ChannelVIPRemoveSubscription", "ChannelWarningAcknowledgementSubscription", "ChannelWarningSendSubscription", + "GoalBeginSubscription", + "GoalProgressSubscription", + "GoalEndSubscription", "HypeTrainBeginSubscription", "HypeTrainProgressSubscription", "HypeTrainEndSubscription", @@ -642,8 +645,8 @@ def condition(self) -> Condition: return {"broadcaster_user_id": self.broadcaster_user_id, "moderator_user_id": self.moderator_user_id} -class HypeTrainProgressSubscription(SubscriptionPayload): - type: ClassVar[Literal["channel.hype_train.progress"]] = "channel.hype_train.progress" +class GoalBeginSubscription(SubscriptionPayload): + type: ClassVar[Literal["channel.goal.begin"]] = "channel.goal.begin" version: ClassVar[Literal["1"]] = "1" def __init__(self, **condition: Unpack[Condition]) -> None: @@ -657,8 +660,23 @@ def condition(self) -> Condition: return {"broadcaster_user_id": self.broadcaster_user_id} -class HypeTrainEndSubscription(SubscriptionPayload): - type: ClassVar[Literal["channel.hype_train.end"]] = "channel.hype_train.end" +class GoalProgressSubscription(SubscriptionPayload): + type: ClassVar[Literal["channel.goal.progress"]] = "channel.goal.progress" + version: ClassVar[Literal["1"]] = "1" + + def __init__(self, **condition: Unpack[Condition]) -> None: + self.broadcaster_user_id: str = condition.get("broadcaster_user_id", "") + + if not self.broadcaster_user_id: + raise ValueError('The parameter "broadcaster_user_id" must be passed.') + + @property + def condition(self) -> Condition: + return {"broadcaster_user_id": self.broadcaster_user_id} + + +class GoalEndSubscription(SubscriptionPayload): + type: ClassVar[Literal["channel.goal.end"]] = "channel.goal.end" version: ClassVar[Literal["1"]] = "1" def __init__(self, **condition: Unpack[Condition]) -> None: @@ -687,6 +705,36 @@ def condition(self) -> Condition: return {"broadcaster_user_id": self.broadcaster_user_id} +class HypeTrainProgressSubscription(SubscriptionPayload): + type: ClassVar[Literal["channel.hype_train.progress"]] = "channel.hype_train.progress" + version: ClassVar[Literal["1"]] = "1" + + def __init__(self, **condition: Unpack[Condition]) -> None: + self.broadcaster_user_id: str = condition.get("broadcaster_user_id", "") + + if not self.broadcaster_user_id: + raise ValueError('The parameter "broadcaster_user_id" must be passed.') + + @property + def condition(self) -> Condition: + return {"broadcaster_user_id": self.broadcaster_user_id} + + +class HypeTrainEndSubscription(SubscriptionPayload): + type: ClassVar[Literal["channel.hype_train.end"]] = "channel.hype_train.end" + version: ClassVar[Literal["1"]] = "1" + + def __init__(self, **condition: Unpack[Condition]) -> None: + self.broadcaster_user_id: str = condition.get("broadcaster_user_id", "") + + if not self.broadcaster_user_id: + raise ValueError('The parameter "broadcaster_user_id" must be passed.') + + @property + def condition(self) -> Condition: + return {"broadcaster_user_id": self.broadcaster_user_id} + + class ShieldModeBeginSubscription(SubscriptionPayload): type: ClassVar[Literal["channel.shield_mode.begin"]] = "channel.shield_mode.begin" version: ClassVar[Literal["1"]] = "1" diff --git a/twitchio/models/eventsub_.py b/twitchio/models/eventsub_.py index d06cd2f4..edfbf091 100644 --- a/twitchio/models/eventsub_.py +++ b/twitchio/models/eventsub_.py @@ -1365,6 +1365,96 @@ def __repr__(self) -> str: return f"" +class GoalBegin(BaseEvent): + __slots__ = ("id", "broadcaster", "type", "description", "current_amount", "target_amount", "started_at") + + def __init__(self, payload: GoalBeginEvent, *, http: HTTPClient) -> None: + self.id: str = payload["id"] + self.broadcaster: PartialUser = PartialUser( + payload["broadcaster_user_id"], payload["broadcaster_user_login"], http=http + ) + self.type: Literal[ + "follow", + "subscription", + "subscription_count", + "new_subscription", + "new_subscription_count", + "new_bit", + "new_cheerer", + ] = payload["type"] + self.description: str = payload["description"] + self.current_amount: int = int(payload["current_amount"]) + self.target_amount: int = int(payload["target_amount"]) + self.started_at: datetime.datetime = parse_timestamp(payload["started_at"]) + + def __repr__(self) -> str: + return f"" + + +class GoalProgress(BaseEvent): + __slots__ = ("id", "broadcaster", "type", "description", "current_amount", "target_amount", "started_at") + + def __init__(self, payload: GoalProgressEvent, *, http: HTTPClient) -> None: + self.id: str = payload["id"] + self.broadcaster: PartialUser = PartialUser( + payload["broadcaster_user_id"], payload["broadcaster_user_login"], http=http + ) + self.type: Literal[ + "follow", + "subscription", + "subscription_count", + "new_subscription", + "new_subscription_count", + "new_bit", + "new_cheerer", + ] = payload["type"] + self.description: str = payload["description"] + self.current_amount: int = int(payload["current_amount"]) + self.target_amount: int = int(payload["target_amount"]) + self.started_at: datetime.datetime = parse_timestamp(payload["started_at"]) + + def __repr__(self) -> str: + return f"" + + +class GoalEnd(BaseEvent): + __slots__ = ( + "id", + "broadcaster", + "type", + "description", + "current_amount", + "target_amount", + "started_at", + "ended_at", + "achieved", + ) + + def __init__(self, payload: GoalEndEvent, *, http: HTTPClient) -> None: + self.id: str = payload["id"] + self.broadcaster: PartialUser = PartialUser( + payload["broadcaster_user_id"], payload["broadcaster_user_login"], http=http + ) + self.type: Literal[ + "follow", + "subscription", + "subscription_count", + "new_subscription", + "new_subscription_count", + "new_bit", + "new_cheerer", + ] = payload["type"] + self.description: str = payload["description"] + self.current_amount: int = int(payload["current_amount"]) + self.target_amount: int = int(payload["target_amount"]) + self.started_at: datetime.datetime = parse_timestamp(payload["started_at"]) + self.ended_at: datetime.datetime = parse_timestamp(payload["ended_at"]) + self.achieved: bool = bool(payload["is_achieved"]) + + def __repr__(self) -> str: + return f"" + + class HypeTrainBegin(BaseEvent): subscription_type = "channel.hype_train.begin" diff --git a/twitchio/types_/eventsub.py b/twitchio/types_/eventsub.py index 16e9e219..719a1fcd 100644 --- a/twitchio/types_/eventsub.py +++ b/twitchio/types_/eventsub.py @@ -94,6 +94,9 @@ "ChatResubData", "ChatSubData", "ChatSubGiftData", + "GoalBeginEvent", + "GoalProgressEvent", + "GoalEndEvent", "HypeTrainBeginEvent", "HypeTrainProgressEvent", "HypeTrainEndEvent", @@ -825,12 +828,40 @@ class ChannelWarningSendEvent(BroadcasterModUserEvent): chat_rules_cited: list[str] | None -class GoalBeginProgressEvent(TypedDict): +class GoalBeginEvent(TypedDict): id: str broadcaster_user_id: str broadcaster_user_login: str broadcaster_user_name: str - type: str + type: Literal[ + "follow", + "subscription", + "subscription_count", + "new_subscription", + "new_subscription_count", + "new_bit", + "new_cheerer", + ] + description: str + current_amount: int + target_amount: int + started_at: str + + +class GoalProgressEvent(TypedDict): + id: str + broadcaster_user_id: str + broadcaster_user_login: str + broadcaster_user_name: str + type: Literal[ + "follow", + "subscription", + "subscription_count", + "new_subscription", + "new_subscription_count", + "new_bit", + "new_cheerer", + ] description: str current_amount: int target_amount: int @@ -842,7 +873,15 @@ class GoalEndEvent(TypedDict): broadcaster_user_id: str broadcaster_user_login: str broadcaster_user_name: str - type: str + type: Literal[ + "follow", + "subscription", + "subscription_count", + "new_subscription", + "new_subscription_count", + "new_bit", + "new_cheerer", + ] description: str is_achieved: bool current_amount: int