make TSSBOT/start_bot.py a real Discord bot and reuse SREBOT venv (#1227)

- TSSBOT/start_bot.py: replace the print-and-idle stub with a minimal
  discord.py Client (commands.Bot with default+message_content intents).
  Loads TSSBOT/.env via python-dotenv, reads DISCORD_KEY, logs on_ready,
  handles SIGTERM/SIGINT cleanly. Aborts with a clear error if the token
  is missing instead of silently exit-looping.

- TSSBOT/ecosystem.config.js: switch the default interpreter from system
  python3 to SREBOT's venv (../SREBOT/.venv/bin/python). Both bots share
  BOTS/SHARED and the same baseline deps (discord.py, dotenv, …); split
  into a dedicated TSSBOT/.venv only when the dependency sets diverge.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
NotSoToothless
2026-05-13 23:55:44 -07:00
committed by GitHub
parent a7de9ecad2
commit 34e9af2f94
2 changed files with 39 additions and 10 deletions
+5 -4
View File
@@ -4,10 +4,11 @@ require('dotenv').config();
// you need to point at a different checkout (e.g. local dev). // you need to point at a different checkout (e.g. local dev).
const DEPLOY_PATH = process.env.TSSBOT_DEPLOY_PATH || __dirname; const DEPLOY_PATH = process.env.TSSBOT_DEPLOY_PATH || __dirname;
// Default to system python until TSSBOT grows its own dependency set. // Reuse SREBOT's venv by default — both bots share BOTS/SHARED and most
// When BOT/botscript.py lands, create TSSBOT/.venv and switch this to // runtime deps (discord.py, dotenv, etc.). Split into TSSBOT/.venv once
// `${DEPLOY_PATH}/.venv/bin/python`. // the dep sets diverge meaningfully.
const PY_INTERPRETER = process.env.TSSBOT_PY_INTERPRETER || 'python3'; const PY_INTERPRETER =
process.env.TSSBOT_PY_INTERPRETER || `${DEPLOY_PATH}/../SREBOT/.venv/bin/python`;
module.exports = { module.exports = {
apps: [ apps: [
+34 -6
View File
@@ -1,8 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Entry point for TSSBOT. Skeleton — idles until BOT/botscript.py is wired.""" """Entry point for TSSBOT. Connects to Discord and idles until commands land."""
import logging
import os
import signal import signal
import sys import sys
import time
from pathlib import Path from pathlib import Path
# Make TSSBOT root and BOTS/SHARED importable. # Make TSSBOT root and BOTS/SHARED importable.
@@ -10,15 +11,42 @@ _HERE = Path(__file__).resolve().parent
sys.path.insert(0, str(_HERE)) sys.path.insert(0, str(_HERE))
sys.path.insert(0, str(_HERE.parent / "SHARED")) 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")
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): def _handle_signal(signum, _frame):
print(f"[tssbot] received signal {signum}, exiting") log.info(f"received signal {signum}, exiting")
sys.exit(0) sys.exit(0)
TOKEN = os.environ.get("DISCORD_KEY", "").strip()
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix="!", intents=intents)
@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)")
if __name__ == "__main__": if __name__ == "__main__":
signal.signal(signal.SIGTERM, _handle_signal) signal.signal(signal.SIGTERM, _handle_signal)
signal.signal(signal.SIGINT, _handle_signal) signal.signal(signal.SIGINT, _handle_signal)
print("[tssbot] skeleton booted — replace with real bot once BOT/botscript.py exists") if not TOKEN:
while True: log.error("DISCORD_KEY not set in TSSBOT/.env — aborting")
time.sleep(60) sys.exit(1)
bot.run(TOKEN, log_handler=None)