import gradio as gr import subprocess import asyncio import threading import os import time from queue import Queue, Empty from telegram import Update from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes # --- Config --- BOT_TOKEN = os.environ.get("BOT_TOKEN", "YOUR_BOT_TOKEN_HERE") log_queue = Queue() telegram_cmd_logs = [] bot_should_run = True # Thread-safe flag # --- Telegram Command Handler --- async def bash_command(update: Update, context: ContextTypes.DEFAULT_TYPE): if not bot_should_run: await update.message.reply_text("Bot is disabled.") return cmd = ' '.join(context.args) if not cmd: await update.message.reply_text("Usage: /bash ") return log_queue.put(f"[Telegram] /bash {cmd}") try: proc = await asyncio.create_subprocess_shell( cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT, ) stdout, _ = await proc.communicate() output = stdout.decode().strip() except Exception as e: output = f"Error: {e}" await update.message.reply_text(f"$ {cmd}\n{output}") telegram_cmd_logs.append(f"$ {cmd}\n{output}") if len(telegram_cmd_logs) > 50: telegram_cmd_logs.pop(0) # --- Start bot once in main thread --- def launch_bot(): async def main(): app = ApplicationBuilder().token(BOT_TOKEN).build() app.add_handler(CommandHandler("bash", bash_command)) log_queue.put("[Bot] Running...") await app.run_polling() def bot_thread(): asyncio.run(main()) thread = threading.Thread(target=bot_thread, daemon=True) thread.start() # --- Terminal Function --- def live_terminal(cmd): if not cmd.strip(): yield "$ " return yield f"$ {cmd}\n" process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) for line in iter(process.stdout.readline, ''): yield line process.stdout.close() process.wait() yield "$ " # --- Log Updater --- def update_logs(): logs = [] try: while True: logs.append(log_queue.get_nowait()) except Empty: pass logs.extend(telegram_cmd_logs[-20:]) return "\n".join(logs[-20:]) # --- Start/Stop Bot Command Execution Only --- def enable_bot(): global bot_should_run bot_should_run = True log_queue.put("[Bot] Enabled") return update_logs() def disable_bot(): global bot_should_run bot_should_run = False log_queue.put("[Bot] Disabled") return update_logs() # --- Gradio Interface --- with gr.Blocks() as demo: gr.Markdown("## 🖥️ Live Terminal + Telegram Bot Interface") with gr.Row(): terminal_output = gr.Textbox(label="Live Terminal", lines=20, interactive=False) cmd_input = gr.Textbox(placeholder="Type shell command", label="Command Input") run_btn = gr.Button("▶️ Run Command") with gr.Row(): start_btn = gr.Button("✅ Enable Bot") stop_btn = gr.Button("🛑 Disable Bot") log_output = gr.Textbox(label="📜 Logs", lines=15, interactive=False) run_btn.click(live_terminal, inputs=cmd_input, outputs=terminal_output) start_btn.click(fn=enable_bot, outputs=log_output) stop_btn.click(fn=disable_bot, outputs=log_output) def background_log_updater(): while True: time.sleep(3) yield update_logs() demo.load(background_log_updater, outputs=log_output) # --- Launch everything --- launch_bot() demo.launch()