Compare commits

...

5 Commits
main ... dev

6 changed files with 121 additions and 57 deletions

View File

@ -1,21 +1,29 @@
use std::ops::Deref; use std::{future::Future, ops::Deref, pin::Pin};
use telers::{ use telers::{
event::{telegram::HandlerResult, EventReturn}, errors::HandlerError,
filters::CommandObject, event::{service::BoxFuture, telegram::HandlerResult, EventReturn},
types::Message, filters::{chat_type, CommandObject},
methods::{BanChatMember, RestrictChatMember, SendMessage, UnbanChatMember},
types::{ChatPermissions, Message},
Bot, Bot,
}; };
use crate::{ use crate::{
assets::files::{BAN_COMMAND_HELP, MUTE_COMMAND_HELP, UNBAN_COMMAND_HELP, UNMUTE_COMMAND_HELP}, 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 пользователя, или ввести команду и выполнить её, ответив на сообщение пользователя"; const USER_ID_NOT_FOUND: &str = "Для выполнение команды нужно знать ID пользователя, или ввести команду и выполнить её, ответив на сообщение пользователя";
#[allow(unused)] const DEMOTE_ERROR: &str = "Невозможно снять привелегий администратора в силу того, что права были выданы одним из администраторов или основателем";
const COMMAND_EXECUTION_REJECTED: &str = "Выполнение данной команды невозможно, поскольку пользователю были выданы права администратора модераторами или основателем";
pub async fn admin_commands_endpoint( pub async fn admin_commands_endpoint(
bot: Bot, bot: Bot,
@ -24,11 +32,52 @@ pub async fn admin_commands_endpoint(
) -> HandlerResult { ) -> HandlerResult {
let (command_type, args) = (command_object.command.deref(), command_object.args.deref()); 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 { 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!(), _ => unreachable!(),
}; };
} else { } else {
@ -40,7 +89,43 @@ pub async fn admin_commands_endpoint(
_ => unreachable!(), _ => unreachable!(),
}; };
send_html(&bot, chat_id, help_txt).await?; send_html(&bot, &message, help_txt).await?;
} }
Ok(EventReturn::Finish) Ok(EventReturn::Finish)
} }
pub async fn execute_command(
bot: &Bot,
message: &Message,
command: impl AsyncFnOnce(i64, i64) -> HandlerResult + Copy,
command_args: Vec<Argument>,
) -> 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!()
}
}

View File

@ -18,10 +18,9 @@ pub async fn info_commands_endpoint(
message: Message, message: Message,
command_object: CommandObject, command_object: CommandObject,
) -> HandlerResult { ) -> HandlerResult {
let chat_id = message.chat().id();
match command_object.command.deref() { match command_object.command.deref() {
"help" => send_html(&bot, chat_id, HELP_COMMAND_TEXT).await, "help" => send_html(&bot, &message, HELP_COMMAND_TEXT).await,
"privacy" => send_html(&bot, chat_id, PRIVACY_COMMAND_TEXT).await, "privacy" => send_html(&bot, &message, PRIVACY_COMMAND_TEXT).await,
_ => Ok(EventReturn::Cancel), _ => Ok(EventReturn::Cancel),
} }
} }

View File

@ -1,6 +1,9 @@
use std::ops::Deref;
use telers::{ use telers::{
errors::SessionErrorKind, errors::SessionErrorKind,
methods::GetChatMember, methods::GetChatMember,
types::User,
types::{ChatMember, Message}, types::{ChatMember, Message},
Bot, Bot,
}; };
@ -53,6 +56,14 @@ impl TargetUser {
} }
} }
fn _inner_get_user_name(&self, user: User) -> Option<Box<str>> {
if let Some(user_name) = user.username.as_ref() {
return Some(user_name.clone());
} else {
return Some(Box::from(user.full_name()));
}
}
pub async fn get_user_name(&self, bot: &Bot, msg: &Message) -> Option<Box<str>> { pub async fn get_user_name(&self, bot: &Bot, msg: &Message) -> Option<Box<str>> {
match self { match self {
Self::Id(id) => { Self::Id(id) => {
@ -60,13 +71,13 @@ impl TargetUser {
bot.send(GetChatMember::new(msg.chat().id(), *id)).await; bot.send(GetChatMember::new(msg.chat().id(), *id)).await;
if let Ok(member_kind) = get_chat_member_result { if let Ok(member_kind) = get_chat_member_result {
return match member_kind { match member_kind {
ChatMember::Owner(member) => member.user.username, ChatMember::Owner(member) => self._inner_get_user_name(member.user),
ChatMember::Administrator(member) => member.user.username, ChatMember::Administrator(member) => self._inner_get_user_name(member.user),
ChatMember::Member(member) => member.user.username, ChatMember::Member(member) => self._inner_get_user_name(member.user),
ChatMember::Restricted(member) => member.user.username, ChatMember::Restricted(member) => self._inner_get_user_name(member.user),
ChatMember::Left(member) => member.user.username, ChatMember::Left(member) => self._inner_get_user_name(member.user),
ChatMember::Banned(member) => member.user.username, ChatMember::Banned(member) => self._inner_get_user_name(member.user),
}; };
} }
None None

View File

@ -3,4 +3,3 @@ pub mod args_parser;
pub mod data_getters; pub mod data_getters;
pub mod member_rights; pub mod member_rights;
pub mod senders; pub mod senders;
pub mod try_admin_action;

View File

@ -2,11 +2,12 @@ use telers::{
enums::ParseMode, enums::ParseMode,
event::{telegram::HandlerResult, EventReturn}, event::{telegram::HandlerResult, EventReturn},
methods::SendMessage, methods::SendMessage,
types::Message,
Bot, Bot,
}; };
pub async fn send_html(bot: &Bot, chat_id: i64, text: &str) -> HandlerResult { pub async fn send_html(bot: &Bot, message: &Message, text: &str) -> HandlerResult {
bot.send(SendMessage::new(chat_id, text).parse_mode(ParseMode::HTML)) bot.send(SendMessage::new(message.chat().id(), text).parse_mode(ParseMode::HTML))
.await?; .await?;
Ok(EventReturn::Finish) Ok(EventReturn::Finish)

View File

@ -1,31 +0,0 @@
use telers::{
errors::{HandlerError, SessionErrorKind},
event::simple::HandlerResult,
methods::SendMessage,
Bot,
};
use super::member_rights::demote_user;
const DEMOTE_ERROR: &str = "Невозможно снять привелегий администратора в силу того, что права были выданы одним из администраторов или основателем";
pub async fn try_admin_action<F>(
callback: F,
bot: &Bot,
chat_id: i64,
user_id: i64,
) -> HandlerResult
where
F: Copy + AsyncFnOnce(i64) -> Result<bool, SessionErrorKind>,
{
if callback(user_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("DemoteFailure"));
} else {
callback(user_id).await;
}
}
Ok(())
}