Files
FascioSchoolBot/app/bot/dialogs/flows/mailing/handlers.py
2025-11-14 14:42:25 +03:00

77 lines
2.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import asyncio
from aiogram.types import CallbackQuery, Message
from aiogram_dialog import DialogManager
from aiogram_dialog.widgets.input import MessageInput
from aiogram_dialog.widgets.kbd import Button
from structlog import get_logger
from app.infrastructure.database.crud import get_users
logger = get_logger()
async def message_data(
message: Message,
widget: MessageInput,
manager: DialogManager,
):
manager.dialog_data["message"] = message
await manager.next()
async def choose_recipients(
callback: CallbackQuery,
button: Button,
manager: DialogManager,
):
manager.dialog_data["recipients"] = button.widget_id
await manager.next()
async def confirm_mailing(
callback: CallbackQuery,
button: Button,
manager: DialogManager,
):
print(manager.dialog_data["recipients"])
users = list(await get_users(
manager.middleware_data["session"],
exclude_admins=manager.dialog_data["recipients"] == "send_users",
))
message = manager.dialog_data["message"]
source_chat_id = message.chat.id
source_message_id = message.message_id
success_count = 0
# Создаём задачу с обработкой ошибок для каждого пользователя
async def send_to_user(user):
nonlocal success_count
try:
await callback.bot.copy_message(
chat_id=user.tg_id,
from_chat_id=source_chat_id,
message_id=source_message_id,
)
success_count += 1
except Exception as e:
logger.warning(
"не удалось отправить сообщение",
user_id=user.tg_id,
error=str(e),
exc_info=True, # добавит traceback
)
pass
await asyncio.gather(*[send_to_user(user) for user in users])
await callback.bot.send_message(
chat_id=callback.from_user.id,
text=f"Рассылка завершена.\nУспешно отправлено: {success_count} из {len(users)}",
)
await manager.done()