|
1 | 1 | import logging |
2 | 2 | import sys |
3 | 3 | import traceback |
| 4 | +from contextlib import asynccontextmanager |
4 | 5 | from pathlib import Path |
5 | | -from aiogram.client.default import DefaultBotProperties |
6 | 6 | from aiogram.fsm.storage.redis import RedisStorage |
7 | 7 | from aiogram.types import BufferedInputFile, URLInputFile |
8 | 8 | from redis.asyncio import Redis |
9 | 9 | from sqladmin import Admin |
10 | 10 |
|
11 | 11 | import config |
12 | | -from aiogram import Bot, Dispatcher |
13 | | -from aiogram.enums import ParseMode |
| 12 | +from aiogram import Dispatcher |
14 | 13 | from fastapi import FastAPI, Request, status, HTTPException |
15 | 14 |
|
16 | 15 | from admin import authentication_backend |
|
37 | 36 | from services.media import MediaService |
38 | 37 | from services.notification import NotificationService |
39 | 38 | from services.wallet import WalletService |
| 39 | +from utils.telegram import create_bot, create_telegram_session |
40 | 40 | from utils.utils import validate_i18n |
41 | 41 |
|
42 | 42 | redis = Redis(host=config.REDIS_HOST, password=config.REDIS_PASSWORD) |
43 | | -bot = Bot(config.TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML)) |
| 43 | +session = create_telegram_session() |
| 44 | +bot = create_bot(config.TOKEN, session) |
44 | 45 | dp = Dispatcher(storage=RedisStorage(redis)) |
45 | | -app = FastAPI() |
46 | | -admin = Admin(app=app, engine=engine, authentication_backend=authentication_backend) |
47 | | -admin.add_model_view(UserAdmin) |
48 | | -admin.add_model_view(BuyAdmin) |
49 | | -admin.add_model_view(ShippingOptionAdmin) |
50 | | -admin.add_model_view(CouponAdmin) |
51 | | -admin.add_model_view(CategoryAdmin) |
52 | | -admin.add_model_view(SubcategoryAdmin) |
53 | | -admin.add_model_view(ItemAdmin) |
54 | | -admin.add_model_view(DepositAdmin) |
55 | | -admin.add_model_view(BuyItemAdmin) |
56 | | -admin.add_model_view(PaymentAdmin) |
57 | | -admin.add_model_view(CartAdmin) |
58 | | -admin.add_model_view(CartItemAdmin) |
59 | | -admin.add_model_view(ReferralBonusAdmin) |
60 | | -admin.add_model_view(ReviewAdmin) |
61 | | - |
62 | | -app.include_router(processing_router) |
63 | 46 |
|
64 | 47 |
|
65 | | -@app.post(config.WEBHOOK_PATH) |
66 | | -async def webhook(request: Request): |
67 | | - secret_token = request.headers.get("X-Telegram-Bot-Api-Secret-Token") |
68 | | - if secret_token != config.WEBHOOK_SECRET_TOKEN: |
69 | | - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Unauthorized") |
70 | | - |
71 | | - try: |
72 | | - update_data = await request.json() |
73 | | - await dp.feed_webhook_update(bot, update_data) |
74 | | - return {"status": "ok"} |
75 | | - except Exception as e: |
76 | | - logging.error(f"Error processing webhook: {e}") |
77 | | - return {"status": "error"}, status.HTTP_500_INTERNAL_SERVER_ERROR |
78 | | - |
79 | | - |
80 | | -@app.on_event("startup") |
81 | | -async def on_startup(): |
| 48 | +async def _startup() -> None: |
82 | 49 | await create_db_and_tables() |
83 | 50 | await bot.set_webhook( |
84 | 51 | url=config.WEBHOOK_URL, |
@@ -110,30 +77,74 @@ async def on_startup(): |
110 | 77 | await ButtonMediaRepository.init_buttons_media() |
111 | 78 | if config.CRYPTO_FORWARDING_MODE: |
112 | 79 | for cryptocurrency in Cryptocurrency: |
113 | | - is_addr_valid = WalletService.validate_withdrawal_address( |
114 | | - cryptocurrency.get_forwarding_address(), |
115 | | - cryptocurrency |
116 | | - ) |
| 80 | + forwarding_address = cryptocurrency.get_forwarding_address() |
| 81 | + is_addr_valid = WalletService.validate_withdrawal_address(forwarding_address, cryptocurrency) |
117 | 82 | if is_addr_valid is False: |
118 | | - logging.debug( |
119 | | - f"Your withdrawal address for {cryptocurrency.name} cryptocurrency is not valid!" |
| 83 | + logging.error( |
| 84 | + "Your withdrawal address for %s cryptocurrency is not configured correctly: %s", |
| 85 | + cryptocurrency.name, |
| 86 | + forwarding_address |
120 | 87 | ) |
121 | | - sys.exit() |
| 88 | + sys.exit(1) |
122 | 89 | for admin in config.ADMIN_ID_LIST: |
123 | 90 | try: |
124 | 91 | await bot.send_message(admin, 'Bot is working') |
125 | 92 | except Exception as e: |
126 | 93 | logging.warning(e) |
127 | 94 |
|
128 | 95 |
|
129 | | -@app.on_event("shutdown") |
130 | | -async def on_shutdown(): |
| 96 | +async def _shutdown() -> None: |
131 | 97 | logging.warning('Shutting down..') |
132 | 98 | await bot.delete_webhook() |
133 | 99 | await dp.storage.close() |
| 100 | + await bot.session.close() |
134 | 101 | logging.warning('Bye!') |
135 | 102 |
|
136 | 103 |
|
| 104 | +@asynccontextmanager |
| 105 | +async def lifespan(app: FastAPI): |
| 106 | + await _startup() |
| 107 | + try: |
| 108 | + yield |
| 109 | + finally: |
| 110 | + await _shutdown() |
| 111 | + |
| 112 | + |
| 113 | +app = FastAPI(lifespan=lifespan) |
| 114 | +admin = Admin(app=app, engine=engine, authentication_backend=authentication_backend) |
| 115 | +admin.add_model_view(UserAdmin) |
| 116 | +admin.add_model_view(BuyAdmin) |
| 117 | +admin.add_model_view(ShippingOptionAdmin) |
| 118 | +admin.add_model_view(CouponAdmin) |
| 119 | +admin.add_model_view(CategoryAdmin) |
| 120 | +admin.add_model_view(SubcategoryAdmin) |
| 121 | +admin.add_model_view(ItemAdmin) |
| 122 | +admin.add_model_view(DepositAdmin) |
| 123 | +admin.add_model_view(BuyItemAdmin) |
| 124 | +admin.add_model_view(PaymentAdmin) |
| 125 | +admin.add_model_view(CartAdmin) |
| 126 | +admin.add_model_view(CartItemAdmin) |
| 127 | +admin.add_model_view(ReferralBonusAdmin) |
| 128 | +admin.add_model_view(ReviewAdmin) |
| 129 | + |
| 130 | +app.include_router(processing_router) |
| 131 | + |
| 132 | + |
| 133 | +@app.post(config.WEBHOOK_PATH) |
| 134 | +async def webhook(request: Request): |
| 135 | + secret_token = request.headers.get("X-Telegram-Bot-Api-Secret-Token") |
| 136 | + if secret_token != config.WEBHOOK_SECRET_TOKEN: |
| 137 | + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Unauthorized") |
| 138 | + |
| 139 | + try: |
| 140 | + update_data = await request.json() |
| 141 | + await dp.feed_webhook_update(bot, update_data) |
| 142 | + return {"status": "ok"} |
| 143 | + except Exception as e: |
| 144 | + logging.error(f"Error processing webhook: {e}") |
| 145 | + return {"status": "error"}, status.HTTP_500_INTERNAL_SERVER_ERROR |
| 146 | + |
| 147 | + |
137 | 148 | @app.exception_handler(Exception) |
138 | 149 | async def exception_handler(request: Request, exc: Exception): |
139 | 150 | traceback_str = traceback.format_exc() |
|
0 commit comments