Telegram funktionen hinzugefügt
This commit is contained in:
90
main.py
90
main.py
@@ -9,6 +9,8 @@ import re
|
|||||||
import httpx
|
import httpx
|
||||||
import struct
|
import struct
|
||||||
import termios
|
import termios
|
||||||
|
from telegram import Update
|
||||||
|
from telegram.ext import ApplicationBuilder, ContextTypes, MessageHandler, filters
|
||||||
from google import genai
|
from google import genai
|
||||||
from google.genai import types
|
from google.genai import types
|
||||||
import json
|
import json
|
||||||
@@ -44,6 +46,11 @@ OPENAI_MODEL = os.getenv("OPENAI_MODEL", "gpt-4o")
|
|||||||
OLLAMA_MODEL = os.getenv("OLLAMA_MODEL", "llama3")
|
OLLAMA_MODEL = os.getenv("OLLAMA_MODEL", "llama3")
|
||||||
NVIDIA_MODEL = os.getenv("NVIDIA_MODEL", "moonshotai/kimi-k2.5")
|
NVIDIA_MODEL = os.getenv("NVIDIA_MODEL", "moonshotai/kimi-k2.5")
|
||||||
|
|
||||||
|
# Telegram Bot Konfiguration
|
||||||
|
TELEGRAM_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN", "")
|
||||||
|
ALLOWED_ID = os.getenv("ALLOWED_TELEGRAM_USER_ID", "")
|
||||||
|
telegram_app = None
|
||||||
|
|
||||||
# --- DATENBANK INITIALISIERUNG (ERWEITERT) ---
|
# --- DATENBANK INITIALISIERUNG (ERWEITERT) ---
|
||||||
def init_db():
|
def init_db():
|
||||||
conn = sqlite3.connect(DB_PATH)
|
conn = sqlite3.connect(DB_PATH)
|
||||||
@@ -163,6 +170,89 @@ async def get_ai_response(user_input, system_prompt):
|
|||||||
|
|
||||||
return ai_msg
|
return ai_msg
|
||||||
|
|
||||||
|
async def handle_telegram_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
# Sicherheits-Check: Nur deine Chat-ID wird akzeptiert
|
||||||
|
if str(update.effective_chat.id) != ALLOWED_ID:
|
||||||
|
await update.message.reply_text("Zugriff verweigert. 🔒")
|
||||||
|
return
|
||||||
|
|
||||||
|
user_msg = update.message.text
|
||||||
|
|
||||||
|
# "Tippt..." Status in Telegram anzeigen (schöne UX)
|
||||||
|
await update.message.reply_chat_action(action="typing")
|
||||||
|
|
||||||
|
# 1. KI Antwort holen
|
||||||
|
ai_response = await get_ai_response(user_msg, get_system_prompt())
|
||||||
|
|
||||||
|
# 2. Befehle extrahieren
|
||||||
|
commands = re.findall(r'<EXECUTE target="(.*?)">(.*?)</EXECUTE>', ai_response, re.I | re.S)
|
||||||
|
clean_msg = re.sub(r'<EXECUTE.*?>.*?</EXECUTE>', '', ai_response, flags=re.I | re.S).strip()
|
||||||
|
|
||||||
|
# KI Text-Antwort senden
|
||||||
|
if clean_msg:
|
||||||
|
await update.message.reply_text(clean_msg)
|
||||||
|
|
||||||
|
# 3. Befehle ausführen und Ergebnisse als Telegram-Nachricht senden
|
||||||
|
if commands:
|
||||||
|
for target, cmd in commands:
|
||||||
|
await update.message.reply_text(f"⏳ Führe aus auf *{target}*:\n`{cmd}`", parse_mode='Markdown')
|
||||||
|
|
||||||
|
# Node in DB suchen
|
||||||
|
conn = get_db()
|
||||||
|
n = conn.execute('SELECT * FROM nodes WHERE ip=? OR name=?', (target.strip(), target.strip())).fetchone()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
if n:
|
||||||
|
# Befehl ausführen und Output abfangen
|
||||||
|
try:
|
||||||
|
proc = await asyncio.create_subprocess_shell(
|
||||||
|
f"ssh -o StrictHostKeyChecking=no {n['user']}@{n['ip']} '{cmd}'",
|
||||||
|
stdout=asyncio.subprocess.PIPE,
|
||||||
|
stderr=asyncio.subprocess.STDOUT
|
||||||
|
)
|
||||||
|
stdout, _ = await proc.communicate()
|
||||||
|
output = stdout.decode('utf-8', errors='ignore').strip()
|
||||||
|
|
||||||
|
# Ergebnis an Telegram senden (abgeschnitten auf 4000 Zeichen, da Telegram Limits hat)
|
||||||
|
result_text = output[:4000] if output else "✅ Befehl ohne Output ausgeführt."
|
||||||
|
await update.message.reply_text(f"💻 **Output von {n['name']}:**\n```\n{result_text}\n```", parse_mode='Markdown')
|
||||||
|
|
||||||
|
# Auch ins KI-Gedächtnis schreiben
|
||||||
|
chat_history.append({"role": "user", "content": f"[SYSTEM] Befehl '{cmd}' auf {target} fertig:\n{result_text}"})
|
||||||
|
except Exception as e:
|
||||||
|
await update.message.reply_text(f"❌ Fehler bei der Ausführung: {e}")
|
||||||
|
else:
|
||||||
|
await update.message.reply_text(f"⚠️ Node '{target}' nicht in der Datenbank gefunden.")
|
||||||
|
|
||||||
|
# --- FASTAPI LIFESPAN EVENTS (Bot starten/stoppen) ---
|
||||||
|
@app.on_event("startup")
|
||||||
|
async def startup_event():
|
||||||
|
global telegram_app
|
||||||
|
if TELEGRAM_TOKEN and ALLOWED_ID:
|
||||||
|
print("🤖 Starte Telegram Bot im Hintergrund...")
|
||||||
|
telegram_app = ApplicationBuilder().token(TELEGRAM_TOKEN).build()
|
||||||
|
|
||||||
|
# Leitet alle Text-Nachrichten an unsere Funktion weiter
|
||||||
|
telegram_app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_telegram_message))
|
||||||
|
|
||||||
|
# Bot asynchron in die FastAPI Event-Loop einhängen
|
||||||
|
await telegram_app.initialize()
|
||||||
|
await telegram_app.start()
|
||||||
|
await telegram_app.updater.start_polling()
|
||||||
|
print("✅ Telegram Bot lauscht!")
|
||||||
|
else:
|
||||||
|
print("ℹ️ Telegram Bot inaktiv (Token oder ID fehlen in der .env).")
|
||||||
|
|
||||||
|
@app.on_event("shutdown")
|
||||||
|
async def shutdown_event():
|
||||||
|
global telegram_app
|
||||||
|
if telegram_app:
|
||||||
|
print("🛑 Stoppe Telegram Bot...")
|
||||||
|
await telegram_app.updater.stop()
|
||||||
|
await telegram_app.stop()
|
||||||
|
await telegram_app.shutdown()
|
||||||
|
|
||||||
|
|
||||||
# --- WebSocket Manager ---
|
# --- WebSocket Manager ---
|
||||||
class ConnectionManager:
|
class ConnectionManager:
|
||||||
def __init__(self): self.active_connections = []
|
def __init__(self): self.active_connections = []
|
||||||
|
|||||||
Reference in New Issue
Block a user