Edit on GitHub

src.scheduler.notices

Отправка уведомлений пользователям

  1"""Отправка уведомлений пользователям"""
  2
  3import logging
  4import os
  5from random import randint
  6
  7import aiofiles
  8from aiogram import Bot
  9from aiogram.exceptions import TelegramForbiddenError
 10from pytils.numeral import get_plural
 11
 12from core.err import log_cash_error
 13from core.path import PATH
 14from db.models import UserData
 15from db.utils import close_free_trial, get_admins
 16from db.utils.redis import CashManager
 17
 18logger = logging.getLogger("apscheduler")
 19logging.getLogger("apscheduler.executors.default").setLevel(logging.WARNING)
 20
 21queue = os.path.join(PATH, "logs", "queue.log")
 22
 23
 24async def send_notice(bot: Bot):
 25    """Отправляет уведомления пользователям и администраторам.
 26
 27    Эта функция читает уведомления из файла очереди и обрабатывает их.
 28    В зависимости от типа уведомления (TRANSACTION, REPORT или CODE) отправляет
 29    сообщения пользователю и администраторам. Также обрабатывает
 30    изменения статуса пробного тарифа.
 31
 32    Args:
 33        bot (Bot): Экземпляр бота для отправки сообщений.
 34
 35    Raises:
 36        TelegramForbiddenError: Если бот заблокирован пользователем.
 37        Exception: Если произошла ошибка при обработке уведомлений.
 38
 39    Notes:
 40        Уведомления, которые не удалось отправить, остаются в очереди для
 41        повторной отправки.
 42    """
 43    async with aiofiles.open(queue) as file:
 44        notices = (await file.read()).splitlines()
 45
 46    for notice in notices.copy():
 47        date, _type, user_id, label, amount, *extra = notice.strip("\n#|").split("||")
 48        try:
 49            match _type:
 50                case "TRANSACTION":
 51                    user_id = int(user_id)
 52                    admin_ids: list[UserData] = await get_admins()
 53
 54                    await bot.send_message(
 55                        user_id,
 56                        f"<b>УСПЕШНО!</b> Ваш баланс пополнен на {get_plural(float(amount), 'рубль, рубля, рублей')}!",
 57                    )
 58                    for admin in admin_ids:
 59                        await bot.send_message(
 60                            admin.telegram_id,
 61                            f"Казна пополнена на {get_plural(float(amount), 'рубль, рубля, рублей')} пользователем {user_id}!",
 62                        )
 63
 64                    user_data: UserData = await close_free_trial(user_id)
 65                    if user_data:
 66                        await bot.send_message(
 67                            user_id,
 68                            "Ваш <b>Пробный тариф</b> автоматически сменен на <b>Базовый</b>",
 69                        )
 70
 71                    logger.info(
 72                        "Отправлено сообщение об успешной оплате",
 73                        extra={"user_id": user_id},
 74                    )
 75
 76                case "REPORT":
 77                    if amount and amount != "None":
 78                        await bot.send_message(
 79                            user_id,
 80                            f"Вашему обращению присвоен новый статус: <b>{amount}</b>. Номер обращения: {label}",
 81                        )
 82                    else:
 83                        admin_ids: list[UserData] = await get_admins()
 84
 85                        for admin in admin_ids:
 86                            await bot.send_message(
 87                                admin.telegram_id,
 88                                f"Поступило обращение от пользователя {user_id}. Номер обращения: {label}",
 89                            )
 90                case "CODE":
 91                    user_id = int(user_id)
 92
 93                    auth_code = randint(100_000, 999_999)
 94
 95                    await CashManager(UserData).add(
 96                        {f"authcode:{user_id}": {"code": auth_code}}
 97                    )
 98
 99                    await bot.send_message(
100                        user_id,
101                        f'Ваш код для авторизации\n\n<span class="tg-spoiler">{auth_code}</span>',
102                    )
103
104                    logger.info("Отправлен код авторизации", extra={"user_id": user_id})
105
106        except TelegramForbiddenError as e:
107            if log_cash_error(e):
108                logger.debug("Бот заблокирован пользователем. Уведомление отложено.")
109            return
110        except Exception as e:
111            if log_cash_error(e):
112                logger.exception("Ошибка планировщика событий")
113            return
114        else:
115            notices.pop(notice.index(notice))
116
117    async with aiofiles.open(queue, "w") as file:
118        await file.write("\n".join(notices))
logger = <Logger apscheduler (INFO)>
queue = '/home/bot/vpn_dan_bot/logs/queue.log'
async def send_notice(bot: aiogram.client.bot.Bot):
 25async def send_notice(bot: Bot):
 26    """Отправляет уведомления пользователям и администраторам.
 27
 28    Эта функция читает уведомления из файла очереди и обрабатывает их.
 29    В зависимости от типа уведомления (TRANSACTION, REPORT или CODE) отправляет
 30    сообщения пользователю и администраторам. Также обрабатывает
 31    изменения статуса пробного тарифа.
 32
 33    Args:
 34        bot (Bot): Экземпляр бота для отправки сообщений.
 35
 36    Raises:
 37        TelegramForbiddenError: Если бот заблокирован пользователем.
 38        Exception: Если произошла ошибка при обработке уведомлений.
 39
 40    Notes:
 41        Уведомления, которые не удалось отправить, остаются в очереди для
 42        повторной отправки.
 43    """
 44    async with aiofiles.open(queue) as file:
 45        notices = (await file.read()).splitlines()
 46
 47    for notice in notices.copy():
 48        date, _type, user_id, label, amount, *extra = notice.strip("\n#|").split("||")
 49        try:
 50            match _type:
 51                case "TRANSACTION":
 52                    user_id = int(user_id)
 53                    admin_ids: list[UserData] = await get_admins()
 54
 55                    await bot.send_message(
 56                        user_id,
 57                        f"<b>УСПЕШНО!</b> Ваш баланс пополнен на {get_plural(float(amount), 'рубль, рубля, рублей')}!",
 58                    )
 59                    for admin in admin_ids:
 60                        await bot.send_message(
 61                            admin.telegram_id,
 62                            f"Казна пополнена на {get_plural(float(amount), 'рубль, рубля, рублей')} пользователем {user_id}!",
 63                        )
 64
 65                    user_data: UserData = await close_free_trial(user_id)
 66                    if user_data:
 67                        await bot.send_message(
 68                            user_id,
 69                            "Ваш <b>Пробный тариф</b> автоматически сменен на <b>Базовый</b>",
 70                        )
 71
 72                    logger.info(
 73                        "Отправлено сообщение об успешной оплате",
 74                        extra={"user_id": user_id},
 75                    )
 76
 77                case "REPORT":
 78                    if amount and amount != "None":
 79                        await bot.send_message(
 80                            user_id,
 81                            f"Вашему обращению присвоен новый статус: <b>{amount}</b>. Номер обращения: {label}",
 82                        )
 83                    else:
 84                        admin_ids: list[UserData] = await get_admins()
 85
 86                        for admin in admin_ids:
 87                            await bot.send_message(
 88                                admin.telegram_id,
 89                                f"Поступило обращение от пользователя {user_id}. Номер обращения: {label}",
 90                            )
 91                case "CODE":
 92                    user_id = int(user_id)
 93
 94                    auth_code = randint(100_000, 999_999)
 95
 96                    await CashManager(UserData).add(
 97                        {f"authcode:{user_id}": {"code": auth_code}}
 98                    )
 99
100                    await bot.send_message(
101                        user_id,
102                        f'Ваш код для авторизации\n\n<span class="tg-spoiler">{auth_code}</span>',
103                    )
104
105                    logger.info("Отправлен код авторизации", extra={"user_id": user_id})
106
107        except TelegramForbiddenError as e:
108            if log_cash_error(e):
109                logger.debug("Бот заблокирован пользователем. Уведомление отложено.")
110            return
111        except Exception as e:
112            if log_cash_error(e):
113                logger.exception("Ошибка планировщика событий")
114            return
115        else:
116            notices.pop(notice.index(notice))
117
118    async with aiofiles.open(queue, "w") as file:
119        await file.write("\n".join(notices))

Отправляет уведомления пользователям и администраторам.

Эта функция читает уведомления из файла очереди и обрабатывает их. В зависимости от типа уведомления (TRANSACTION, REPORT или CODE) отправляет сообщения пользователю и администраторам. Также обрабатывает изменения статуса пробного тарифа.

Arguments:
  • bot (Bot): Экземпляр бота для отправки сообщений.
Raises:
  • TelegramForbiddenError: Если бот заблокирован пользователем.
  • Exception: Если произошла ошибка при обработке уведомлений.
Notes:

Уведомления, которые не удалось отправить, остаются в очереди для повторной отправки.