From 0e43b369018fbbf035b8a0483aa58dd7c1f4609e Mon Sep 17 00:00:00 2001 From: Vlad Date: Thu, 26 Sep 2024 02:38:32 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=B9?= =?UTF-8?q?=20=D0=B8=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=81=D1=83=D1=82=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot.py | 3 +- client.py | 1 + handlers/__pycache__/keys.cpython-310.pyc | Bin 8931 -> 9044 bytes .../__pycache__/notifications.cpython-310.pyc | Bin 1627 -> 2689 bytes handlers/__pycache__/pay.cpython-310.pyc | Bin 7951 -> 7951 bytes handlers/keys.py | 11 ++++++-- handlers/notifications.py | 26 ++++++++++++++++++ handlers/pay.py | 2 +- key_management.py | 22 +++++++++++++-- 9 files changed, 58 insertions(+), 7 deletions(-) diff --git a/bot.py b/bot.py index b22f25db..622fc347 100644 --- a/bot.py +++ b/bot.py @@ -9,7 +9,7 @@ storage = MemoryStorage() dp = Dispatcher(bot=bot, storage=storage) router = Router() -from handlers import balance, keys, pay, profile, start +from handlers import balance, keys, pay, profile, start, notifications from key_management import router as key_management_router # Регистрация обработчиков @@ -19,6 +19,7 @@ dp.include_router(keys.router) dp.include_router(balance.router) dp.include_router(key_management_router) dp.include_router(pay.router) +dp.include_router(notifications.router) diff --git a/client.py b/client.py index 87587bab..19fb12b3 100644 --- a/client.py +++ b/client.py @@ -40,6 +40,7 @@ def add_client(session, client_id: str, email: str, tg_id: str, limit_ip: int, t if response.status_code == 200: print(f"Клиент добавлен: email={email}") + return response.json() else: print(f"Ошибка при добавлении клиента: {response.status_code}, {response.text}") diff --git a/handlers/__pycache__/keys.cpython-310.pyc b/handlers/__pycache__/keys.cpython-310.pyc index 028d3eb07049c57fd5c7e2a565dd4ec08fabf4d7..0500dff1b7dcf0f37d8c22b45355ecd83b596b60 100644 GIT binary patch delta 873 zcmYjOPe>F|7=Pb5uH)>^?9Tpk|G4e!YL*b*JZR)4jFdIY|-` z{T%myjX&smF2@DgODWTKDDvOQpb{p-g3q(5^Tm4IR)Ri+(RpO@b5F^l&;%Rgp>S%! z6b-RxFCi>Ufp!5mn)a;U5YrCIdF?8uZrZVm9&=P@y@c%{WIC|J_@`pYu&p928$waW z&JxhxW!UM2&6IR!+JzPDHtN_0>?v@jT+_VRS7T0nfkphd>A#4p775^BEuv7S7;*{> zCxwebNkNLop#qq0-JSLrk^u%vd(%F{jl;OPP=9bIpsdV%969ur z#C?De`RW*Gmh_yS$c*HZW4SEOS9zS6%~u-^DCv>TN?y%R_i3H1bdzgA4=G7)C-uqc zJq@g*+2vtL{0>OBRAyZFiOIq zR`O160i8tszA`x90&U;B!jP<4jYZmQg9)+|jn!*c zs7QWBJ0L^iY9CCJj2ebCSy5HnG`l`ao~d1Q*B3Pb^Q1r4OJBMh>j9DM#@2kJERtkp Yij^EI^JFF7uXMV>Ayc$cv{7{b1y4iyCjbBd delta 763 zcmY*WOK1~87@mK#iR&gi$!?m>qfMHGRwzm>3Q|235mRkZJSc|Zp|45OrfmYrN=%ux z7SB2TUTiHSQ1Ghcq#nK0;L%g97X>}^rl(xQ*_5CTeE-h(n13GoY5H4+mNiW!Vm!F^ zE5AMYnx+*R6x7k)3sgHerA!20T5{8Ed0H?-7`aJodGi@=D`D8f=gPUQqSscr%9J&^ za+{sz>Mq%nO2Aax%e>sPOPG%xl6_pcu{?WZtpN2tFiVi?=e6GC$&3NW{dUep;EOf zd24k8Uq#R3k)}cre`uMWhZ8h{_vk~I#tt3!s9;J8V3&@V{nCW&$-*-V4%b^!S@R=D{aXP^QJ~C6#YVVjI zC16;H{`9n*ju%ijLukcPur6{V_%?PH4%**iUnN+^5AmGBL~0Bw_uH2erzFUU#_^y_ zXos3rwiegttGVTJiB*v$$6*yQIRkn8k{pBrc9Tg@Q6wvCIGnl+2RN5nggU-UWyAp> kJq0ejn%)o1JCP-)tT<)eDRu0oXZ3Ldd{kgW;EcePKSa91sQ>@~ diff --git a/handlers/__pycache__/notifications.cpython-310.pyc b/handlers/__pycache__/notifications.cpython-310.pyc index 80b1e136c6ac10cc73f858f63ed8badd6302eb40..c354ebf23502ac51d83aeca7cf655d8fde3c12cb 100644 GIT binary patch delta 1223 zcmZ8g&2Jk;6rVRcyK6gZ$8kSYK7>}H4Op()9x5tTQ6RKPRD>SdB7_e_# zT2Ue!=j(tF1vB}d%KB}7C-w4?|Af!XVFgg*gsf`t@@#8I=(ZhSS^8+I=>tJDae9&1sa=Y?%nFM5Sx$;SFD`Rr!*3q;6o z<(}M^Kgol1Q|`MruDkMyJd}^pFXhj;?#bQLDuIEoU3uVY|Ce+l-Ao$n)IbII+;m$W zrt9*t+*RqTg_&l^z1fSSirsGHi3Oh@`*r4`28c;KzY3zFm&|H(q7_eIK;27BADP$C z%Sxl&7RHyqgt3SX(9-oYhB%MTGfb#%QT?Qu_zs;B6GPyrw3uI;R=f=94*8h&p-=k; zr$eJ>>_Fd$*^=3#J>xiIJu(TqzYYz}LW^zD2)MPRe+pF&Z=`$c}6%Dp}>^^xw zkD!SB2(f+k8B_F+ycJj(iDBPdv&Vd8;8v+9W65F)P4^BO`Tba=LnQeTs`0BlK(W%< zt#kwB+D|{n$f1iWY|1C7#4f@|FbqB?=UC0J+zgT{>`j#Ls$0$Jv$8@IH$)t*`0=Ni z87;T{IAcqp-_boQR6~iHGB2a4np&sK9xIaBW1;m{;+(=gr{T$E5jMRjTF_eh%|`5p zway!ejLx8;>kg$*rUf`@yaFY97IN$KKlZn{td6UQ6Ujg3O9P>#6_zsUC1sNhKU@@z z;6lr9<2#H*PDL#-dX-i)?6mwvkym*2kj6#7k7YC#J>58Z|6{f4s&&)lW`dA++up2t bSo%TbULa*~KurfM>d+D`pRIspo`(Mcu6SPt delta 229 zcmZn^z0ISY&&$ij00ak}Kd0?wXJB{?;vfTNAjbiSi=8HF>qxWavPH2mGNiDkvZOJk zu%)oKutc$^Fa|Sda!kCXD#Cb+$Hg(k(aAB`H9j=R=N5BPe#vGt#wW~-tdoIy8QCUx zvTAd40*xyI*;>Rsc|WTGqw?ertUiqFlWp0YIaGndnjA#}lh1KVJKthU&d*EBOfO;u oDF#UuDWei9K<+ILo80`A(wtN~Mj)>kWH1MV03#1050elR0MyGZDF6Tf diff --git a/handlers/__pycache__/pay.cpython-310.pyc b/handlers/__pycache__/pay.cpython-310.pyc index 65cf0116fc04a722e174dff89ced4e09e22dbb93..97a39129c1bb0f247c613f539447d6458e14ccf0 100644 GIT binary patch delta 22 ccmeCT>$l_0=jG*M0D|6$U((iW$l_0=jG*M00MpOPibp6@-oQ-06r82c>n+a diff --git a/handlers/keys.py b/handlers/keys.py index 064d3517..ab89bb5e 100644 --- a/handlers/keys.py +++ b/handlers/keys.py @@ -79,9 +79,16 @@ async def process_callback_view_key(callback_query: types.CallbackQuery): expiry_time = record['expiry_time'] expiry_date = datetime.utcfromtimestamp(expiry_time / 1000) current_date = datetime.utcnow() - days_left = (expiry_date - current_date).days + time_left = expiry_date - current_date + + if time_left.total_seconds() <= 0: + days_left_message = "Ключ истек." + elif time_left.days > 0: + days_left_message = f"Осталось дней: {time_left.days}" + else: + hours_left = time_left.seconds // 3600 + days_left_message = f"Осталось часов: {hours_left}" - days_left_message = f"Осталось дней: {days_left}" if days_left > 0 else "Ключ истек." response_message = (f"Ваш ключ:\n
{key}
\n" f"Дата окончания: {expiry_date.strftime('%Y-%m-%d %H:%M:%S')}\n" f"{days_left_message}") diff --git a/handlers/notifications.py b/handlers/notifications.py index 42c57a76..6ddce0db 100644 --- a/handlers/notifications.py +++ b/handlers/notifications.py @@ -1,6 +1,11 @@ import asyncpg from datetime import datetime, timedelta from aiogram import Bot +from aiogram import Router, types +from bot import bot +from aiogram.filters import Command + +router = Router() from config import DATABASE_URL @@ -39,3 +44,24 @@ async def notify_expiring_keys(bot: Bot): await conn.close() except Exception as e: print(f"Ошибка при отправке уведомлений: {e}") + +@router.message(Command(commands=['notify'])) +async def notify_command(message: types.Message): + # Запрашиваем у администратора ID пользователя и текст уведомления + await message.answer("Введите ID пользователя и текст уведомления в формате:\n/notify user_id текст", parse_mode="HTML") + +# Обработка команды уведомления +@router.message() +async def process_notification(message: types.Message): + if message.text.startswith("/notify"): + try: + # Парсим команду + command, user_id, *text = message.text.split() + text = ' '.join(text) + + # Отправляем сообщение пользователю + await bot.send_message(chat_id=user_id, text=text) + await message.answer(f"Уведомление успешно отправлено пользователю {user_id}.") + + except Exception as e: + await message.answer(f"Ошибка при отправке уведомления: {e}") diff --git a/handlers/pay.py b/handlers/pay.py index 1828e21f..826f3d6f 100644 --- a/handlers/pay.py +++ b/handlers/pay.py @@ -232,4 +232,4 @@ async def process_admin_confirmation(callback_query: types.CallbackQuery, state: finally: await state.clear() - await callback_query.answer() + await callback_query.answer() \ No newline at end of file diff --git a/key_management.py b/key_management.py index 9cd058ec..2336a92e 100644 --- a/key_management.py +++ b/key_management.py @@ -9,6 +9,7 @@ from aiogram.fsm.context import FSMContext from aiogram.fsm.state import State, StatesGroup from aiogram.types import (CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message) +from pytz import timezone from auth import link, login_with_credentials from bot import bot, dp @@ -139,7 +140,7 @@ async def handle_key_name_input(message: Message, state: FSMContext): if trial_status == 0: # Создаем пробный ключ на 1 день - expiry_time = int((current_time + timedelta(days=1)).timestamp() * 1000) + expiry_time = int((current_time + timedelta(days=1, hours=3)).timestamp() * 1000) else: # Проверяем баланс перед созданием нового ключа balance = await get_balance(tg_id) @@ -151,10 +152,23 @@ async def handle_key_name_input(message: Message, state: FSMContext): return await update_balance(tg_id, -100) - expiry_time = int((current_time + timedelta(days=30)).timestamp() * 1000) + expiry_time = int((current_time + timedelta(days=30, hours=3)).timestamp() * 1000) try: - add_client(session, client_id, email, tg_id, limit_ip=1, total_gb=0, expiry_time=expiry_time, enable=True, flow="xtls-rprx-vision") + # Попробуем добавить клиента + response = add_client(session, client_id, email, tg_id, limit_ip=1, total_gb=0, expiry_time=expiry_time, enable=True, flow="xtls-rprx-vision") + + # Проверяем статус ответа от сервера + if not response.get("success", True): + error_msg = response.get("msg", "Неизвестная ошибка.") + if "Duplicate email" in error_msg: + await message.bot.send_message(tg_id, "❌ Этот email уже используется. Пожалуйста, выберите другое имя для ключа.") + await state.set_state(Form.waiting_for_key_name) # Возвращаем пользователя к вводу имени ключа + return + else: + raise Exception(error_msg) + + # Если добавление клиента прошло успешно, получаем ссылку connection_link = link(session, client_id, email) # Проверка существующей записи @@ -182,6 +196,7 @@ async def handle_key_name_input(message: Message, state: FSMContext): f"
{connection_link}
" ) await message.bot.send_message(tg_id, key_message, parse_mode="HTML", reply_markup=keyboard) + except Exception as e: await message.bot.send_message(tg_id, f"❌ Ошибка при создании ключа: {e}") @@ -189,6 +204,7 @@ async def handle_key_name_input(message: Message, state: FSMContext): + @dp.callback_query(F.data == 'instructions') async def handle_instructions(callback_query: CallbackQuery): instructions_message = (