teloxide/examples/admin.rs

140 lines
4 KiB
Rust
Raw Normal View History

use std::str::FromStr;
2020-02-13 19:26:06 +01:00
2022-01-12 12:03:10 +01:00
use chrono::Duration;
2022-04-02 11:34:43 +02:00
use teloxide::{prelude::*, types::ChatPermissions, utils::command::BotCommands};
2020-02-11 20:35:22 +01:00
// Derive BotCommands to parse text with a command into this enumeration.
2020-02-13 19:11:56 +01:00
//
// 1. `rename_rule = "lowercase"` turns all the commands into lowercase letters.
// 2. `description = "..."` specifies a text before all the commands.
2020-02-13 19:11:56 +01:00
//
// That is, you can just call Command::descriptions() to get a description of
// your commands in this format:
// %GENERAL-DESCRIPTION%
// %PREFIX%%COMMAND% - %DESCRIPTION%
#[derive(BotCommands, Clone)]
2020-02-13 18:23:22 +01:00
#[command(
rename_rule = "lowercase",
2020-06-24 19:43:21 +02:00
description = "Use commands in format /%command% %num% %unit%",
parse_with = "split"
2020-02-13 18:23:22 +01:00
)]
2020-02-11 20:35:22 +01:00
enum Command {
#[command(description = "kick user from chat.")]
Kick,
#[command(description = "ban user in chat.")]
2020-06-24 19:43:21 +02:00
Ban {
2021-07-05 21:16:29 +02:00
time: u64,
2020-06-24 19:43:21 +02:00
unit: UnitOfTime,
},
2020-02-11 20:35:22 +01:00
#[command(description = "mute user in chat.")]
2020-06-24 19:43:21 +02:00
Mute {
2021-07-05 21:16:29 +02:00
time: u64,
2020-06-24 19:43:21 +02:00
unit: UnitOfTime,
},
2020-02-11 20:35:22 +01:00
Help,
}
2021-12-26 18:59:32 +01:00
#[derive(Clone)]
2020-06-24 19:43:21 +02:00
enum UnitOfTime {
Seconds,
Minutes,
Hours,
2020-02-11 20:35:22 +01:00
}
2020-06-24 19:43:21 +02:00
impl FromStr for UnitOfTime {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
match s {
"h" | "hours" => Ok(UnitOfTime::Hours),
"m" | "minutes" => Ok(UnitOfTime::Minutes),
"s" | "seconds" => Ok(UnitOfTime::Seconds),
_ => Err("Allowed units: h, m, s"),
}
2020-02-11 20:35:22 +01:00
}
}
#[tokio::main]
async fn main() {
pretty_env_logger::init();
log::info!("Starting admin bot...");
let bot = teloxide::Bot::from_env();
Command::repl(bot, action).await;
2020-02-11 20:35:22 +01:00
}
async fn action(bot: Bot, msg: Message, cmd: Command) -> ResponseResult<()> {
match cmd {
Command::Help => {
2022-04-02 11:34:43 +02:00
bot.send_message(msg.chat.id, Command::descriptions().to_string()).await?;
}
Command::Kick => kick_user(bot, msg).await?,
Command::Ban { time, unit } => ban_user(bot, msg, calc_restrict_time(time, unit)).await?,
Command::Mute { time, unit } => mute_user(bot, msg, calc_restrict_time(time, unit)).await?,
};
Ok(())
}
2021-12-26 18:59:32 +01:00
// Kick a user with a replied message.
async fn kick_user(bot: Bot, msg: Message) -> ResponseResult<()> {
match msg.reply_to_message() {
2021-12-26 18:59:32 +01:00
Some(replied) => {
// bot.unban_chat_member can also kicks a user from a group chat.
2022-02-04 14:45:35 +01:00
bot.unban_chat_member(msg.chat.id, replied.from().unwrap().id).await?;
2020-06-24 19:43:21 +02:00
}
2020-02-13 16:42:24 +01:00
None => {
2022-02-04 14:45:35 +01:00
bot.send_message(msg.chat.id, "Use this command in reply to another message").await?;
2020-02-13 18:23:22 +01:00
}
2020-02-13 16:42:24 +01:00
}
Ok(())
}
// Ban a user with replied message.
async fn ban_user(bot: Bot, msg: Message, time: Duration) -> ResponseResult<()> {
match msg.reply_to_message() {
2021-12-26 18:59:32 +01:00
Some(replied) => {
bot.kick_chat_member(
2022-02-04 14:45:35 +01:00
msg.chat.id,
2021-12-26 18:59:32 +01:00
replied.from().expect("Must be MessageKind::Common").id,
)
2022-02-03 15:39:32 +01:00
.until_date(msg.date + time)
2021-12-26 18:59:32 +01:00
.await?;
2020-02-13 18:23:22 +01:00
}
2020-02-13 16:42:24 +01:00
None => {
2022-02-04 14:45:35 +01:00
bot.send_message(msg.chat.id, "Use this command in a reply to another message!")
2021-12-26 18:59:32 +01:00
.await?;
2020-02-13 16:42:24 +01:00
}
}
Ok(())
}
// Mute a user with a replied message.
async fn mute_user(bot: Bot, msg: Message, time: Duration) -> ResponseResult<()> {
match msg.reply_to_message() {
2021-12-26 18:59:32 +01:00
Some(replied) => {
bot.restrict_chat_member(
2022-02-04 14:45:35 +01:00
msg.chat.id,
2021-12-26 18:59:32 +01:00
replied.from().expect("Must be MessageKind::Common").id,
ChatPermissions::empty(),
2021-12-26 18:59:32 +01:00
)
2022-02-03 15:39:32 +01:00
.until_date(msg.date + time)
2021-12-26 18:59:32 +01:00
.await?;
2020-06-24 19:43:21 +02:00
}
2020-02-13 16:42:24 +01:00
None => {
2022-02-04 14:45:35 +01:00
bot.send_message(msg.chat.id, "Use this command in a reply to another message!")
2021-12-26 18:59:32 +01:00
.await?;
2020-02-13 18:23:22 +01:00
}
2020-02-13 16:42:24 +01:00
}
Ok(())
}
// Calculates time of user restriction.
fn calc_restrict_time(time: u64, unit: UnitOfTime) -> Duration {
match unit {
UnitOfTime::Hours => Duration::hours(time as i64),
UnitOfTime::Minutes => Duration::minutes(time as i64),
UnitOfTime::Seconds => Duration::seconds(time as i64),
}
2020-02-11 20:35:22 +01:00
}