mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 22:46:39 +01:00
fixed example and added documentation
This commit is contained in:
parent
726a46b5ab
commit
c9f811a311
2 changed files with 114 additions and 64 deletions
|
@ -7,7 +7,6 @@ edition = "2018"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
pretty_env_logger = "0.3.1"
|
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
tokio = "0.2.9"
|
tokio = "0.2.9"
|
||||||
teloxide = { path = "../../" }
|
teloxide = { path = "../../" }
|
||||||
|
|
|
@ -2,8 +2,12 @@ use teloxide::prelude::*;
|
||||||
use teloxide::utils::command::BotCommand;
|
use teloxide::utils::command::BotCommand;
|
||||||
use teloxide::types::ChatPermissions;
|
use teloxide::types::ChatPermissions;
|
||||||
|
|
||||||
|
// Declare type of handler context
|
||||||
type Ctx = DispatcherHandlerCtx<Message>;
|
type Ctx = DispatcherHandlerCtx<Message>;
|
||||||
|
|
||||||
|
// Derive trait which allow to parse text with command into enum
|
||||||
|
// (rename = "lowercase") means that names of variants of enum will be lowercase before parsing
|
||||||
|
// `description` will be add before description of command when you call Command::descriptions()
|
||||||
#[derive(BotCommand)]
|
#[derive(BotCommand)]
|
||||||
#[command(rename = "lowercase", description = "Use commands in format /%command% %num% %unit%")]
|
#[command(rename = "lowercase", description = "Use commands in format /%command% %num% %unit%")]
|
||||||
enum Command {
|
enum Command {
|
||||||
|
@ -17,15 +21,17 @@ enum Command {
|
||||||
Help,
|
Help,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate time of restrict user.
|
||||||
fn calc_restrict_time(num: i32, unit: &str) -> Result<i32, &str> {
|
fn calc_restrict_time(num: i32, unit: &str) -> Result<i32, &str> {
|
||||||
match unit {
|
match unit {
|
||||||
"h"|"hours" => Ok(num * 3600),
|
"h"|"hours" => Ok(num * 3600),
|
||||||
"m"|"minutes" => Ok(num * 60),
|
"m"|"minutes" => Ok(num * 60),
|
||||||
"s"|"seconds" => Ok(num),
|
"s"|"seconds" => Ok(num),
|
||||||
_ => Err("allowed units: h, m, s")
|
_ => Err("Allowed units: h, m, s")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse args which user printed after command.
|
||||||
fn parse_args(args: Vec<&str>) -> Result<(i32, &str), &str> {
|
fn parse_args(args: Vec<&str>) -> Result<(i32, &str), &str> {
|
||||||
let num = match args.get(0) {
|
let num = match args.get(0) {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
|
@ -42,80 +48,127 @@ fn parse_args(args: Vec<&str>) -> Result<(i32, &str), &str> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse input args into time to restrict
|
||||||
fn parse_time_restrict(args: Vec<&str>) -> Result<i32, &str> {
|
fn parse_time_restrict(args: Vec<&str>) -> Result<i32, &str> {
|
||||||
let (num, unit) = parse_args(args)?;
|
let (num, unit) = parse_args(args)?;
|
||||||
calc_restrict_time(num, unit)
|
calc_restrict_time(num, unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_command(ctx: Ctx) -> Result<(), ()> {
|
// Mute user by replied message
|
||||||
if let Some(text) = ctx.update.text() {
|
async fn mute_user(ctx: &Ctx, args: Vec<&str>) -> Result<(), RequestError> {
|
||||||
let (command, args): (Command, Vec<&str>) = Command::parse(text).ok_or(())?;
|
|
||||||
|
|
||||||
match command {
|
|
||||||
Command::Help => {
|
|
||||||
ctx.answer(Command::descriptions()).send().await;
|
|
||||||
}
|
|
||||||
Command::Kick => {
|
|
||||||
match ctx.update.reply_to_message() {
|
|
||||||
Some(mes) => {
|
|
||||||
if let Some(user) = mes.from() {
|
|
||||||
ctx.bot.unban_chat_member(
|
|
||||||
ctx.update.chat_id(),
|
|
||||||
user.id
|
|
||||||
).send().await;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
ctx.reply_to("Use this command in reply to another message").send().await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::Ban => {
|
|
||||||
match ctx.update.reply_to_message() {
|
match ctx.update.reply_to_message() {
|
||||||
Some(mes) => match parse_time_restrict(args) {
|
Some(mes) => match parse_time_restrict(args) {
|
||||||
|
// Mute user temporarily...
|
||||||
Ok(time) => {
|
Ok(time) => {
|
||||||
if let Some(user) = mes.from() {
|
|
||||||
ctx.bot.kick_chat_member(
|
|
||||||
ctx.update.chat_id(),
|
|
||||||
user.id
|
|
||||||
)
|
|
||||||
.until_date(ctx.update.date + time)
|
|
||||||
.send()
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(msg) => {
|
|
||||||
ctx.answer(msg).send().await;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
ctx.reply_to("Use this command in reply to another message").send().await;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::Mute => {
|
|
||||||
match ctx.update.reply_to_message() {
|
|
||||||
Some(mes) => match parse_time_restrict(args) {
|
|
||||||
Ok(time) => {
|
|
||||||
if let Some(user) = mes.from() {
|
|
||||||
ctx.bot.restrict_chat_member(
|
ctx.bot.restrict_chat_member(
|
||||||
ctx.update.chat_id(),
|
ctx.update.chat_id(),
|
||||||
user.id,
|
// Sender of message cannot be only in messages from channels
|
||||||
|
// so we can use unwrap()
|
||||||
|
mes.from().unwrap().id,
|
||||||
ChatPermissions::default()
|
ChatPermissions::default()
|
||||||
)
|
)
|
||||||
.until_date(ctx.update.date + time)
|
.until_date(ctx.update.date + time)
|
||||||
.send()
|
.send()
|
||||||
.await;
|
.await?;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// ...or permanently
|
||||||
Err(msg) => {
|
Err(msg) => {
|
||||||
ctx.answer(msg).send().await;
|
ctx.bot.restrict_chat_member(
|
||||||
|
ctx.update.chat_id(),
|
||||||
|
mes.from().unwrap().id,
|
||||||
|
ChatPermissions::default()
|
||||||
|
)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
ctx.reply_to("Use this command in reply to another message").send().await;
|
ctx.reply_to("Use this command in reply to another message").send().await?;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kick user by replied message
|
||||||
|
async fn kick_user(ctx: &Ctx) -> Result<(), RequestError> {
|
||||||
|
match ctx.update.reply_to_message() {
|
||||||
|
Some(mes) => {
|
||||||
|
// `unban_chat_member` will also kick user from group chat
|
||||||
|
ctx.bot.unban_chat_member(
|
||||||
|
ctx.update.chat_id(),
|
||||||
|
mes.from().unwrap().id
|
||||||
|
).send().await?;
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
ctx.reply_to("Use this command in reply to another message").send().await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ban user by replied message
|
||||||
|
async fn ban_user(ctx: &Ctx, args: Vec<&str>) -> Result<(), RequestError> {
|
||||||
|
match ctx.update.reply_to_message() {
|
||||||
|
Some(mes) => match parse_time_restrict(args) {
|
||||||
|
// Mute user temporarily...
|
||||||
|
Ok(time) => {
|
||||||
|
ctx.bot.kick_chat_member(
|
||||||
|
ctx.update.chat_id(),
|
||||||
|
mes.from().unwrap().id
|
||||||
|
)
|
||||||
|
.until_date(ctx.update.date + time)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
// ...or permanently
|
||||||
|
Err(msg) => {
|
||||||
|
ctx.bot.kick_chat_member(
|
||||||
|
ctx.update.chat_id(),
|
||||||
|
mes.from().unwrap().id
|
||||||
|
)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
ctx.reply_to("Use this command in reply to another message").send().await?;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle all messages
|
||||||
|
async fn handle_command(ctx: Ctx) -> Result<(), RequestError> {
|
||||||
|
// If message not from group stop handled.
|
||||||
|
// NOTE: in this case we have only one `message_handler`. If you have more, return
|
||||||
|
// DispatcherHandlerResult::next() so that the following handlers can receive this message!
|
||||||
|
if ctx.update.chat.is_group() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(text) = ctx.update.text() {
|
||||||
|
// Parse text into command with args
|
||||||
|
let (command, args): (Command, Vec<&str>) = match Command::parse(text) {
|
||||||
|
Some(tuple) => tuple,
|
||||||
|
None => return Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
|
match command {
|
||||||
|
Command::Help => {
|
||||||
|
// Command::descriptions() return a message in format:
|
||||||
|
//
|
||||||
|
// %general_description%
|
||||||
|
// %prefix%%command% - %description%
|
||||||
|
ctx.answer(Command::descriptions()).send().await?;
|
||||||
|
}
|
||||||
|
Command::Kick => {
|
||||||
|
kick_user(&ctx).await?;
|
||||||
|
}
|
||||||
|
Command::Ban => {
|
||||||
|
ban_user(&ctx, args).await?;
|
||||||
|
}
|
||||||
|
Command::Mute => {
|
||||||
|
mute_user(&ctx, args).await?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -125,9 +178,7 @@ async fn handle_command(ctx: Ctx) -> Result<(), ()> {
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
pretty_env_logger::init();
|
let bot = Bot::from_env().enable_logging(crate_name!()).build();
|
||||||
|
|
||||||
let bot = Bot::new("YourAwesomeToken");
|
|
||||||
Dispatcher::new(bot)
|
Dispatcher::new(bot)
|
||||||
.message_handler(&handle_command)
|
.message_handler(&handle_command)
|
||||||
.dispatch()
|
.dispatch()
|
||||||
|
|
Loading…
Reference in a new issue