2022-01-12 14:45:01 +01:00
|
|
|
//! This example provide quick overview of the new features in the
|
|
|
|
//! `dispatching2` module.
|
|
|
|
|
|
|
|
use rand::Rng;
|
|
|
|
/// Note that you need to import `prelude2` because `prelude` contains
|
|
|
|
/// items from the old dispatching system (it may change in future versions).
|
|
|
|
use teloxide::prelude2::*;
|
2022-01-28 15:52:01 +01:00
|
|
|
use teloxide::{types::Update, utils::command::BotCommand};
|
2022-01-12 14:45:01 +01:00
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() {
|
|
|
|
// Start you main as early: start logging, create bot, etc.
|
|
|
|
teloxide::enable_logging!();
|
|
|
|
log::info!("Starting dispatching2_features_bot...");
|
|
|
|
let bot = Bot::from_env().auto_send();
|
|
|
|
|
|
|
|
let parameters = ConfigParameters {
|
|
|
|
bot_maintainer: 268486177, // Paste your ID if you run this bot.
|
|
|
|
maintainer_username: None,
|
|
|
|
};
|
|
|
|
|
2022-01-26 10:51:51 +01:00
|
|
|
let handler = Update::filter_message()
|
|
|
|
// Branch is a special method that allow you to handle update several ways.
|
|
|
|
.branch(
|
|
|
|
// Filter allow you to filter updates by some condition.
|
|
|
|
dptree::filter(
|
|
|
|
// Note that `async move` is obligatory.
|
2022-02-02 10:40:22 +01:00
|
|
|
|msg: Message| async move { msg.chat.is_group() || msg.chat.is_supergroup() },
|
2022-01-26 10:51:51 +01:00
|
|
|
)
|
|
|
|
// Endpoint is a last message handler.
|
2022-02-02 10:40:22 +01:00
|
|
|
.endpoint(|msg: Message, bot: AutoSend<Bot>| async move {
|
2022-01-26 10:51:51 +01:00
|
|
|
log::info!("Received message from the group chat.");
|
2022-02-02 10:40:22 +01:00
|
|
|
bot.send_message(msg.chat.id, "This is a group chat.").await?;
|
2022-01-26 10:51:51 +01:00
|
|
|
respond(())
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
// Note that we cannot filter messages from public chats in the next branch,
|
|
|
|
// because they all is handled by previous branch.
|
|
|
|
.branch(
|
|
|
|
// There are some `filter` functions on message, that filters events. This
|
|
|
|
// filter will filter only messages with dices.
|
2022-02-02 10:40:22 +01:00
|
|
|
Message::filter_dice().endpoint(|msg: Message, bot: AutoSend<Bot>| async move {
|
|
|
|
bot.send_message(msg.chat.id, "This is a dice!")
|
|
|
|
.reply_to_message_id(msg.id)
|
2022-01-26 10:51:51 +01:00
|
|
|
.await?;
|
|
|
|
Ok(())
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
.branch(
|
|
|
|
// If you do not like photos, you can break their handling like that.
|
|
|
|
Message::filter_photo().endpoint(|| async move { Ok(()) }),
|
|
|
|
)
|
|
|
|
.branch(
|
|
|
|
dptree::entry()
|
|
|
|
// This method allows to parse text messages commands.
|
2022-02-04 14:46:34 +01:00
|
|
|
.filter_command::<SimpleCommand>()
|
2022-01-26 10:51:51 +01:00
|
|
|
// Next we can add `SimpleCommand` in the argument of endpoint. If
|
|
|
|
// command parsing fails, this endpoint will not be called.
|
|
|
|
.endpoint(simple_commands_handler),
|
|
|
|
)
|
|
|
|
.branch(
|
|
|
|
// Filter maintainer by used ID.
|
2022-02-02 10:40:22 +01:00
|
|
|
dptree::filter(|msg: Message, cfg: ConfigParameters| async move {
|
|
|
|
msg.from().map(|user| user.id == cfg.bot_maintainer).unwrap_or_default()
|
2022-01-26 10:51:51 +01:00
|
|
|
})
|
2022-02-04 14:46:34 +01:00
|
|
|
.filter_command::<MaintainerCommands>()
|
2022-01-26 10:51:51 +01:00
|
|
|
.endpoint(
|
2022-02-02 10:40:22 +01:00
|
|
|
|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);
|
|
|
|
|
2022-02-02 10:40:22 +01:00
|
|
|
bot.send_message(msg.chat.id, value.to_string()).await?;
|
2022-01-26 10:51:51 +01:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
2022-01-12 14:45:01 +01:00
|
|
|
// Start create dispatcher.
|
2022-02-04 15:09:53 +01:00
|
|
|
Dispatcher::builder(bot, handler)
|
2022-01-12 14:45:01 +01:00
|
|
|
// You can specify dependencies to that you have access inside of handlers. It may be
|
2022-01-26 10:51:51 +01:00
|
|
|
// configs, connection to Database, or dialogue storage (see more in the dialogue_bot
|
|
|
|
// example). It is similar to the `actix_web::Extensions`.
|
2022-01-12 14:45:01 +01:00
|
|
|
.dependencies(dptree::deps![parameters])
|
2022-01-26 10:51:51 +01:00
|
|
|
// Now handlers don't use streams. Instead handler is special constructs from `dptree`
|
|
|
|
// library. Any `*_handler` accepts function `Fn(UpdateHandler) -> UpdateHandler`
|
|
|
|
// which is builder for the handlers. Note that you _must_ use it instead of using
|
|
|
|
// `dptree` methods forward.
|
2022-01-12 14:45:01 +01:00
|
|
|
.default_handler(dptree::endpoint(|upd: Update| async move {
|
|
|
|
// This handler handles updates that do not handled by other handlers.
|
|
|
|
log::warn!("Unhandled update: {:?}", upd);
|
|
|
|
}))
|
|
|
|
// If `Result::Err` returns from the dispatcher, it goes here.
|
2022-01-26 10:51:51 +01:00
|
|
|
.error_handler(LoggingErrorHandler::with_custom_text(
|
|
|
|
"Error has occurred in the dispatcher",
|
|
|
|
))
|
2022-02-01 23:51:36 +01:00
|
|
|
.build()
|
2022-02-03 11:34:40 +01:00
|
|
|
.setup_ctrlc_handler()
|
2022-01-12 14:45:01 +01:00
|
|
|
.dispatch()
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
struct ConfigParameters {
|
|
|
|
bot_maintainer: i64,
|
|
|
|
maintainer_username: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
// We do not change BotCommand api.
|
|
|
|
#[derive(BotCommand, Clone)]
|
|
|
|
#[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(BotCommand, Clone)]
|
|
|
|
#[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(
|
2022-02-02 10:40:22 +01:00
|
|
|
msg: Message,
|
2022-01-12 14:45:01 +01:00
|
|
|
bot: AutoSend<Bot>,
|
|
|
|
cmd: SimpleCommand,
|
|
|
|
cfg: ConfigParameters,
|
|
|
|
) -> Result<(), teloxide::RequestError> {
|
|
|
|
let text = match cmd {
|
|
|
|
SimpleCommand::Help => {
|
2022-02-02 10:40:22 +01:00
|
|
|
if msg.from().unwrap().id == cfg.bot_maintainer {
|
2022-01-12 14:45:01 +01:00
|
|
|
format!("{}\n{}", SimpleCommand::descriptions(), MaintainerCommands::descriptions())
|
|
|
|
} else {
|
|
|
|
SimpleCommand::descriptions()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SimpleCommand::Maintainer => {
|
2022-02-02 10:40:22 +01:00
|
|
|
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 => {
|
2022-02-02 10:40:22 +01:00
|
|
|
format!("{}", msg.from().unwrap().id)
|
2022-01-12 14:45:01 +01:00
|
|
|
}
|
|
|
|
};
|
2022-02-02 10:40:22 +01:00
|
|
|
bot.send_message(msg.chat.id, text).await?;
|
2022-01-12 14:45:01 +01:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|