Spaces:
Runtime error
Runtime error
File size: 4,319 Bytes
d923177 c55be2e d923177 c55be2e d923177 df1c82c d923177 52cf66a df1c82c 52cf66a df1c82c 52cf66a d923177 c55be2e 52cf66a c55be2e df1c82c d923177 c55be2e df1c82c d923177 df1c82c ff8ed63 d923177 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | import asyncio
import logging
import socket
from aiogram import Bot, Dispatcher
from aiogram.client.default import DefaultBotProperties
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.enums import ParseMode
from aiogram.fsm.storage.memory import MemoryStorage
from aiohttp import TCPConnector, ClientTimeout, ClientSession, web
from config import BOT_TOKEN, TELEGRAM_API_URL
from database.db import init_db
from handlers import user, payment, admin
# βββββββββββββββββββ LOGGING βββββββββββββββββββ
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
logger = logging.getLogger(__name__)
class IPv4OnlyAiohttpSession(AiohttpSession):
"""Hugging Face Spaces-da IPv6 ulanish xatolarini chetlab o'tish uchun faqat IPv4-ni ishlatuvchi session.
Cloudflare Worker orqali Telegram API'ga ulanganda timeout'ni oshiramiz,
chunki Worker javoblari ba'zan sekinroq keladi.
"""
async def create_session(self) -> ClientSession:
if self._session is None or self._session.closed:
self._session = ClientSession(
connector=TCPConnector(family=socket.AF_INET),
timeout=ClientTimeout(total=60, connect=30, sock_connect=30, sock_read=30),
json_serialize=self.json_dumps
)
return self._session
async def start_web_server():
"""Hugging Face Spaces port tekshiruvidan o'tishi uchun dummy web server."""
async def handle(request):
return web.Response(text="Bot is running!")
app = web.Application()
app.router.add_get('/', handle)
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, '0.0.0.0', 7860)
await site.start()
logger.info("β
Web server 7860-portda ishga tushdi.")
async def main():
logger.info("π Bot ishga tushmoqda...")
# Ma'lumotlar bazasini yaratish/tekshirish
await init_db()
logger.info("β
Ma'lumotlar bazasi tayyor.")
# Hugging Face-da IPv6 ulanish xatolarining oldini olish uchun faqat IPv4 ni majburlaymiz
session = IPv4OnlyAiohttpSession()
# Telegram API manzilini tanlash:
# - Standart: https://api.telegram.org (HF bunda bloklaydi)
# - Worker orqali: TELEGRAM_API_URL (masalan, https://tg-proxy.xxx.workers.dev)
api_to_use = TELEGRAM_API_URL if TELEGRAM_API_URL != "https://api.telegram.org" else None
# Bot va Dispatcher yaratish
bot = Bot(
token=BOT_TOKEN,
session=session,
api=api_to_use,
default=DefaultBotProperties(parse_mode=ParseMode.HTML)
)
dp = Dispatcher(storage=MemoryStorage())
# Routerlarni ulash (tartib muhim: admin birinchi)
dp.include_router(admin.router)
dp.include_router(payment.router)
dp.include_router(user.router)
logger.info("β
Routerlar ulandi.")
# Web-serverni ishga tushirish
try:
await start_web_server()
except Exception as e:
logger.error(f"β Web-serverni ishga tushirishda xato: {e}")
# Boshlash β Worker ulanishi sekin bo'lishi mumkin, shu sababli
# birinchi so'rovni 3 marta qayta urinib ko'ramiz.
max_retries = 3
started = False
try:
for attempt in range(1, max_retries + 1):
try:
await bot.delete_webhook(drop_pending_updates=True)
logger.info("π€ Bot polling rejimida ishga tushdi.")
started = True
await dp.start_polling(bot, allowed_updates=dp.resolve_used_update_types())
break
except Exception as e:
logger.error(f"β Bot xatosi (urinish {attempt}/{max_retries}): {e}")
if attempt < max_retries:
logger.info("β³ 5 soniyadan so'ng qayta uriniladi...")
await asyncio.sleep(5)
else:
logger.error("β Bot ishga tushmadi β barcha urinishlar tugadi.", exc_info=True)
if not started:
logger.error("π΄ Bot Telegram'ga ulana olmadi.")
finally:
await bot.session.close()
logger.info("π΄ Bot to'xtatildi.")
if __name__ == "__main__":
asyncio.run(main())
|