"""counter.py: a live message counter, in Python. It sits in your chat rooms with its own API key, counts the members' messages (never a bot's) and every 5 seconds pushes the total to the public channel "status", which every page can show. It never speaks in the rooms. Python 3.10+. pip install -r requirements.txt, then python counter.py (reads .env). Its key (dashboard, New API key): rights subscribe, client_events and publish; kinds public and presence; channels: prefix presence-chat-, exact name status. """ import asyncio from pikoman_bot import Bot, Rest, env ROOMS = env("ROOMS", "presence-chat-lobby,presence-chat-help").split(",") # Access 3, though it never speaks: in a presence channel only members who may speak get the # member list, and the list says who is a bot. bot = Bot("Counter", access=3) rest = Rest() # PIKOMAN_APP and PIKOMAN_API_KEY; PIKOMAN_HTTP only for another server total = 0 for name in ROOMS: room = bot.join(name) # Every chat message a member sends. Bots are skipped: only the server says who is a bot (its # member list, and info["bot"] on each event), never a member. @room.on("message") def counted(sender, data, info, room=room): global total if not info.get("bot") and not room.is_bot(sender): total += 1 async def push(): """Every 5 seconds, changed or not, so a page opened a moment ago gets the number soon.""" while True: await asyncio.sleep(5) try: await asyncio.to_thread(rest.publish, "status", "total-messages", {"total": total}) except Exception as e: # noqa: BLE001: try again in 5 seconds print("publish:", e) print(f"Counting in {', '.join(ROOMS)}") bot.start(push())