Teekeks / pyTwitchAPI

A Python 3.7 compatible implementation of the Twitch API, EventSub, PubSub and Chat
https://pytwitchapi.dev
MIT License
253 stars 38 forks source link

EventSub websocket fails with listen_channel_prediction_progress #322

Closed ericjtaylor closed 1 month ago

ericjtaylor commented 1 month ago

Minimal example below shows listen_channel_prediction_begin() succeed before listen_channel_prediction_progress() fails, so I'm reasonably confident I've set things up right. Spent a lot of time trying to make sense of it, would appreciate any advice.

from twitchAPI.helper import first
from twitchAPI.twitch import Twitch
from twitchAPI.oauth import UserAuthenticationStorageHelper
from twitchAPI.object.eventsub import ChannelPredictionEvent
from twitchAPI.eventsub.websocket import EventSubWebsocket
from twitchAPI.type import AuthScope
import asyncio

import logging
logging.basicConfig(level=logging.DEBUG)

APP_ID = 'your_app_id'
APP_SECRET = 'your_app_secret'
TARGET_SCOPES = [AuthScope.CHANNEL_MANAGE_PREDICTIONS, AuthScope.CHANNEL_READ_PREDICTIONS]

async def on_prediction_begin(data: ChannelPredictionEvent):
    print("prediction began")

async def on_prediction_progress(data: ChannelPredictionEvent):
    print("prediction progressed")

async def run():
    twitch = await Twitch(APP_ID, APP_SECRET)
    helper = UserAuthenticationStorageHelper(twitch, TARGET_SCOPES)
    await helper.bind()
    user = await first(twitch.get_users())
    eventsub = EventSubWebsocket(twitch)
    eventsub.start()

    await eventsub.listen_channel_prediction_begin(user.id, on_prediction_begin)
    await eventsub.listen_channel_prediction_progress(user.id, on_prediction_progress)

    try:
        input('press Enter to shut down...')
    except KeyboardInterrupt:
        pass
    finally:
        await eventsub.stop()
        await twitch.close()

asyncio.run(run())

And the error:

DEBUG:asyncio:Using proactor: IocpProactor
DEBUG:twitchAPI.twitch:generating fresh app token
DEBUG:twitchAPI.twitch:making GET request to https://api.twitch.tv/helix/users
DEBUG:twitchAPI.eventsub.websocket:starting websocket EventSub...
DEBUG:asyncio:Using proactor: IocpProactor
DEBUG:twitchAPI.eventsub.websocket:connecting to wss://eventsub.wss.twitch.tv/ws...
DEBUG:twitchAPI.eventsub.websocket:new session id: AgoQ5WVLSBgCRvy1E1ZgObkoeBIGY2VsbC1i
DEBUG:twitchAPI.eventsub.websocket:EventSubWebsocket started up!
DEBUG:twitchAPI.eventsub.websocket:subscribe to channel.prediction.begin version 1 with condition {'broadcaster_user_id': '40452019'}
DEBUG:twitchAPI.eventsub.websocket:subscription for channel.prediction.begin version 1 with condition {'broadcaster_user_id': '40452019'} has id d54261b6-5ab2-4501-9104-c19c4bff0a7f
DEBUG:twitchAPI.eventsub.websocket:subscribe to channel.prediction.progress version 1 with condition {'broadcaster_user_id': '40452019'}
DEBUG:twitchAPI.eventsub.websocket:subscription for channel.prediction.progress version 1 with condition {'broadcaster_user_id': '40452019'} has id 5034af5a-4d50-4534-b850-97c7cd8c362f
press Enter to shut down...DEBUG:twitchAPI.eventsub.websocket:got session keep alive
DEBUG:twitchAPI.eventsub.websocket:got session keep alive
DEBUG:twitchAPI.eventsub.websocket:got session keep alive
prediction began
ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='Task-31' coro=<EventSubWebsocket._handle_notification() done, defined at \Python\Python311\Lib\site-packages\twitchAPI\eventsub\websocket.py:418> exception=TypeError('twitchAPI.object.eventsub.TopPredictors() argument after ** must be a mapping, not list')>
Traceback (most recent call last):
  File "\Python\Python311\Lib\site-packages\twitchAPI\eventsub\websocket.py", line 426, in _handle_notification
    t = self._callback_loop.create_task(callback['callback'](callback['event'](**_payload)))
                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\Python\Python311\Lib\site-packages\twitchAPI\object\base.py", line 121, in __init__
    self.__setattr__(name, TwitchObject._val_by_instance(cls, kwargs.get(name)))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\Python\Python311\Lib\site-packages\twitchAPI\object\base.py", line 54, in _val_by_instance
    return instance(**val)
           ^^^^^^^^^^^^^^^
  File "\Python\Python311\Lib\site-packages\twitchAPI\object\base.py", line 121, in __init__
    self.__setattr__(name, TwitchObject._val_by_instance(cls, kwargs.get(name)))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\Python\Python311\Lib\site-packages\twitchAPI\object\base.py", line 44, in _val_by_instance
    return [TwitchObject._val_by_instance(c, x) for x in val]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\Python\Python311\Lib\site-packages\twitchAPI\object\base.py", line 44, in <listcomp>
    return [TwitchObject._val_by_instance(c, x) for x in val]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\Python\Python311\Lib\site-packages\twitchAPI\object\base.py", line 54, in _val_by_instance
    return instance(**val)
           ^^^^^^^^^^^^^^^
  File "\Python\Python311\Lib\site-packages\twitchAPI\object\base.py", line 121, in __init__
    self.__setattr__(name, TwitchObject._val_by_instance(cls, kwargs.get(name)))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\Python\Python311\Lib\site-packages\twitchAPI\object\base.py", line 54, in _val_by_instance
    return instance(**val)
           ^^^^^^^^^^^^^^^
TypeError: twitchAPI.object.eventsub.TopPredictors() argument after ** must be a mapping, not list
ericjtaylor commented 1 month ago

Apologies for the noise. I was on version 4.2.0 and this was fixed in 4.2.1. Thank you for your hard work!