Teekeks / pyTwitchAPI

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

ChatMessage room property is not set #173

Closed Kodstok closed 1 year ago

Kodstok commented 1 year ago

On a ChatEvent.MESSAGE room property is not set. Acording to : https://pytwitchapi.readthedocs.io/en/latest/modules/twitchAPI.chat.html#twitchAPI.chat.ChatMessage.room room property is optional, but I know the message comes from a roomn, unfortunately I don't now which one (and I need it) What is the mechanisme behind this property being set or not ?

Teekeks commented 1 year ago

Its Null on a cache miss, so for example when your bot just joined a chat room and got a message event before it got the notification (and with that the room details) that it joined.

It should be populated if you retry after something like half a second. (in reality closer to a few ms but that should do the trick)

Teekeks commented 1 year ago

Thinking about it, I know at least the name it came from when the message is issued so I should probably make that available.

Kodstok commented 1 year ago

I'm sorry but I d'ont quite understand, for me it's long after all rooms are joined that errors start to occure. Here is my code if it can help you because i don't see a way to retry it

async def on_ready(self,ready_event: EventData):
        print('Bot is ready for work, joining channels : ' + str(self.dataBase.getStreamList()))
        # join our target channel, if you want to join multiple, either call join for each individually
        # or even better pass a list of channels as the argument
        for stream in self.dataBase.getStreamList():
            await self.chat.join_room(stream)
            time.sleep(1)    

        print("Channels joined")

    # this will be called whenever a message in a channel was send by either the bot OR another user
    async def on_message(self,msg: ChatMessage):
        dict = {}
        try:
            dict["room_name"] = msg.room.name
            dict["user_name"] = msg.user.name
            dict["msg_text"]  = msg.text
        except AttributeError:
            print("msg " +str(msg))
            print("msg  user name : "+ str(msg.user.name))
            print("msg msg_text : "+ str(msg.text))
            print("retrying in 2000ms")
            dict["room_name"] = "unknown"
        dict["type"] = "viewer"
        self.logger.info(json.dumps(dict))

    def run(self):
        print("run")
        asyncio.run(self.run_chats())

    async def run_chats(self):
        print("run_chats")
        # set up twitch api instance and add user authentication with some scopes
        auth = UserAuthenticator(self.twitch, self.USER_SCOPE, force_verify=False)     
        print("create chat instance")
        # create chat instance
        self.chat = await Chat(self.twitch)

        # register the handlers for the events you want

        # listen to when the bot is done starting up and ready to join channels
        self.chat.register_event(ChatEvent.READY, self.on_ready)
        # listen to chat messages
        self.chat.register_event(ChatEvent.MESSAGE, self.on_message)

        # we are done with our setup, lets start this bot up!
        print("chats starting")
        self.chat.start()
        print("chats started")

        while self.continue_running:
            time.sleep(60)

        print("finaly clause")
        self.chat.stop()
        await self.twitch.close()
Teekeks commented 1 year ago

when you get a cache miss like that, could you please look if all rooms are present in msg.chat.room_cache? That variable should be a dictionary with the room names as keys and ChatRoom as value.

Kodstok commented 1 year ago

I've tried to join 42 room (some of them are offline) only 23 are present in msg.chat.room_cache and this number seems go down as the time pass

No value is set to None

Teekeks commented 1 year ago

Oh thats interesting, can you check if you get ChatEvent.LEFT events for those channels that go missing?

Kodstok commented 1 year ago

after adding self.chat.register_event(ChatEvent.LEFT, self.room_left) and

async def room_left(self, cht: ChatEvent):
        print("I LEFT A ROOM")

I can see it being trigered 51 times juste before on_ready function finish

Then as before msg.chat.room_cache decrease

and room_left is trigered time to time but always in burst

twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM twitch_stats_1 | I LEFT A ROOM

Teekeks commented 1 year ago

Really interesting, thanks! Will need to take a look at that and try to reproduce it