bot.py docker-compose.yml venv lionel@ubuntuserver1:~/krotbot$ cat bot.py import os import time import subprocess import requests from dotenv import load_dotenv load_dotenv() BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") ALLOWED_USER_ID = int(os.getenv("TELEGRAM_ALLOWED_USER_ID")) DEPLOY_DIR = os.getenv("DEPLOY_DIR", "/home/lionel/docker-compose/arcade") CI_COMPOSE_FILE = os.getenv("CI_COMPOSE_FILE", "docker-compose.ci.yml") PROD_COMPOSE_FILE = os.getenv("PROD_COMPOSE_FILE", "docker-compose.prod.yml") if not BOT_TOKEN: raise RuntimeError("TELEGRAM_BOT_TOKEN ontbreekt") if not ALLOWED_USER_ID: raise RuntimeError("TELEGRAM_ALLOWED_USER_ID ontbreekt") BASE_URL = f"https://api.telegram.org/bot{BOT_TOKEN}" offset = None def send_message(chat_id: int, text: str) -> None: requests.post( f"{BASE_URL}/sendMessage", data={"chat_id": chat_id, "text": text}, timeout=20, ) def run_cmd(cmd: str, timeout: int = 300) -> str: result = subprocess.run( ["bash", "-lc", cmd], capture_output=True, text=True, timeout=timeout, ) output = ((result.stdout or "") + "\n" + (result.stderr or "")).strip() if result.returncode != 0: raise RuntimeError(output or f"Commando faalde: {cmd}") return output def handle_command(chat_id: int, user_id: int, text: str) -> None: text = text.strip().split()[0].split("@")[0] if user_id != ALLOWED_USER_ID: send_message(chat_id, "Niet toegestaan.") return if text == "/start": send_message(chat_id, "Bot actief. Beschikbare commando's: /status /deploy_stable") return if text == "/status": try: output = run_cmd( f"cd {DEPLOY_DIR} && docker compose -f {PROD_COMPOSE_FILE} ps", timeout=60, ) send_message(chat_id, f"Productie status:\n\n{output[:3500]}") except Exception as e: send_message(chat_id, f"Status ophalen mislukt:\n{str(e)[:3500]}") return if text == "/deploy_stable": send_message(chat_id, "Stable deployment gestart...") try: commands = f""" set -e cd {DEPLOY_DIR} docker compose -f {CI_COMPOSE_FILE} down || true docker compose -f {PROD_COMPOSE_FILE} pull docker compose -f {PROD_COMPOSE_FILE} up -d docker compose -f {PROD_COMPOSE_FILE} ps """ output = run_cmd(commands, timeout=300) send_message(chat_id, f"Stable uitgerold.\n\n{output[:3500]}") except Exception as e: send_message(chat_id, f"Deployment mislukt:\n{str(e)[:3500]}") return send_message(chat_id, "Onbekend commando. Gebruik /deploy_stable of /status") while True: try: params = {"timeout": 30} if offset is not None: params["offset"] = offset response = requests.get(f"{BASE_URL}/getUpdates", params=params, timeout=40) response.raise_for_status() updates = response.json().get("result", []) for update in updates: offset = update["update_id"] + 1 message = update.get("message", {}) text = message.get("text", "").strip() chat_id = message.get("chat", {}).get("id") user_id = message.get("from", {}).get("id") if text and chat_id and user_id: handle_command(chat_id, user_id, text) except Exception as e: print(f"Loop error: {e}") time.sleep(5)