From 2c960813def471f981bc84f8edacf252b9dee2c9 Mon Sep 17 00:00:00 2001 From: Legacyyy777 <162005411+Legacyyy777@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:38:39 +0500 Subject: [PATCH 1/6] restore deploy.yml for my fork deploy From d506ba7317e4b073bd53250088b4a713e086c22e Mon Sep 17 00:00:00 2001 From: Legacyyy777 <162005411+Legacyyy777@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:46:37 +0500 Subject: [PATCH 2/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D1=84=D0=B0=D0=B9=D0=BB=20=D0=BA=D0=BE=D0=BD=D1=84?= =?UTF-8?q?=D0=B8=D0=B3=D1=83=D1=80=D0=B0=D1=86=D0=B8=D0=B8=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=B4=D0=B5=D0=BF=D0=BB=D0=BE=D1=8F=20=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=20=D0=BD=D0=B0=20VPS=20=D0=BF=D1=80=D0=B8=20=D0=BF?= =?UTF-8?q?=D1=83=D1=88=D0=B5=20=D0=B2=20=D0=B2=D0=B5=D1=82=D0=BA=D1=83=20?= =?UTF-8?q?DEV?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..2e158c49 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,37 @@ +name: Deploy Bot + +on: + push: + branches: + - DEV # деплой только при пуше в DEV + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Deploy to VPS + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.VPS_HOST }} + username: ${{ secrets.VPS_USER }} + key: ${{ secrets.VPS_SSH_KEY }} + script: | + # если папки ещё нет — клонируем + if [ ! -d /opt/mybot/.git ]; then + rm -rf /opt/mybot + git clone https://github.com/Legacyyy777/remnawave-bedolaga-telegram-bot_777.git /opt/mybot + fi + + cd /opt/mybot + + # обновляем и переключаемся на DEV + git fetch origin + git checkout DEV + git reset --hard origin/DEV + + # пересобираем и запускаем контейнер + docker compose build --no-cache + docker compose up -d --force-recreate From e324e50713e7f6ac9dc4d4ea48be457b5a8072d7 Mon Sep 17 00:00:00 2001 From: Legacyyy777 <162005411+Legacyyy777@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:04:55 +0500 Subject: [PATCH 3/6] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5=D1=81=D1=81=20=D1=83=D0=B4?= =?UTF-8?q?=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8F=20RemnaWave:?= =?UTF-8?q?=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BF=D1=8B=D1=82=D0=BA=D0=B0=20=D1=83=D0=B4=D0=B0?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8F=20=D0=B8=D0=B7=20?= =?UTF-8?q?=D0=BF=D0=B0=D0=BD=D0=B5=D0=BB=D0=B8=20Remnawave=20=D1=81=20?= =?UTF-8?q?=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=BE=D0=B9=20?= =?UTF-8?q?=D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA=20=D0=B8=20=D1=80=D0=B5?= =?UTF-8?q?=D0=B7=D0=B5=D1=80=D0=B2=D0=BD=D1=8B=D0=BC=20=D0=B2=D0=B0=D1=80?= =?UTF-8?q?=D0=B8=D0=B0=D0=BD=D1=82=D0=BE=D0=BC=20=D0=B4=D0=B5=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D0=B8=D0=B2=D0=B0=D1=86=D0=B8=D0=B8=20=D1=87=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B7=20SubscriptionService.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/user_service.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/app/services/user_service.py b/app/services/user_service.py index ef8a1196..a7888488 100644 --- a/app/services/user_service.py +++ b/app/services/user_service.py @@ -240,12 +240,27 @@ class UserService: if user.remnawave_uuid: try: - from app.services.subscription_service import SubscriptionService - subscription_service = SubscriptionService() - await subscription_service.disable_remnawave_user(user.remnawave_uuid) - logger.info(f"✅ RemnaWave пользователь {user.remnawave_uuid} деактивирован") + from app.services.remnawave_service import RemnaWaveService + remnawave_service = RemnaWaveService() + + # Сначала попытаемся удалить пользователя из панели Remnawave + async with remnawave_service.api as api: + delete_success = await api.delete_user(user.remnawave_uuid) + if delete_success: + logger.info(f"✅ RemnaWave пользователь {user.remnawave_uuid} удален из панели") + else: + logger.warning(f"⚠️ Не удалось удалить пользователя {user.remnawave_uuid} из панели Remnawave") + except Exception as e: - logger.warning(f"⚠️ Ошибка деактивации RemnaWave: {e}") + logger.warning(f"⚠️ Ошибка удаления пользователя из Remnawave: {e}") + # Если не удалось удалить из панели, попытаемся хотя бы деактивировать + try: + from app.services.subscription_service import SubscriptionService + subscription_service = SubscriptionService() + await subscription_service.disable_remnawave_user(user.remnawave_uuid) + logger.info(f"✅ RemnaWave пользователь {user.remnawave_uuid} деактивирован как fallback") + except Exception as fallback_e: + logger.error(f"❌ Ошибка деактивации RemnaWave как fallback: {fallback_e}") try: sent_notifications_result = await db.execute( From e8c458f2c4ae83e0c214f9f57d23f06a9d7629f2 Mon Sep 17 00:00:00 2001 From: Legacyyy777 <162005411+Legacyyy777@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:25:37 +0500 Subject: [PATCH 4/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9=20=D0=BF=D0=B0=D1=80?= =?UTF-8?q?=D0=B0=D0=BC=D0=B5=D1=82=D1=80=20REMNAWAVE=5FUSER=5FDELETE=5FMO?= =?UTF-8?q?DE=20=D0=B2=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3=D1=83=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8E=20=D0=B8=20=D0=BE=D0=B1=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5=D1=81?= =?UTF-8?q?=D1=81=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5?= =?UTF-8?q?=D0=BB=D1=8F=20RemnaWave=20=D1=81=20=D1=83=D1=87=D0=B5=D1=82?= =?UTF-8?q?=D0=BE=D0=BC=20=D0=B2=D1=8B=D0=B1=D1=80=D0=B0=D0=BD=D0=BD=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=D0=B0=20=D1=83?= =?UTF-8?q?=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B8=D0=BB=D0=B8?= =?UTF-8?q?=20=D0=B4=D0=B5=D0=B0=D0=BA=D1=82=D0=B8=D0=B2=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8.=20=D0=9E=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=20=D0=B2=D0=B7=D0=B0=D0=B8=D0=BC=D0=BE=D0=B4=D0=B5=D0=B9?= =?UTF-8?q?=D1=81=D1=82=D0=B2=D0=B8=D0=B8=20=D1=81=20Remnawave.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/config.py | 6 ++++++ app/services/user_service.py | 41 +++++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/app/config.py b/app/config.py index 3884a425..0c434620 100644 --- a/app/config.py +++ b/app/config.py @@ -43,6 +43,7 @@ class Settings(BaseSettings): REMNAWAVE_PASSWORD: Optional[str] = None REMNAWAVE_AUTH_TYPE: str = "api_key" REMNAWAVE_USER_DESCRIPTION_TEMPLATE: str = "Bot user: {full_name} {username}" + REMNAWAVE_USER_DELETE_MODE: str = "delete" # "delete" или "disable" TRIAL_DURATION_DAYS: int = 3 TRIAL_TRAFFIC_LIMIT_GB: int = 10 @@ -259,6 +260,11 @@ class Settings(BaseSettings): "password": self.REMNAWAVE_PASSWORD, "auth_type": self.REMNAWAVE_AUTH_TYPE } + + def get_remnawave_user_delete_mode(self) -> str: + """Возвращает режим удаления пользователей: 'delete' или 'disable'""" + mode = self.REMNAWAVE_USER_DELETE_MODE.lower().strip() + return mode if mode in ["delete", "disable"] else "delete" def format_remnawave_user_description( self, diff --git a/app/services/user_service.py b/app/services/user_service.py index a7888488..0c65fde0 100644 --- a/app/services/user_service.py +++ b/app/services/user_service.py @@ -239,28 +239,39 @@ class UserService: logger.info(f"🗑️ Начинаем полное удаление пользователя {user_id} (Telegram ID: {user.telegram_id})") if user.remnawave_uuid: + from app.config import settings + delete_mode = settings.get_remnawave_user_delete_mode() + try: from app.services.remnawave_service import RemnaWaveService remnawave_service = RemnaWaveService() - # Сначала попытаемся удалить пользователя из панели Remnawave - async with remnawave_service.api as api: - delete_success = await api.delete_user(user.remnawave_uuid) - if delete_success: - logger.info(f"✅ RemnaWave пользователь {user.remnawave_uuid} удален из панели") - else: - logger.warning(f"⚠️ Не удалось удалить пользователя {user.remnawave_uuid} из панели Remnawave") - - except Exception as e: - logger.warning(f"⚠️ Ошибка удаления пользователя из Remnawave: {e}") - # Если не удалось удалить из панели, попытаемся хотя бы деактивировать - try: + if delete_mode == "delete": + # Удаляем пользователя из панели Remnawave + async with remnawave_service.api as api: + delete_success = await api.delete_user(user.remnawave_uuid) + if delete_success: + logger.info(f"✅ RemnaWave пользователь {user.remnawave_uuid} удален из панели") + else: + logger.warning(f"⚠️ Не удалось удалить пользователя {user.remnawave_uuid} из панели Remnawave") + else: + # Деактивируем пользователя в панели Remnawave from app.services.subscription_service import SubscriptionService subscription_service = SubscriptionService() await subscription_service.disable_remnawave_user(user.remnawave_uuid) - logger.info(f"✅ RemnaWave пользователь {user.remnawave_uuid} деактивирован как fallback") - except Exception as fallback_e: - logger.error(f"❌ Ошибка деактивации RemnaWave как fallback: {fallback_e}") + logger.info(f"✅ RemnaWave пользователь {user.remnawave_uuid} деактивирован (режим: {delete_mode})") + + except Exception as e: + logger.warning(f"⚠️ Ошибка обработки пользователя в Remnawave (режим: {delete_mode}): {e}") + # Если основное действие не удалось, попытаемся хотя бы деактивировать + if delete_mode == "delete": + try: + from app.services.subscription_service import SubscriptionService + subscription_service = SubscriptionService() + await subscription_service.disable_remnawave_user(user.remnawave_uuid) + logger.info(f"✅ RemnaWave пользователь {user.remnawave_uuid} деактивирован как fallback") + except Exception as fallback_e: + logger.error(f"❌ Ошибка деактивации RemnaWave как fallback: {fallback_e}") try: sent_notifications_result = await db.execute( From d0b3bbd488f56c817c312b116720f9f5a24601a7 Mon Sep 17 00:00:00 2001 From: Legacyyy777 <162005411+Legacyyy777@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:29:22 +0500 Subject: [PATCH 5/6] Update .env.example --- .env.example | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.env.example b/.env.example index 49d40597..28c25f2f 100644 --- a/.env.example +++ b/.env.example @@ -59,6 +59,11 @@ REMNAWAVE_SECRET_KEY= # {telegram_id} — ID Telegram REMNAWAVE_USER_DESCRIPTION_TEMPLATE="Bot user: {full_name} {username}" +# Режим удаления пользователей из панели RemnaWave +# delete - полностью удалить пользователя из панели +# disable - только деактивировать пользователя +REMNAWAVE_USER_DELETE_MODE=delete + # ========= ПОДПИСКИ ========= # ===== ТРИАЛ ПОДПИСКА ===== TRIAL_DURATION_DAYS=3 From d8d01384b12bd4e30af3f1890087630ed0e9bbc6 Mon Sep 17 00:00:00 2001 From: Egor Date: Wed, 17 Sep 2025 13:44:22 +0300 Subject: [PATCH 6/6] Delete .github/workflows/deploy.yml --- .github/workflows/deploy.yml | 37 ------------------------------------ 1 file changed, 37 deletions(-) delete mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 2e158c49..00000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Deploy Bot - -on: - push: - branches: - - DEV # деплой только при пуше в DEV - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Deploy to VPS - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.VPS_HOST }} - username: ${{ secrets.VPS_USER }} - key: ${{ secrets.VPS_SSH_KEY }} - script: | - # если папки ещё нет — клонируем - if [ ! -d /opt/mybot/.git ]; then - rm -rf /opt/mybot - git clone https://github.com/Legacyyy777/remnawave-bedolaga-telegram-bot_777.git /opt/mybot - fi - - cd /opt/mybot - - # обновляем и переключаемся на DEV - git fetch origin - git checkout DEV - git reset --hard origin/DEV - - # пересобираем и запускаем контейнер - docker compose build --no-cache - docker compose up -d --force-recreate