From 5271d6aa2de4f26082467293ec0046fbd6a32dce Mon Sep 17 00:00:00 2001 From: DevilXD <4180725+DevilXD@users.noreply.github.com> Date: Sat, 4 Nov 2023 15:31:39 +0100 Subject: [PATCH] Detect completed drops via notifications feed --- constants.py | 37 ++++++++++++++++++++++++++++++++----- twitch.py | 15 +++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/constants.py b/constants.py index 89383a7..f57bbcd 100644 --- a/constants.py +++ b/constants.py @@ -97,7 +97,7 @@ JsonType = Dict[str, Any] URLType = NewType("URLType", str) TopicProcess: TypeAlias = "abc.Callable[[int, JsonType], Any]" # Values -BASE_TOPICS = 2 +BASE_TOPICS = 3 MAX_WEBSOCKETS = 8 WS_TOPICS_LIMIT = 50 TOPICS_PER_CHANNEL = 2 @@ -324,6 +324,33 @@ GQL_OPERATIONS: dict[str, GQLOperation] = { "sortTypeIsRecency": False, }, ), + "NotificationsView": GQLOperation( # unused, triggers notifications "update-summary" + "OnsiteNotifications_View", + "f6bdb1298f376539487f28b7f8a6b5d7434ec04ba4d7dc5c232b258410ae04d6", + variables={ + "input": {}, + }, + ), + "NotificationsList": GQLOperation( # unused + "OnsiteNotifications_ListNotifications", + "e709b905ddb963d7cf4a8f6760148926ecbd0eee0f2edc48d1cf17f3e87f6490", + variables={ + "cursor": "", + "displayType": "VIEWER", + "language": "en", + "limit": 10, + "shouldLoadLastBroadcast": False, + }, + ), + "NotificationsDelete": GQLOperation( + "OnsiteNotifications_DeleteNotification", + "13d463c831f28ffe17dccf55b3148ed8b3edbbd0ebadd56352f1ff0160616816", + variables={ + "input": { + "id": "", # ID of the notification to delete + } + }, + ), } @@ -368,15 +395,15 @@ class WebsocketTopic: WEBSOCKET_TOPICS: dict[str, dict[str, str]] = { "User": { # Using user_id - "Drops": "user-drop-events", - "CommunityPoints": "community-points-user-v1", "Presence": "presence", # unused - "Notifications": "onsite-notifications", # unused + "Drops": "user-drop-events", + "Notifications": "onsite-notifications", + "CommunityPoints": "community-points-user-v1", }, "Channel": { # Using channel_id "Drops": "channel-drop-events", # unused - "CommunityPoints": "community-points-channel-v1", # unused "StreamState": "video-playback-by-id", "StreamUpdate": "broadcast-settings-update", + "CommunityPoints": "community-points-channel-v1", # unused }, } diff --git a/twitch.py b/twitch.py index aea0e20..c12903f 100644 --- a/twitch.py +++ b/twitch.py @@ -790,6 +790,9 @@ class Twitch: self.websocket.add_topics([ WebsocketTopic("User", "Drops", auth_state.user_id, self.process_drops), WebsocketTopic("User", "CommunityPoints", auth_state.user_id, self.process_points), + WebsocketTopic( + "User", "Notifications", auth_state.user_id, self.process_notifications + ), ]) full_cleanup: bool = False channels: Final[OrderedDict[int, Channel]] = self.channels @@ -1391,6 +1394,18 @@ class Twitch: self._drop_update.set_result(False) self._drop_update = None + @task_wrapper + async def process_notifications(self, user_id: int, message: JsonType): + if message["type"] == "create-notification": + data: JsonType = message["data"]["notification"] + if data["type"] == "user_drop_reward_reminder_notification": + self.change_state(State.INVENTORY_FETCH) + await self.gql_request( + GQL_OPERATIONS["NotificationsDelete"].with_variables( + {"input": {"id": data["id"]}} + ) + ) + @task_wrapper async def process_points(self, user_id: int, message: JsonType): # Example payloads: