#!/usr/bin/env python3 """Entry point for TSSBOT. Connects to Discord and idles until commands land.""" import asyncio import logging import os import signal import sys from pathlib import Path # Make TSSBOT root and BOTS/SHARED importable. _HERE = Path(__file__).resolve().parent sys.path.insert(0, str(_HERE)) sys.path.insert(0, str(_HERE.parent / "SHARED")) import discord from discord.ext import commands from dotenv import load_dotenv load_dotenv(dotenv_path=_HERE / ".env") # Imported after load_dotenv so env vars are available. from BOT.storage import init_tss_dbs # noqa: E402 from BOT.autologging import set_bot as set_autolog_bot # noqa: E402 from BOT.commands import setup_commands # noqa: E402 from tss_ws import listen, _handle_game # noqa: E402 logging.basicConfig( level=logging.INFO, format="[%(asctime)s] [%(levelname)s] [tssbot] %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) log = logging.getLogger("tssbot") def _handle_signal(signum, _frame): log.info(f"received signal {signum}, exiting") sys.exit(0) TOKEN = os.environ.get("DISCORD_KEY", "").strip() intents = discord.Intents.default() intents.message_content = False intents.reactions = True intents.messages = True class TSSBot(commands.Bot): async def setup_hook(self) -> None: # Register the client so the autolog matcher can post, wire up the # slash commands, and push them to Discord. set_autolog_bot(self) await setup_commands(self) try: synced = await self.tree.sync() log.info("synced %d slash command(s)", len(synced)) except Exception as exc: log.error("slash command sync failed: %s", exc) bot = TSSBot(command_prefix="!", intents=intents) async def _ws_task_loop() -> None: """Run the TSS WS listener forever, restarting on any error.""" while True: try: await listen(_handle_game) except Exception as exc: log.error(f"TSS WS listener crashed: {exc} — restarting in 10s") await asyncio.sleep(10) @bot.event async def on_ready(): log.info(f"logged in as {bot.user} (id={bot.user.id if bot.user else '?'})") log.info(f"connected to {len(bot.guilds)} guild(s)") await bot.change_presence( activity=discord.CustomActivity(name="Soon...") ) asyncio.create_task(_ws_task_loop()) if __name__ == "__main__": signal.signal(signal.SIGTERM, _handle_signal) signal.signal(signal.SIGINT, _handle_signal) if not TOKEN: log.error("DISCORD_KEY not set in TSSBOT/.env — aborting") sys.exit(1) try: asyncio.run(init_tss_dbs()) except Exception as e: log.error(f"failed to initialise TSS databases: {e}") sys.exit(1) bot.run(TOKEN, log_handler=None)