Spaces:
Sleeping
Sleeping
| """ | |
| 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')}" | |
| 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="/") | |
| 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) | |