113 lines
3.5 KiB
Python
113 lines
3.5 KiB
Python
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)
|