From b03d76c4948de0d4ad6680983564b53113d17f83 Mon Sep 17 00:00:00 2001 From: Nefrace Date: Tue, 11 Oct 2022 22:59:37 +0300 Subject: [PATCH] Admin commands, minor refactoring --- src/godette.rs | 85 ++++++++++++----------------------- src/{ => godette}/commands.rs | 9 ++++ src/godette/handlers.rs | 68 ++++++++++++++++++++++++++++ src/main.rs | 7 ++- 4 files changed, 112 insertions(+), 57 deletions(-) rename src/{ => godette}/commands.rs (66%) create mode 100644 src/godette/handlers.rs diff --git a/src/godette.rs b/src/godette.rs index 5bcd8d8..7045829 100644 --- a/src/godette.rs +++ b/src/godette.rs @@ -1,8 +1,8 @@ -use teloxide::{ - prelude::*, types::ParseMode::MarkdownV2, utils::command::BotCommands, utils::markdown, -}; +use teloxide::prelude::*; -use crate::commands::Command; +pub mod commands; +mod handlers; +use commands::{AdminCommand, Command}; pub struct Godette { pub bot: Bot, @@ -17,10 +17,27 @@ impl Godette { pub async fn commands_dispatcher(bot: Bot, msg: Message, cmd: Command) -> ResponseResult<()> { match cmd { - Command::Help => Godette::show_help(bot, msg).await?, - Command::Me(quote) => Godette::me(bot, msg, quote).await?, - Command::Warn(reason) => Godette::warn(bot, msg, reason).await?, - Command::Unwarn => Godette::unwarn(bot, msg).await?, + Command::Help => handlers::show_help(bot, msg).await?, + Command::Me(quote) => handlers::me(bot, msg, quote).await?, + }; + Ok(()) + } + + pub async fn admin_dispatcher(bot: Bot, msg: Message, cmd: AdminCommand) -> ResponseResult<()> { + let mut is_admin = true; + if msg.chat.is_group() || msg.chat.is_supergroup() { + let sender = msg.from().unwrap(); + let admins = bot.get_chat_administrators(msg.chat.id).await?; + is_admin = admins.iter().any(|member| member.user.id == sender.id); + } + if !is_admin { + return Ok(()); + } + match cmd { + AdminCommand::HelpAdmin => handlers::show_adminhelp(bot, msg).await?, + AdminCommand::Say(quote) => handlers::say(bot, msg, quote).await?, + AdminCommand::Warn(reason) => handlers::warn(bot, msg, reason).await?, + AdminCommand::Unwarn => handlers::unwarn(bot, msg).await?, }; Ok(()) } @@ -31,55 +48,11 @@ impl Godette { .unwrap_or(msg.caption().unwrap_or_default()) .to_string(); match text.to_lowercase().find("спасибо") { - Some(_id) => bot.send_message(msg.chat.id, "Не за что!").await?, - None => todo!(), + Some(_id) => { + bot.send_message(msg.chat.id, "Не за что!").await?; + } + None => (), }; Ok(()) } - - async fn show_help(bot: Bot, msg: Message) -> ResponseResult { - bot.send_message(msg.chat.id, Command::descriptions().to_string()) - .await - } - - async fn me(bot: Bot, msg: Message, quote: String) -> ResponseResult { - let name = msg.from().unwrap().to_owned().full_name(); - let esc_username = markdown::escape(&name); - let esc_quote = markdown::escape("e); - - let text = format!("*_{esc_username}_* {esc_quote}").to_string(); - bot.delete_message(msg.chat.id, msg.id).await?; - bot.send_message(msg.chat.id, text) - .parse_mode(MarkdownV2) - .await - } - - async fn warn(bot: Bot, msg: Message, reason: String) -> ResponseResult { - match msg.reply_to_message() { - Some(guilty) => { - let username = guilty.from().unwrap().to_owned().full_name(); - let username_formatted = markdown::bold(&markdown::escape(&username)); - let reason_formatted = markdown::italic(&markdown::escape(&reason)); - let text = format!( - "{username_formatted} получил предупреждение по причине:\n\"{reason_formatted}\"" - ); - bot.send_message(msg.chat.id, text) - .parse_mode(MarkdownV2) - .await - } - None => { - bot.send_message( - msg.chat.id, - "Используйте эту команду как ответ на сообщение, требующее действий." - .to_string(), - ) - .await - } - } - } - - async fn unwarn(bot: Bot, msg: Message) -> ResponseResult { - bot.send_message(msg.chat.id, "Это разбан".to_string()) - .await - } } diff --git a/src/commands.rs b/src/godette/commands.rs similarity index 66% rename from src/commands.rs rename to src/godette/commands.rs index b146cd2..3b39c76 100644 --- a/src/commands.rs +++ b/src/godette/commands.rs @@ -6,8 +6,17 @@ pub enum Command { Help, #[command(description = "Написать сообщение от третьего лица")] Me(String), +} + +#[derive(BotCommands, Clone)] +#[command(rename_rule = "lowercase", description = "Админские команды:")] +pub enum AdminCommand { + #[command(description = "Отобразить эту помощь")] + HelpAdmin, #[command(description = "Выдать предупреждение пользователю (только для админов)")] Warn(String), #[command(description = "Снять предупреждения и убрать мут")] Unwarn, + #[command(description = "Сказать от моего лица")] + Say(String), } diff --git a/src/godette/handlers.rs b/src/godette/handlers.rs new file mode 100644 index 0000000..7aca68f --- /dev/null +++ b/src/godette/handlers.rs @@ -0,0 +1,68 @@ +use teloxide::{ + payloads::SendMessageSetters, + prelude::*, + types::ParseMode::MarkdownV2, + utils::command::BotCommands, + utils::markdown::{self, bold, escape, italic}, +}; + +use crate::commands::{AdminCommand, Command}; + +pub async fn show_help(bot: Bot, msg: Message) -> ResponseResult { + bot.send_message(msg.chat.id, Command::descriptions().to_string()) + .await +} +pub async fn show_adminhelp(bot: Bot, msg: Message) -> ResponseResult { + bot.send_message(msg.chat.id, AdminCommand::descriptions().to_string()) + .await +} + +pub async fn me(bot: Bot, msg: Message, quote: String) -> ResponseResult { + let name = msg.from().unwrap().to_owned().full_name(); + let esc_username = markdown::escape(&name); + let esc_quote = markdown::escape("e); + + let text = format!("*_{esc_username}_* {esc_quote}").to_string(); + bot.delete_message(msg.chat.id, msg.id).await?; + bot.send_message(msg.chat.id, text) + .parse_mode(MarkdownV2) + .await +} + +pub async fn say(bot: Bot, msg: Message, quote: String) -> ResponseResult { + let text = bold(&italic(&escape("e))); + bot.delete_message(msg.chat.id, msg.id).await?; + let message = bot.send_message(msg.chat.id, text).parse_mode(MarkdownV2); + match msg.reply_to_message() { + Some(reply) => message.reply_to_message_id(reply.id).await, + None => message.await, + } +} + +pub async fn warn(bot: Bot, msg: Message, reason: String) -> ResponseResult { + match msg.reply_to_message() { + Some(guilty) => { + let username = guilty.from().unwrap().to_owned().full_name(); + let username_formatted = markdown::bold(&markdown::escape(&username)); + let reason_formatted = markdown::italic(&markdown::escape(&reason)); + let text = format!( + "{username_formatted} получил предупреждение по причине:\n\"{reason_formatted}\"" + ); + bot.send_message(msg.chat.id, text) + .parse_mode(MarkdownV2) + .await + } + None => { + bot.send_message( + msg.chat.id, + "Используйте эту команду как ответ на сообщение, требующее действий.".to_string(), + ) + .await + } + } +} + +pub async fn unwarn(bot: Bot, msg: Message) -> ResponseResult { + bot.send_message(msg.chat.id, "Это разбан".to_string()) + .await +} diff --git a/src/main.rs b/src/main.rs index 5505365..2da409d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ -mod commands; mod godette; use teloxide::prelude::*; +use godette::commands; use godette::Godette; #[tokio::main] @@ -16,6 +16,11 @@ async fn main() { .filter_command::() .endpoint(Godette::commands_dispatcher), ) + .branch( + dptree::entry() + .filter_command::() + .endpoint(Godette::admin_dispatcher), + ) .branch( dptree::filter(|msg: Message| { msg.from()