admin: add /broadcast command for sending news

parent 789d6443
......@@ -4,3 +4,20 @@ set_rule_kb = (
InlineKeyboard()
.add(InlineButton("Продолжить", callback_data="command/menu"))
).get_markup()
broadcast_cancel_kb = (
InlineKeyboard()
.add(InlineButton("Отмена", callback_data="broadcast/cancel"))
).get_markup()
def broadcast_confirm_kb(from_chat_id: int, message_id: int):
return (
InlineKeyboard()
.add(InlineButton(
"Отправить всем",
callback_data=f"broadcast/confirm/{from_chat_id}/{message_id}",
))
.row()
.add(InlineButton("Отмена", callback_data="broadcast/cancel"))
).get_markup()
from telegrinder import Dispatch, Message
from telegrinder.rules import Command, Argument
import asyncio
from telegrinder import Dispatch, Message, CallbackQuery, WaiterMachine, MESSAGE_FROM_USER
from telegrinder.rules import Command, Argument, CallbackDataMarkup
from data.keyboards import admin_keyboards
from database.func import DB
from rules import BotAdmin
from config import tg_api
from config import tg_api, config
dp = Dispatch()
dp.message.auto_rules = BotAdmin()
wm = WaiterMachine(dp)
def _get_admin_ids() -> set[int]:
admin_ids = set(config.admins)
for user in DB.user.get_all():
if "admin" in DB.user.get_roles(user.user_id):
admin_ids.add(user.user_id)
return admin_ids
@dp.message(Command("altrepo_users"))
......@@ -102,3 +113,66 @@ async def alrtrepo_users(m: Message, user_id: int, role: str):
text=f"C вас была снята роль {role}",
reply_markup=admin_keyboards.set_rule_kb,
)
@dp.message(Command("broadcast"))
async def broadcast_handler(m: Message) -> None:
await m.answer("Отправьте сообщение для рассылки:", reply_markup=admin_keyboards.broadcast_cancel_kb)
try:
msg, _ = await wm.wait(MESSAGE_FROM_USER, m.from_user.id)
except (asyncio.CancelledError, LookupError):
return
from_chat_id = msg.chat.id
message_id = msg.message_id
for admin_id in _get_admin_ids():
try:
await tg_api.copy_message(
chat_id=admin_id,
from_chat_id=from_chat_id,
message_id=message_id,
)
except Exception:
pass
await m.answer(
"Превью отправлено админам.",
reply_markup=admin_keyboards.broadcast_confirm_kb(from_chat_id, message_id),
)
@dp.callback_query(CallbackDataMarkup("broadcast/confirm/<from_chat_id:int>/<message_id:int>"))
async def broadcast_confirm_handler(
cb: CallbackQuery, from_chat_id: int, message_id: int,
) -> None:
users = DB.user.get_all()
admin_ids = _get_admin_ids()
sent = len(admin_ids)
for user in users:
if user.user_id in admin_ids:
continue
try:
await tg_api.copy_message(
chat_id=user.user_id,
from_chat_id=from_chat_id,
message_id=message_id,
)
sent += 1
except Exception:
pass
await cb.edit_text(f"Рассылка отправлена: {sent} из {len(users)}")
await cb.answer()
@dp.callback_query(CallbackDataMarkup("broadcast/cancel"))
async def broadcast_cancel_handler(cb: CallbackQuery) -> None:
try:
await wm.drop(MESSAGE_FROM_USER, cb.from_user.id)
except LookupError:
pass
await cb.edit_text("Рассылка отменена.")
await cb.answer()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment