""" HuggingFace Spaces Entry Point for Jade Bot """ import os import socket import logging import asyncio import httpx from datetime import datetime from fastapi import FastAPI, Request from telegram import Update from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler, filters import uvicorn import gradio as gr # Direct IP for Telegram API TELEGRAM_IP = "149.154.167.220" def custom_getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): if "telegram" in str(host).lower(): return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (TELEGRAM_IP, port if port else 443))] return socket._original_getaddrinfo(host, port, socket.AF_INET, type, proto, flags) socket._original_getaddrinfo = socket.getaddrinfo socket.getaddrinfo = custom_getaddrinfo logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO) logger = logging.getLogger(__name__) bot_status = {"started_at": None, "is_running": False, "error": None} application = None app = FastAPI() def get_status(): if bot_status.get("error"): return f"🔴 Error: {bot_status['error']}" if not bot_status["is_running"]: return "🟡 Bot starting..." return f"## 🟢 Jade Running!\n- Started: {bot_status.get('started_at')}" @app.post("/webhook") async def webhook(request: Request): global application if application: data = await request.json() update = Update.de_json(data, application.bot) await application.process_update(update) return {"ok": True} async def setup_bot(): global application, bot_status token = os.getenv("TELEGRAM_BOT_TOKEN") space_url = os.getenv("SPACE_URL", "") if not token: bot_status["error"] = "TELEGRAM_BOT_TOKEN not set!" return if not space_url: space_id = os.getenv("SPACE_ID", "") if space_id: space_url = f"https://{space_id.replace('/', '-')}.hf.space" else: bot_status["error"] = "SPACE_URL not set!" return logger.info(f"Space URL: {space_url}") # Wait for network await asyncio.sleep(3) try: from core import TelegramJadeAgent from tools import ReminderManager reminder_manager = ReminderManager() agent = TelegramJadeAgent(reminder_manager=reminder_manager) async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): await context.bot.send_message(chat_id=update.effective_chat.id, text="Hi! I'm Jade 🌿") async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE): chat_id = update.effective_chat.id user_text = update.message.text loop = asyncio.get_event_loop() response = await loop.run_in_executor(None, agent.chat, chat_id, user_text) await context.bot.send_message(chat_id=chat_id, text=response) # Build with extended timeouts from telegram.ext import Defaults from telegram.request import HTTPXRequest request = HTTPXRequest( connection_pool_size=8, read_timeout=30, write_timeout=30, connect_timeout=30, pool_timeout=30 ) application = ( ApplicationBuilder() .token(token) .request(request) .get_updates_request(request) .build() ) application.add_handler(CommandHandler('start', start)) application.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), handle_message)) webhook_url = f"{space_url}/webhook" for attempt in range(5): try: logger.info(f"Attempt {attempt + 1}/5: Initializing...") await application.initialize() logger.info(f"Setting webhook to {webhook_url}...") await application.bot.set_webhook(url=webhook_url, drop_pending_updates=True) logger.info("✅ Webhook set successfully!") bot_status["started_at"] = datetime.now().strftime("%H:%M:%S") bot_status["is_running"] = True return except Exception as e: logger.warning(f"Attempt {attempt + 1} failed: {e}") if attempt < 4: await asyncio.sleep(10) bot_status["error"] = "Failed after 5 attempts" except Exception as e: logger.error(f"Bot setup failed: {e}") bot_status["error"] = str(e) def create_gradio(): with gr.Blocks(title="Jade Bot") as demo: gr.Markdown("# 🌿 Jade - 24h Personal Assistant") status = gr.Markdown(get_status) gr.Button("🔄 Refresh").click(fn=get_status, outputs=status) return demo gradio_app = create_gradio() app = gr.mount_gradio_app(app, gradio_app, path="/") @app.on_event("startup") async def startup_event(): logger.info("Starting bot setup...") asyncio.create_task(setup_bot()) if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=7860)