import os import json import string import random import subprocess import threading import time import requests from flask import Flask import telebot from telebot import types # === CONFIG === BOT_TOKEN = "8018538301:AAGRSngj4Bj5nqizPsU3Zux48Yr6fpaZ7To" # 🔁 Replace this with your Telegram Bot Token SCRIPT_DIR = "scripts" DB_FILE = "scripts.json" PORT = int(os.environ.get('PORT', 7860)) PING_URL = "https://dexsecon-yobot.hf.space/ping" # ✅ Auto-ping URL (your space) # === INIT === os.makedirs(SCRIPT_DIR, exist_ok=True) app = Flask(__name__) bot = telebot.TeleBot(BOT_TOKEN) file_upload_mode = {} status_map = {} # === UTILITIES === def generate_filename(): return ''.join(random.choices(string.ascii_letters + string.digits, k=6)) + ".py" def load_db(): if not os.path.exists(DB_FILE): with open(DB_FILE, "w") as f: json.dump({}, f) with open(DB_FILE, "r") as f: return json.load(f) def save_db(data): with open(DB_FILE, "w") as f: json.dump(data, f, indent=4) def update_status(filename, proc): stdout, stderr = proc.communicate() if proc.returncode == 0: status_map[filename] = 'sleep' else: status_map[filename] = 'error' def auto_ping(): while True: try: requests.get(PING_URL) print("✅ Ping sent to HF") except Exception as e: print(f"❌ Ping failed: {e}") time.sleep(300) # 5 minutes # === TELEGRAM COMMANDS === @bot.message_handler(commands=['start']) def start_message(message): markup = types.ReplyKeyboardMarkup(resize_keyboard=True) markup.add('📥 Upload Script', '📜 My Scripts') markup.add('📊 Status', '🔄 Refresh') bot.send_message(message.chat.id, "👋 Welcome to XOOM Bot!", reply_markup=markup) @bot.message_handler(commands=['help']) def help_message(message): bot.send_message(message.chat.id, "Available:\n/start – Menu\n/help – Help info\n/status – Status of your scripts\n/myscripts – Show your scripts") @bot.message_handler(commands=['status']) def status_all(message): chat_id = str(message.chat.id) db = load_db() scripts = db.get(chat_id, []) counts = {"running": 0, "error": 0, "sleep": 0} for s in scripts: stat = status_map.get(s, 'unknown') if stat in counts: counts[stat] += 1 msg = f"📊 Status:\nRunning: {counts['running']} 🔄\nDone: {counts['sleep']} ✅\nError: {counts['error']} ❌" bot.send_message(message.chat.id, msg) @bot.message_handler(commands=['myscripts']) def my_scripts(message): chat_id = str(message.chat.id) db = load_db() scripts = db.get(chat_id, []) if not scripts: bot.send_message(message.chat.id, "📂 No scripts found.") return msg = "📜 Your Scripts:\n" for s in scripts: stat = status_map.get(s, 'unknown') icon = {'running': '🔄', 'sleep': '✅', 'error': '❌'}.get(stat, '❓') msg += f"{icon} {s} - {stat}\n" bot.send_message(message.chat.id, msg) # === BUTTON HANDLERS === @bot.message_handler(func=lambda m: m.text == '📥 Upload Script') def upload_script_btn(message): bot.send_message(message.chat.id, "📂 Send your .py file now.") file_upload_mode[message.chat.id] = True @bot.message_handler(func=lambda m: m.text == '📜 My Scripts') def my_scripts_btn(message): my_scripts(message) @bot.message_handler(func=lambda m: m.text == '📊 Status') def status_btn(message): status_all(message) @bot.message_handler(func=lambda m: m.text == '🔄 Refresh') def refresh_btn(message): start_message(message) # === FILE HANDLER === @bot.message_handler(content_types=['document']) def handle_file(message): if message.chat.id not in file_upload_mode: return file_info = bot.get_file(message.document.file_id) if not file_info.file_path.endswith(".py"): bot.send_message(message.chat.id, "❌ Only .py files allowed.") return file_data = bot.download_file(file_info.file_path) filename = generate_filename() filepath = os.path.join(SCRIPT_DIR, filename) with open(filepath, "wb") as f: f.write(file_data) chat_id = str(message.chat.id) db = load_db() db.setdefault(chat_id, []).append(filename) save_db(db) try: proc = subprocess.Popen(["python3", filepath], stdout=subprocess.PIPE, stderr=subprocess.PIPE) status_map[filename] = 'running' bot.send_message(message.chat.id, f"✅ Script `{filename}` is running.") threading.Thread(target=lambda: update_status(filename, proc)).start() except Exception as e: status_map[filename] = 'error' bot.send_message(message.chat.id, f"❌ Failed: {e}") file_upload_mode.pop(message.chat.id, None) # === FLASK ROUTES === @app.route('/') def home(): return "✅ XOOM Bot Running - dexsecon/xoomhost" @app.route('/ping') def ping(): return "✅ Ping OK" # === START EVERYTHING === threading.Thread(target=lambda: bot.infinity_polling(), daemon=True).start() threading.Thread(target=auto_ping, daemon=True).start() if __name__ == '__main__': app.run(host='0.0.0.0', port=PORT)