forked from ilyarolf/AiogramShopBot
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbot.py
More file actions
162 lines (146 loc) · 5.72 KB
/
bot.py
File metadata and controls
162 lines (146 loc) · 5.72 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import logging
import sys
import traceback
from pathlib import Path
from aiogram.client.default import DefaultBotProperties
from aiogram.fsm.storage.redis import RedisStorage
from aiogram.types import BufferedInputFile, URLInputFile
from redis.asyncio import Redis
from sqladmin import Admin
import config
from aiogram import Bot, Dispatcher
from aiogram.enums import ParseMode
from fastapi import FastAPI, Request, status, HTTPException
from admin import authentication_backend
from db import create_db_and_tables, engine
import uvicorn
from fastapi.responses import JSONResponse
from enums.cryptocurrency import Cryptocurrency
from models.buy import BuyAdmin
from models.buyItem import BuyItemAdmin
from models.cart import CartAdmin
from models.cartItem import CartItemAdmin
from models.category import CategoryAdmin
from models.coupon import CouponAdmin
from models.deposit import DepositAdmin
from models.item import ItemAdmin
from models.payment import PaymentAdmin
from models.referral import ReferralBonusAdmin
from models.review import ReviewAdmin
from models.shipping_option import ShippingOptionAdmin
from models.subcategory import SubcategoryAdmin
from models.user import UserAdmin
from processing.processing import processing_router
from repositories.button_media import ButtonMediaRepository
from services.media import MediaService
from services.notification import NotificationService
from services.wallet import WalletService
from utils.utils import validate_i18n
redis = Redis(host=config.REDIS_HOST, password=config.REDIS_PASSWORD)
bot = Bot(config.TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))
dp = Dispatcher(storage=RedisStorage(redis))
app = FastAPI()
admin = Admin(app=app, engine=engine, authentication_backend=authentication_backend)
admin.add_model_view(UserAdmin)
admin.add_model_view(BuyAdmin)
admin.add_model_view(ShippingOptionAdmin)
admin.add_model_view(CouponAdmin)
admin.add_model_view(CategoryAdmin)
admin.add_model_view(SubcategoryAdmin)
admin.add_model_view(ItemAdmin)
admin.add_model_view(DepositAdmin)
admin.add_model_view(BuyItemAdmin)
admin.add_model_view(PaymentAdmin)
admin.add_model_view(CartAdmin)
admin.add_model_view(CartItemAdmin)
admin.add_model_view(ReferralBonusAdmin)
admin.add_model_view(ReviewAdmin)
app.include_router(processing_router)
@app.post(config.WEBHOOK_PATH)
async def webhook(request: Request):
secret_token = request.headers.get("X-Telegram-Bot-Api-Secret-Token")
if secret_token != config.WEBHOOK_SECRET_TOKEN:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Unauthorized")
try:
update_data = await request.json()
await dp.feed_webhook_update(bot, update_data)
return {"status": "ok"}
except Exception as e:
logging.error(f"Error processing webhook: {e}")
return {"status": "error"}, status.HTTP_500_INTERNAL_SERVER_ERROR
@app.on_event("startup")
async def on_startup():
await create_db_and_tables()
await bot.set_webhook(
url=config.WEBHOOK_URL,
secret_token=config.WEBHOOK_SECRET_TOKEN
)
static = Path("static")
if static.exists() is False:
static.mkdir()
me = await bot.get_me()
photos = await bot.get_user_profile_photos(me.id)
if photos.total_count == 0:
photo_id_list = []
for admin_id in config.ADMIN_ID_LIST:
try:
msg = await bot.send_photo(chat_id=admin_id,
photo=URLInputFile(url="https://img.freepik.com/premium-vector/no-photo-available-vector-icon-default-image-symbol-picture-coming-soon-web-site-mobile-app_87543-18055.jpg",
filename="no_image.png"))
bot_photo_id = msg.photo[-1].file_id
photo_id_list.append(bot_photo_id)
except Exception as _:
pass
bot_photo_id = photo_id_list[0]
else:
bot_photo_id = photos.photos[0][-1].file_id
with open("static/no_image.jpeg", "w") as f:
f.write(bot_photo_id)
await MediaService.update_inaccessible_media(bot)
validate_i18n()
await ButtonMediaRepository.init_buttons_media()
if config.CRYPTO_FORWARDING_MODE:
for cryptocurrency in Cryptocurrency:
is_addr_valid = WalletService.validate_withdrawal_address(
cryptocurrency.get_forwarding_address(),
cryptocurrency
)
if is_addr_valid is False:
logging.debug(
f"Your withdrawal address for {cryptocurrency.name} cryptocurrency is not valid!"
)
sys.exit()
for admin in config.ADMIN_ID_LIST:
try:
await bot.send_message(admin, 'Bot is working')
except Exception as e:
logging.warning(e)
@app.on_event("shutdown")
async def on_shutdown():
logging.warning('Shutting down..')
await bot.delete_webhook()
await dp.storage.close()
logging.warning('Bye!')
@app.exception_handler(Exception)
async def exception_handler(request: Request, exc: Exception):
traceback_str = traceback.format_exc()
admin_notification = (
f"Critical error caused by {exc}\n\n"
f"Stack trace:\n{traceback_str}"
)
if len(admin_notification) > 4096:
byte_array = bytearray(admin_notification, 'utf-8')
admin_notification = BufferedInputFile(byte_array, "exception.txt")
await NotificationService.send_to_admins(admin_notification, None)
return JSONResponse(
status_code=500,
content={"message": f"An error occurred: {str(exc)}"},
)
def main() -> None:
uvicorn.run(
app,
host=config.WEBAPP_HOST,
port=config.WEBAPP_PORT,
proxy_headers=True,
forwarded_allow_ips="*",
)