diff --git a/client.py b/client.py index 31f8d168..81403e3f 100644 --- a/client.py +++ b/client.py @@ -1,6 +1,5 @@ import py3xui -from config import TOTAL_GB from logger import logger @@ -14,6 +13,7 @@ async def add_client( expiry_time: int, enable: bool, flow: str, + inbound_id: int, ): """ Adds a client to the server via 3x-ui. @@ -25,7 +25,7 @@ async def add_client( id=client_id, email=email.lower(), limit_ip=limit_ip, - total_gb=TOTAL_GB, + total_gb=total_gb, expiry_time=expiry_time, enable=enable, tg_id=tg_id, @@ -33,7 +33,7 @@ async def add_client( flow=flow, ) - response = await xui.client.add(1, [client]) + response = await xui.client.add(inbound_id, [client]) logger.info(f"Клиент {email} успешно добавлен с ID {client_id}.") @@ -44,7 +44,7 @@ async def add_client( return {"status": "failed", "error": str(e)} -async def extend_client_key(xui, email: str, new_expiry_time: int, client_id: str, total_gb: int): +async def extend_client_key(xui, inbound_id, email: str, new_expiry_time: int, client_id: str, total_gb: int): """ Функция для обновления срока действия ключа клиента по email. """ @@ -69,6 +69,7 @@ async def extend_client_key(xui, email: str, new_expiry_time: int, client_id: st client.total_gb = total_gb client.enable = True client.limit_ip = 1 + client.inbound_id = inbound_id await xui.client.update(client.id, client) logger.info(f"Ключ клиента {client.email} успешно продлён до {new_expiry_time}.") @@ -79,6 +80,7 @@ async def extend_client_key(xui, email: str, new_expiry_time: int, client_id: st async def delete_client( xui, + inbound_id: int, email: str, client_id: str, ) -> bool: @@ -95,7 +97,6 @@ async def delete_client( return False client.id = client_id - inbound_id = 1 await xui.client.delete(inbound_id, client.id) logger.info(f"Клиент с ID {client_id} был удален успешно.") diff --git a/handlers/keys/key_utils.py b/handlers/keys/key_utils.py index 4418b02d..9c18756a 100644 --- a/handlers/keys/key_utils.py +++ b/handlers/keys/key_utils.py @@ -23,6 +23,11 @@ async def create_key_on_cluster(cluster_id, tg_id, client_id, email, expiry_time password=ADMIN_PASSWORD, ) + inbound_id = server_info.get("INBOUND_ID") + if not inbound_id: + logger.warning(f"INBOUND_ID отсутствует для сервера {server_info.get('name', 'unknown')}. Пропуск.") + continue + conn = await asyncpg.connect(DATABASE_URL) existing_key = await conn.fetchrow("SELECT 1 FROM keys WHERE email = $1", email) @@ -40,6 +45,7 @@ async def create_key_on_cluster(cluster_id, tg_id, client_id, email, expiry_time expiry_time=expiry_timestamp, enable=True, flow="xtls-rprx-vision", + inbound_id=int(inbound_id), ) ) await conn.close() @@ -70,7 +76,21 @@ async def renew_key_in_cluster(cluster_id, email, client_id, new_expiry_time, to password=ADMIN_PASSWORD, ) - tasks.append(extend_client_key(xui, email, new_expiry_time, client_id, total_gb)) + inbound_id = server_info.get("INBOUND_ID") + if not inbound_id: + logger.warning(f"INBOUND_ID отсутствует для сервера {server_info.get('name', 'unknown')}. Пропуск.") + continue + + tasks.append( + extend_client_key( + xui, + int(inbound_id), + email, + new_expiry_time, + client_id, + total_gb, + ) + ) await asyncio.gather(*tasks) @@ -78,7 +98,6 @@ async def renew_key_in_cluster(cluster_id, email, client_id, new_expiry_time, to logger.error(f"Не удалось продлить ключ {client_id} в кластере {cluster_id}: {e}") raise e - async def delete_key_from_db(client_id, session): try: await session.execute("DELETE FROM keys WHERE client_id = $1", client_id) @@ -102,7 +121,19 @@ async def delete_key_from_cluster(cluster_id, email, client_id): password=ADMIN_PASSWORD, ) - tasks.append(delete_client(xui, email, client_id)) + inbound_id = server_info.get("INBOUND_ID") + if not inbound_id: + logger.warning(f"INBOUND_ID отсутствует для сервера {server_info.get('name', 'unknown')}. Пропуск.") + continue + + tasks.append( + delete_client( + xui, + int(inbound_id), + email, + client_id, + ) + ) await asyncio.gather(*tasks) @@ -126,6 +157,11 @@ async def update_key_on_cluster(tg_id, client_id, email, expiry_time, cluster_id password=ADMIN_PASSWORD, ) + inbound_id = server_info.get("INBOUND_ID") + if not inbound_id: + logger.warning(f"INBOUND_ID отсутствует для сервера {server_info.get('name', 'unknown')}. Пропуск.") + continue + tasks.append( add_client( xui, @@ -137,6 +173,7 @@ async def update_key_on_cluster(tg_id, client_id, email, expiry_time, cluster_id expiry_time=expiry_time, enable=True, flow="xtls-rprx-vision", + inbound_id=int(inbound_id), ) ) @@ -146,4 +183,4 @@ async def update_key_on_cluster(tg_id, client_id, email, expiry_time, cluster_id except Exception as e: logger.error(f"Ошибка при обновлении ключа на серверах кластера {cluster_id} для {client_id}: {e}") - raise e + raise e \ No newline at end of file diff --git a/handlers/keys/trial_key.py b/handlers/keys/trial_key.py index 13c74362..8cf10ecf 100644 --- a/handlers/keys/trial_key.py +++ b/handlers/keys/trial_key.py @@ -5,7 +5,7 @@ import uuid from py3xui import AsyncApi from client import add_client -from config import ADMIN_PASSWORD, ADMIN_USERNAME, CLUSTERS, PUBLIC_LINK, TRIAL_TIME +from config import ADMIN_PASSWORD, ADMIN_USERNAME, CLUSTERS, PUBLIC_LINK, TRIAL_TIME, TOTAL_GB from database import store_key, use_trial from handlers.texts import INSTRUCTIONS from handlers.utils import generate_random_email, get_least_loaded_cluster @@ -22,23 +22,29 @@ async def create_trial_key(tg_id: int, session: Any): expiry_timestamp = int(expiry_time.timestamp() * 1000) least_loaded_cluster = await get_least_loaded_cluster() - for server_id, server in CLUSTERS[least_loaded_cluster].items(): + + for server_id, server_info in CLUSTERS[least_loaded_cluster].items(): xui = AsyncApi( - CLUSTERS[least_loaded_cluster][server_id]["API_URL"], + server_info["API_URL"], username=ADMIN_USERNAME, password=ADMIN_PASSWORD, ) + inbound_id = server_info.get("INBOUND_ID") + if not inbound_id: + raise ValueError(f"INBOUND_ID отсутствует для сервера {server_info.get('name', 'unknown')}") + await add_client( xui, client_id, email, tg_id, limit_ip=1, - total_gb=0, + total_gb=TOTAL_GB, expiry_time=expiry_timestamp, enable=True, flow="xtls-rprx-vision", + inbound_id=int(inbound_id), ) await store_key( @@ -48,6 +54,7 @@ async def create_trial_key(tg_id: int, session: Any): expiry_timestamp, public_link, server_id=least_loaded_cluster, + session=session, ) await use_trial(tg_id, session) return result diff --git a/handlers/payments/cryprobot_pay.py b/handlers/payments/cryprobot_pay.py index 3704de6b..67cdd3c6 100644 --- a/handlers/payments/cryprobot_pay.py +++ b/handlers/payments/cryprobot_pay.py @@ -57,7 +57,7 @@ async def process_callback_pay_cryptobot(callback_query: types.CallbackQuery, st builder.row(InlineKeyboardButton(text="⬅️ Назад", callback_data="view_profile")) - key_count = await get_key_count(tg_id) + key_count = await get_key_count(callback_query.message.chat.id) if key_count == 0: exists = await check_connection_exists(callback_query.message.chat.id) if not exists: