from __future__ import annotations import asyncio import re from pyrogram import Client, filters from pyrogram.errors import FloodWait, InputUserDeactivated, PeerIdInvalid, UserIsBlocked from pyrogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message from utils import filters as myfilters from utils.client import MyClient from utils.db import Depends, User, get_user, get_user_query, inject from utils.i18n import tr as _ from utils.messages import message_handler NO_BROADCAST_PATTERN = re.compile(r"^send_user_msg\.no$") YES_BROADCAST_PATTERN = re.compile(r"^send_user_msg\.yes_(?P\d+)$") @Client.on_message(filters.reply & filters.command(["sm"]) & myfilters.is_admin) @inject async def send_message_main(client: MyClient, msg: Message, user: User = Depends(get_user)) -> None: if len(msg.command) == 1: await message_handler(msg.reply, _("cp.invalid_send_message_command", locale=user.language)) return user_id = msg.command[1] if not user_id.isdigit(): await message_handler(msg.reply, _("cp.invalid_send_message_command", locale=user.language)) return user_id = int(user_id) u = await User.find_one(User.user_id == user_id) if not u: await message_handler(msg.reply, _("cp.cannot_find_user", locale=user.language)) return await msg.reply_to_message.reply( _("cp.send_message_confirm", user_id=user_id, locale=user.language), quote=True, reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton( _("common.yes", locale=user.language), f"send_user_msg.yes_{user_id}" ), InlineKeyboardButton(_("common.no", locale=user.language), "send_user_msg.no"), ] ] ), ) await message_handler(msg.delete) @Client.on_callback_query(filters.regex(NO_BROADCAST_PATTERN)) async def broadcast_no(client: MyClient, query: CallbackQuery) -> None: await message_handler(query.message.delete) async def send_message(msg: Message, user_id: int) -> tuple[int, str | None]: try: await msg.copy(user_id) except FloodWait as e: await asyncio.sleep(e.x * 1.2) return send_message(user_id, msg) except InputUserDeactivated: return 400, None except UserIsBlocked: return 400, None except PeerIdInvalid: return 400, None except Exception as e: return 500, str(repr(e)) return 200, None @Client.on_callback_query(filters.regex(YES_BROADCAST_PATTERN)) @inject async def broadcast_yes( client: MyClient, query: CallbackQuery, user: User = Depends(get_user_query) ) -> None: msg_to_copy = query.message.reply_to_message user_id = int(query.matches[0].group("user_id")) res = await send_message(msg_to_copy, user_id) if res[0] != 200: # noqa: PLR2004 await message_handler( query.edit_message_text, _("cp.failed_to_send_message", locale=user.language) ) return await message_handler(query.edit_message_text, _("cp.message_sent", locale=user.language))