From fe84289def63236b02f7223b8476053d58699970 Mon Sep 17 00:00:00 2001 From: doryan Date: Fri, 11 Apr 2025 12:10:21 +0400 Subject: [PATCH] feat(executer): add command executor, needs to fix some bugs --- src/handlers/commands/admin_commands.rs | 111 +++++++++++++++++++++--- 1 file changed, 98 insertions(+), 13 deletions(-) diff --git a/src/handlers/commands/admin_commands.rs b/src/handlers/commands/admin_commands.rs index da95f13..893f699 100644 --- a/src/handlers/commands/admin_commands.rs +++ b/src/handlers/commands/admin_commands.rs @@ -1,21 +1,29 @@ -use std::ops::Deref; +use std::{future::Future, ops::Deref, pin::Pin}; use telers::{ - event::{telegram::HandlerResult, EventReturn}, - filters::CommandObject, - types::Message, + errors::HandlerError, + event::{service::BoxFuture, telegram::HandlerResult, EventReturn}, + filters::{chat_type, CommandObject}, + methods::{BanChatMember, RestrictChatMember, SendMessage, UnbanChatMember}, + types::{ChatPermissions, Message}, Bot, }; use crate::{ assets::files::{BAN_COMMAND_HELP, MUTE_COMMAND_HELP, UNBAN_COMMAND_HELP, UNMUTE_COMMAND_HELP}, - utils::telegram::{args_parser::parse_args, senders::send_html}, + types::enums::{target_user::TargetUser, time_metrics::TimeDuration}, + utils::{ + general::get_expiration_time::get_expiration_date, + telegram::{ + args_parser::{parse_args, Argument}, + member_rights::{demote_user, restrict}, + senders::send_html, + }, + }, }; -#[allow(unused)] const USER_ID_NOT_FOUND: &str = "Для выполнение команды нужно знать ID пользователя, или ввести команду и выполнить её, ответив на сообщение пользователя"; -#[allow(unused)] -const COMMAND_EXECUTION_REJECTED: &str = "Выполнение данной команды невозможно, поскольку пользователю были выданы права администратора модераторами или основателем"; +const DEMOTE_ERROR: &str = "Невозможно снять привелегий администратора в силу того, что права были выданы одним из администраторов или основателем"; pub async fn admin_commands_endpoint( bot: Bot, @@ -24,11 +32,52 @@ pub async fn admin_commands_endpoint( ) -> HandlerResult { let (command_type, args) = (command_object.command.deref(), command_object.args.deref()); - let chat_id = message.chat().id(); - - if let Some(_args) = parse_args(args, &message, command_type) { + if let Some(args) = parse_args(args, &message, command_type) { match command_type { - "ban" | "unban" | "mute" | "unmute" => todo!(), + "ban" => { + let ban_callback = async |chat_id: i64, user_id: i64| { + bot.send(BanChatMember::new(chat_id, user_id)).await?; + Ok(EventReturn::Finish) + }; + + execute_command(&bot, &message, ban_callback, args).await?; + } + "unban" => { + let unban_callback = async |chat_id: i64, user_id: i64| { + bot.send(UnbanChatMember::new(chat_id, user_id)).await?; + Ok(EventReturn::Finish) + }; + execute_command(&bot, &message, unban_callback, args).await?; + } + "mute" => { + let duration = if let Some(Argument::Time(duration)) = args.get(1) { + get_expiration_date(*duration) + } else { + bot.send(SendMessage::new( + message.chat().id(), + "Не указана длительность мута.", + )) + .await?; + return Err(HandlerError::from_display("Mute duration is not defined")); + }; + let mute_callback = async |chat_id: i64, user_id: i64| { + restrict(&bot, user_id, duration, chat_id).await?; + Ok(EventReturn::Finish) + }; + execute_command(&bot, &message, mute_callback, args).await?; + } + "unmute" => { + let unmute_callback = async |chat_id: i64, user_id: i64| { + bot.send(RestrictChatMember::new( + chat_id, + user_id, + ChatPermissions::new(), + )) + .await?; + Ok(EventReturn::Finish) + }; + execute_command(&bot, &message, unmute_callback, args).await?; + } _ => unreachable!(), }; } else { @@ -40,7 +89,43 @@ pub async fn admin_commands_endpoint( _ => unreachable!(), }; - send_html(&bot, chat_id, help_txt).await?; + send_html(&bot, &message, help_txt).await?; } Ok(EventReturn::Finish) } + +pub async fn execute_command( + bot: &Bot, + message: &Message, + command: impl AsyncFnOnce(i64, i64) -> HandlerResult + Copy, + command_args: Vec, +) -> HandlerResult { + let chat_id = message.chat().id(); + + if let Some(Argument::User(user)) = command_args.first() { + if let TargetUser::None = user { + bot.send(SendMessage::new(chat_id, USER_ID_NOT_FOUND)) + .await?; + return Err(HandlerError::from_display("Can't find user ID")); + } + + let (user_name, user_id) = ( + user.get_user_name(bot, message).await.unwrap(), + user.get_id().unwrap(), + ); + + if command(user_id, chat_id).await.is_err() { + if demote_user(bot, user_id, chat_id).await.is_err() { + bot.send(SendMessage::new(chat_id, DEMOTE_ERROR)).await?; + return Err(HandlerError::from_display("Can't demote chat member because he has permission that he got from another admin/chat owner")); + } + command(user_id, chat_id).await?; + } else { + bot.send(SendMessage::new(chat_id, "Command executed successful!")) + .await?; + } + Ok(EventReturn::Finish) + } else { + unreachable!() + } +}