teloxide/examples/dispatching_features.rs

159 lines
5.6 KiB
Rust
Raw Normal View History

// This example provide a quick overview of the new features in the
2022-03-24 12:25:42 +01:00
// `dispatching` module.
2022-01-12 14:45:01 +01:00
use rand::Rng;
use teloxide::{
2022-03-24 12:25:42 +01:00
prelude::*,
types::{Dice, Update},
2022-04-02 11:34:43 +02:00
utils::command::BotCommands,
};
2022-01-12 14:45:01 +01:00
#[tokio::main]
async fn main() {
pretty_env_logger::init();
2022-03-24 12:25:42 +01:00
log::info!("Starting dispatching_features_bot...");
2022-01-12 14:45:01 +01:00
let bot = Bot::from_env().auto_send();
let parameters = ConfigParameters {
bot_maintainer: 268486177, // Paste your ID to run this bot.
2022-01-12 14:45:01 +01:00
maintainer_username: None,
};
2022-01-26 10:51:51 +01:00
let handler = Update::filter_message()
// You can use branching to define multiple ways in which an update will be handled. If the
// first branch fails, an update will be passed to the second branch, and so on.
2022-01-26 10:51:51 +01:00
.branch(
dptree::entry()
// Filter commands: the next handlers will receive a parsed `SimpleCommand`.
.filter_command::<SimpleCommand>()
// If a command parsing fails, this handler will not be executed.
2022-01-26 10:51:51 +01:00
.endpoint(simple_commands_handler),
)
.branch(
// Filter a maintainer by a used ID.
2022-02-04 19:02:22 +01:00
dptree::filter(|msg: Message, cfg: ConfigParameters| {
msg.from().map(|user| user.id == cfg.bot_maintainer).unwrap_or_default()
2022-01-26 10:51:51 +01:00
})
.filter_command::<MaintainerCommands>()
2022-01-26 10:51:51 +01:00
.endpoint(
|msg: Message, bot: AutoSend<Bot>, cmd: MaintainerCommands| async move {
2022-01-26 10:51:51 +01:00
match cmd {
MaintainerCommands::Rand { from, to } => {
let mut rng = rand::rngs::OsRng::default();
let value: u64 = rng.gen_range(from..=to);
bot.send_message(msg.chat.id, value.to_string()).await?;
2022-01-26 10:51:51 +01:00
Ok(())
}
}
},
),
)
.branch(
// Filtering allow you to filter updates by some condition.
dptree::filter(|msg: Message| msg.chat.is_group() || msg.chat.is_supergroup())
// An endpoint is the last update handler.
.endpoint(|msg: Message, bot: AutoSend<Bot>| async move {
log::info!("Received a message from a group chat.");
bot.send_message(msg.chat.id, "This is a group chat.").await?;
respond(())
}),
)
.branch(
// There are some extension filtering functions on `Message`. The following filter will
// filter only messages with dices.
Message::filter_dice().endpoint(
|msg: Message, dice: Dice, bot: AutoSend<Bot>| async move {
bot.send_message(msg.chat.id, format!("Dice value: {}", dice.value))
.reply_to_message_id(msg.id)
.await?;
Ok(())
},
),
2022-01-26 10:51:51 +01:00
);
Dispatcher::builder(bot, handler)
// Here you specify initial dependencies that all handlers will receive; they can be
// database connections, configurations, and other auxiliary arguments. It is similar to
// `actix_web::Extensions`.
2022-01-12 14:45:01 +01:00
.dependencies(dptree::deps![parameters])
// If no handler succeeded to handle an update, this closure will be called.
2022-02-04 17:32:06 +01:00
.default_handler(|upd| async move {
2022-01-12 14:45:01 +01:00
log::warn!("Unhandled update: {:?}", upd);
2022-02-04 17:32:06 +01:00
})
// If the dispatcher fails for some reason, execute this handler.
2022-01-26 10:51:51 +01:00
.error_handler(LoggingErrorHandler::with_custom_text(
"An error has occurred in the dispatcher",
2022-01-26 10:51:51 +01:00
))
.build()
.setup_ctrlc_handler()
2022-01-12 14:45:01 +01:00
.dispatch()
.await;
}
#[derive(Clone)]
struct ConfigParameters {
bot_maintainer: i64,
maintainer_username: Option<String>,
}
#[derive(BotCommands, Clone)]
2022-01-12 14:45:01 +01:00
#[command(rename = "lowercase", description = "Simple commands")]
enum SimpleCommand {
#[command(description = "shows this message.")]
Help,
#[command(description = "shows maintainer info.")]
Maintainer,
#[command(description = "shows your ID.")]
MyId,
}
#[derive(BotCommands, Clone)]
2022-01-12 14:45:01 +01:00
#[command(rename = "lowercase", description = "Maintainer commands")]
enum MaintainerCommands {
#[command(parse_with = "split", description = "generate a number within range")]
Rand { from: u64, to: u64 },
}
async fn simple_commands_handler(
msg: Message,
2022-01-12 14:45:01 +01:00
bot: AutoSend<Bot>,
cmd: SimpleCommand,
cfg: ConfigParameters,
2022-04-02 11:34:43 +02:00
me: teloxide::types::Me,
2022-01-12 14:45:01 +01:00
) -> Result<(), teloxide::RequestError> {
let text = match cmd {
SimpleCommand::Help => {
if msg.from().unwrap().id == cfg.bot_maintainer {
format!(
"{}\n\n{}",
SimpleCommand::descriptions(),
MaintainerCommands::descriptions()
)
} else if msg.chat.is_group() || msg.chat.is_supergroup() {
SimpleCommand::descriptions().username_from_me(&me).to_string()
2022-01-12 14:45:01 +01:00
} else {
SimpleCommand::descriptions().to_string()
2022-01-12 14:45:01 +01:00
}
}
SimpleCommand::Maintainer => {
if msg.from().unwrap().id == cfg.bot_maintainer {
2022-01-12 14:45:01 +01:00
"Maintainer is you!".into()
2022-02-03 15:48:40 +01:00
} else if let Some(username) = cfg.maintainer_username {
format!("Maintainer is @{username}")
2022-01-12 14:45:01 +01:00
} else {
2022-02-03 15:48:40 +01:00
format!("Maintainer ID is {}", cfg.bot_maintainer)
2022-01-12 14:45:01 +01:00
}
}
SimpleCommand::MyId => {
format!("{}", msg.from().unwrap().id)
2022-01-12 14:45:01 +01:00
}
};
bot.send_message(msg.chat.id, text).await?;
2022-01-12 14:45:01 +01:00
Ok(())
}