add mailing function
This commit is contained in:
@@ -11,6 +11,9 @@
|
|||||||
- [ ] Удалять мероприятия
|
- [ ] Удалять мероприятия
|
||||||
- [x] Просматривать список существующих мероприятий
|
- [x] Просматривать список существующих мероприятий
|
||||||
- [ ] Просматривать людей записавшихся на мероприятие
|
- [ ] Просматривать людей записавшихся на мероприятие
|
||||||
|
- [x] Делать рассылку по пользователям
|
||||||
|
- [x] Исключать из рассылки администраторов
|
||||||
|
- [ ] Указать дату и время рассылки
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from aiogram import Router
|
from aiogram import Router
|
||||||
|
|
||||||
from .events.dialogs import events_dialog
|
from .events.dialogs import events_dialog
|
||||||
|
from .mailing.dialogs import mailing_dialog
|
||||||
from .new_event.dialogs import new_event_dialog
|
from .new_event.dialogs import new_event_dialog
|
||||||
from .profile.dialogs import profile_dialog
|
from .profile.dialogs import profile_dialog
|
||||||
from .start.dialogs import start_dialog
|
from .start.dialogs import start_dialog
|
||||||
@@ -10,3 +11,4 @@ dialogs_router.include_router(start_dialog)
|
|||||||
dialogs_router.include_router(events_dialog)
|
dialogs_router.include_router(events_dialog)
|
||||||
dialogs_router.include_router(profile_dialog)
|
dialogs_router.include_router(profile_dialog)
|
||||||
dialogs_router.include_router(new_event_dialog)
|
dialogs_router.include_router(new_event_dialog)
|
||||||
|
dialogs_router.include_router(mailing_dialog)
|
||||||
|
|||||||
43
app/bot/dialogs/flows/mailing/dialogs.py
Normal file
43
app/bot/dialogs/flows/mailing/dialogs.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
from aiogram_dialog import Dialog, Window
|
||||||
|
from aiogram_dialog.widgets.input import MessageInput
|
||||||
|
from aiogram_dialog.widgets.kbd import Back, Button, Cancel
|
||||||
|
from aiogram_dialog.widgets.text import Const
|
||||||
|
|
||||||
|
# from .getters import event_getter, events_list_getter, registration_getter
|
||||||
|
from .handlers import choose_recipients, confirm_mailing, message_data
|
||||||
|
from .states import MailingSG
|
||||||
|
|
||||||
|
mailing_dialog = Dialog(
|
||||||
|
Window(
|
||||||
|
Const("Пришлите сообщение которое хотите разослать"),
|
||||||
|
MessageInput(message_data),
|
||||||
|
Cancel(Const("Отмена")),
|
||||||
|
state=MailingSG.message_data,
|
||||||
|
),
|
||||||
|
Window(
|
||||||
|
Const("Кому отправить сообщение?"),
|
||||||
|
Button(
|
||||||
|
Const("Всем"),
|
||||||
|
id="send_all",
|
||||||
|
on_click=choose_recipients,
|
||||||
|
),
|
||||||
|
Button(
|
||||||
|
Const("Не админам"),
|
||||||
|
id="send_users",
|
||||||
|
on_click=choose_recipients,
|
||||||
|
),
|
||||||
|
Back(Const("Назад")),
|
||||||
|
state=MailingSG.recipients,
|
||||||
|
),
|
||||||
|
Window(
|
||||||
|
Const("Начать рассылку?"),
|
||||||
|
Button(
|
||||||
|
Const("Разослать"),
|
||||||
|
id="start_mailing",
|
||||||
|
on_click=confirm_mailing,
|
||||||
|
),
|
||||||
|
Back(Const("Назад")),
|
||||||
|
Cancel(Const("Отмена")),
|
||||||
|
state=MailingSG.confirm,
|
||||||
|
),
|
||||||
|
)
|
||||||
54
app/bot/dialogs/flows/mailing/handlers.py
Normal file
54
app/bot/dialogs/flows/mailing/handlers.py
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
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 app.infrastructure.database.crud import get_users
|
||||||
|
|
||||||
|
|
||||||
|
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",
|
||||||
|
))
|
||||||
|
|
||||||
|
await asyncio.gather(
|
||||||
|
*[
|
||||||
|
callback.bot.copy_message(
|
||||||
|
chat_id=user.tg_id,
|
||||||
|
from_chat_id=manager.dialog_data["message"].chat.id,
|
||||||
|
message_id=manager.dialog_data["message"].message_id,
|
||||||
|
)
|
||||||
|
for user in users
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await callback.bot.send_message(
|
||||||
|
chat_id=callback.from_user.id,
|
||||||
|
text=f"Разослано сообщений: {len(users)}",
|
||||||
|
)
|
||||||
|
await manager.done()
|
||||||
8
app/bot/dialogs/flows/mailing/states.py
Normal file
8
app/bot/dialogs/flows/mailing/states.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
from aiogram.fsm.state import State, StatesGroup
|
||||||
|
|
||||||
|
|
||||||
|
class MailingSG(StatesGroup):
|
||||||
|
message_data = State()
|
||||||
|
recipients = State()
|
||||||
|
# mailing_date = State()
|
||||||
|
confirm = State()
|
||||||
@@ -3,6 +3,7 @@ from aiogram_dialog.widgets.kbd import Button, Start
|
|||||||
from aiogram_dialog.widgets.text import Const, Format
|
from aiogram_dialog.widgets.text import Const, Format
|
||||||
|
|
||||||
from app.bot.dialogs.flows.events.dialogs import EventsSG
|
from app.bot.dialogs.flows.events.dialogs import EventsSG
|
||||||
|
from app.bot.dialogs.flows.mailing.dialogs import MailingSG
|
||||||
from app.bot.dialogs.flows.new_event.dialogs import NewEventSG
|
from app.bot.dialogs.flows.new_event.dialogs import NewEventSG
|
||||||
from app.bot.dialogs.flows.profile.dialogs import ProfileSG
|
from app.bot.dialogs.flows.profile.dialogs import ProfileSG
|
||||||
from app.bot.dialogs.widgets.getters import is_admin_getter, user_getter
|
from app.bot.dialogs.widgets.getters import is_admin_getter, user_getter
|
||||||
@@ -19,6 +20,12 @@ start_dialog = Dialog(
|
|||||||
state=NewEventSG.input_title,
|
state=NewEventSG.input_title,
|
||||||
when="is_admin",
|
when="is_admin",
|
||||||
),
|
),
|
||||||
|
Start(
|
||||||
|
Const("📧 разослать сообщение"),
|
||||||
|
id="create_mailing",
|
||||||
|
state=MailingSG.message_data,
|
||||||
|
when="is_admin",
|
||||||
|
),
|
||||||
Start(Const("👤 профиль"), id="profile", state=ProfileSG.profile),
|
Start(Const("👤 профиль"), id="profile", state=ProfileSG.profile),
|
||||||
getter=[user_getter, is_admin_getter],
|
getter=[user_getter, is_admin_getter],
|
||||||
state=StartSG.start,
|
state=StartSG.start,
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ async def update_user(
|
|||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
async def get_users(session: AsyncSession, exclude_admins=False) -> list[User]:
|
||||||
|
query = select(User).where(User.role == "user") if exclude_admins else select(User)
|
||||||
|
return await session.scalars(query)
|
||||||
|
|
||||||
|
|
||||||
async def get_events_list(session: AsyncSession) -> list[Event]:
|
async def get_events_list(session: AsyncSession) -> list[Event]:
|
||||||
result = await session.execute(
|
result = await session.execute(
|
||||||
select(Event).where(Event.start_date >= datetime.now())
|
select(Event).where(Event.start_date >= datetime.now())
|
||||||
|
|||||||
Reference in New Issue
Block a user