From 5453efadb531bbb17e1600e4769c93bf828e59f0 Mon Sep 17 00:00:00 2001 From: Legacyyy777 <162005411+Legacyyy777@users.noreply.github.com> Date: Wed, 17 Sep 2025 16:07:56 +0500 Subject: [PATCH 1/3] =?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=B0=D0=B2=D1=82=D0=BE=D0=BC=D0=B0=D1=82=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D1=81=D0=BA=D0=BE=D0=B3=D0=BE=20=D0=B4=D0=B5=D0=BF=D0=BB?= =?UTF-8?q?=D0=BE=D1=8F=20=D0=B1=D0=BE=D1=82=D0=B0=20=D0=BD=D0=B0=20VPS=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=20=D0=BF=D1=83=D1=88=D0=B5=20=D0=B2=20=D0=B2?= =?UTF-8?q?=D0=B5=D1=82=D0=BA=D1=83=20DEV.?= 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 d29ad223a75c3dc260dc0f6b9644aa478a410fe4 Mon Sep 17 00:00:00 2001 From: Legacyyy777 <162005411+Legacyyy777@users.noreply.github.com> Date: Wed, 17 Sep 2025 19:22:43 +0500 Subject: [PATCH 2/3] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D1=83=D0=B2=D0=B5=D0=B4=D0=BE=D0=BC=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D1=82=D0=B5=D0=BB=D1=8E=20=D0=BE=20=D0=BF=D0=BE=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8/=D1=81=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B8=D0=B8=20=D0=B1=D0=B0=D0=BB=D0=B0=D0=BD?= =?UTF-8?q?=D1=81=D0=B0.=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B0=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B9=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20Telegram-=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=20=D1=81=20=D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B5=D0=B9=20=D0=BE=20=D1=82=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=B7=D0=B0=D0=BA=D1=86=D0=B8=D0=B8=20=D0=B8=20=D0=B0?= =?UTF-8?q?=D0=B4=D0=BC=D0=B8=D0=BD=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B5,=20=D0=B2=D1=8B=D0=BF=D0=BE=D0=BB=D0=BD?= =?UTF-8?q?=D0=B8=D0=B2=D1=88=D0=B5=D0=BC=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8E.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/handlers/admin/users.py | 3 +- app/services/user_service.py | 80 ++++++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/app/handlers/admin/users.py b/app/handlers/admin/users.py index d0e858e4..9b7a9c2a 100644 --- a/app/handlers/admin/users.py +++ b/app/handlers/admin/users.py @@ -685,7 +685,8 @@ async def process_balance_edit( description = f"Списание администратором: {int(amount_rubles)} ₽" success = await user_service.update_user_balance( - db, user_id, amount_kopeks, description, db_user.id + db, user_id, amount_kopeks, description, db_user.id, + bot=message.bot, admin_name=db_user.full_name ) if success: diff --git a/app/services/user_service.py b/app/services/user_service.py index 0c65fde0..f26e14b2 100644 --- a/app/services/user_service.py +++ b/app/services/user_service.py @@ -3,6 +3,8 @@ from datetime import datetime, timedelta from typing import Optional, List, Dict, Any from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import delete, select, update +from aiogram import Bot +from aiogram.exceptions import TelegramBadRequest, TelegramForbiddenError from app.database.crud.user import ( get_user_by_id, get_user_by_telegram_id, get_users_list, get_users_count, get_users_statistics, get_inactive_users, @@ -23,6 +25,59 @@ logger = logging.getLogger(__name__) class UserService: + async def _send_balance_notification( + self, + bot: Bot, + user: User, + amount_kopeks: int, + admin_name: str + ) -> bool: + """Отправляет уведомление пользователю о пополнении/списании баланса""" + try: + if amount_kopeks > 0: + # Пополнение + emoji = "💰" + action = "пополнен" + amount_text = f"+{settings.format_price(amount_kopeks)}" + message = ( + f"{emoji} Баланс пополнен!\n\n" + f"💵 Сумма: {amount_text}\n" + f"👤 Администратор: {admin_name}\n" + f"💳 Текущий баланс: {settings.format_price(user.balance_kopeks)}\n\n" + f"Спасибо за использование нашего сервиса! 🎉" + ) + else: + # Списание + emoji = "💸" + action = "списан" + amount_text = f"-{settings.format_price(abs(amount_kopeks))}" + message = ( + f"{emoji} Средства списаны с баланса\n\n" + f"💵 Сумма: {amount_text}\n" + f"👤 Администратор: {admin_name}\n" + f"💳 Текущий баланс: {settings.format_price(user.balance_kopeks)}\n\n" + f"Если у вас есть вопросы, обратитесь в поддержку." + ) + + await bot.send_message( + chat_id=user.telegram_id, + text=message, + parse_mode="HTML" + ) + + logger.info(f"✅ Уведомление о изменении баланса отправлено пользователю {user.telegram_id}") + return True + + except TelegramForbiddenError: + logger.warning(f"⚠️ Пользователь {user.telegram_id} заблокировал бота") + return False + except TelegramBadRequest as e: + logger.error(f"❌ Ошибка Telegram API при отправке уведомления пользователю {user.telegram_id}: {e}") + return False + except Exception as e: + logger.error(f"❌ Неожиданная ошибка при отправке уведомления пользователю {user.telegram_id}: {e}") + return False + async def get_user_profile( self, db: AsyncSession, @@ -128,22 +183,41 @@ class UserService: user_id: int, amount_kopeks: int, description: str, - admin_id: int + admin_id: int, + bot: Optional[Bot] = None, + admin_name: Optional[str] = None ) -> bool: try: user = await get_user_by_id(db, user_id) if not user: return False + # Сохраняем старый баланс для уведомления + old_balance = user.balance_kopeks + if amount_kopeks > 0: await add_user_balance(db, user, amount_kopeks, description=description) logger.info(f"Админ {admin_id} пополнил баланс пользователя {user_id} на {amount_kopeks/100}₽") - return True + success = True else: success = await subtract_user_balance(db, user, abs(amount_kopeks), description) if success: logger.info(f"Админ {admin_id} списал с баланса пользователя {user_id} {abs(amount_kopeks)/100}₽") - return success + + # Отправляем уведомление пользователю, если операция прошла успешно + if success and bot: + # Обновляем пользователя для получения нового баланса + await db.refresh(user) + + # Получаем имя администратора + if not admin_name: + admin_user = await get_user_by_id(db, admin_id) + admin_name = admin_user.full_name if admin_user else f"Админ #{admin_id}" + + # Отправляем уведомление (не блокируем операцию если не удалось отправить) + await self._send_balance_notification(bot, user, amount_kopeks, admin_name) + + return success except Exception as e: logger.error(f"Ошибка изменения баланса пользователя: {e}") From 5e94b287b90754bf069b8892152e8b4f8f1b9843 Mon Sep 17 00:00:00 2001 From: Egor Date: Thu, 18 Sep 2025 03:08:50 +0300 Subject: [PATCH 3/3] 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