mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 22:46:39 +01:00
5922984f6c
In reordering the parameters, I stick the following principle: place parameters from least changing to most changing. Thus, we have config and bot right from the beginning, next a dialogue with a possible payload, and next updates such as messages, inline queries, etc. This principle is used in languages with a native support for currying, although in Rust people appear to order parameters arbitrarily, so this commit is mostly for the sake of consistency.
129 lines
4.2 KiB
Rust
129 lines
4.2 KiB
Rust
use std::error::Error;
|
|
use teloxide::{
|
|
payloads::SendMessageSetters,
|
|
prelude::*,
|
|
types::{
|
|
InlineKeyboardButton, InlineKeyboardMarkup, InlineQueryResultArticle, InputMessageContent,
|
|
InputMessageContentText, Me,
|
|
},
|
|
utils::command::BotCommands,
|
|
};
|
|
|
|
#[derive(BotCommands)]
|
|
#[command(rename = "lowercase", description = "These commands are supported:")]
|
|
enum Command {
|
|
#[command(description = "Display this text")]
|
|
Help,
|
|
#[command(description = "Start")]
|
|
Start,
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn Error>> {
|
|
pretty_env_logger::init();
|
|
log::info!("Starting buttons bot...");
|
|
|
|
let bot = Bot::from_env();
|
|
|
|
let handler = dptree::entry()
|
|
.branch(Update::filter_message().endpoint(message_handler))
|
|
.branch(Update::filter_callback_query().endpoint(callback_handler))
|
|
.branch(Update::filter_inline_query().endpoint(inline_query_handler));
|
|
|
|
Dispatcher::builder(bot, handler).enable_ctrlc_handler().build().dispatch().await;
|
|
Ok(())
|
|
}
|
|
|
|
/// Creates a keyboard made by buttons in a big column.
|
|
fn make_keyboard() -> InlineKeyboardMarkup {
|
|
let mut keyboard: Vec<Vec<InlineKeyboardButton>> = vec![];
|
|
|
|
let debian_versions = [
|
|
"Buzz", "Rex", "Bo", "Hamm", "Slink", "Potato", "Woody", "Sarge", "Etch", "Lenny",
|
|
"Squeeze", "Wheezy", "Jessie", "Stretch", "Buster", "Bullseye",
|
|
];
|
|
|
|
for versions in debian_versions.chunks(3) {
|
|
let row = versions
|
|
.iter()
|
|
.map(|&version| InlineKeyboardButton::callback(version.to_owned(), version.to_owned()))
|
|
.collect();
|
|
|
|
keyboard.push(row);
|
|
}
|
|
|
|
InlineKeyboardMarkup::new(keyboard)
|
|
}
|
|
|
|
/// Parse the text wrote on Telegram and check if that text is a valid command
|
|
/// or not, then match the command. If the command is `/start` it writes a
|
|
/// markup with the `InlineKeyboardMarkup`.
|
|
async fn message_handler(
|
|
bot: Bot,
|
|
msg: Message,
|
|
me: Me,
|
|
) -> Result<(), Box<dyn Error + Send + Sync>> {
|
|
if let Some(text) = msg.text() {
|
|
match BotCommands::parse(text, me.username()) {
|
|
Ok(Command::Help) => {
|
|
// Just send the description of all commands.
|
|
bot.send_message(msg.chat.id, Command::descriptions().to_string()).await?;
|
|
}
|
|
Ok(Command::Start) => {
|
|
// Create a list of buttons and send them.
|
|
let keyboard = make_keyboard();
|
|
bot.send_message(msg.chat.id, "Debian versions:").reply_markup(keyboard).await?;
|
|
}
|
|
|
|
Err(_) => {
|
|
bot.send_message(msg.chat.id, "Command not found!").await?;
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn inline_query_handler(
|
|
bot: Bot,
|
|
q: InlineQuery,
|
|
) -> Result<(), Box<dyn Error + Send + Sync>> {
|
|
let choose_debian_version = InlineQueryResultArticle::new(
|
|
"0",
|
|
"Chose debian version",
|
|
InputMessageContent::Text(InputMessageContentText::new("Debian versions:")),
|
|
)
|
|
.reply_markup(make_keyboard());
|
|
|
|
bot.answer_inline_query(q.id, vec![choose_debian_version.into()]).await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// When it receives a callback from a button it edits the message with all
|
|
/// those buttons writing a text with the selected Debian version.
|
|
///
|
|
/// **IMPORTANT**: do not send privacy-sensitive data this way!!!
|
|
/// Anyone can read data stored in the callback button.
|
|
async fn callback_handler(bot: Bot, q: CallbackQuery) -> Result<(), Box<dyn Error + Send + Sync>> {
|
|
if let Some(version) = q.data {
|
|
let text = format!("You chose: {version}");
|
|
|
|
// Tell telegram that we've seen this query, to remove 🕑 icons from the
|
|
//
|
|
// clients. You could also use `answer_callback_query`'s optional
|
|
// parameters to tweak what happens on the client side.
|
|
bot.answer_callback_query(q.id).await?;
|
|
|
|
// Edit text of the message to which the buttons were attached
|
|
if let Some(Message { id, chat, .. }) = q.message {
|
|
bot.edit_message_text(chat.id, id, text).await?;
|
|
} else if let Some(id) = q.inline_message_id {
|
|
bot.edit_message_text_inline(id, text).await?;
|
|
}
|
|
|
|
log::info!("You chose: {}", version);
|
|
}
|
|
|
|
Ok(())
|
|
}
|