1use std::error::Error;
2use teloxide::{
3 payloads::SendMessageSetters,
4 prelude::*,
5 sugar::bot::BotMessagesExt,
6 types::{
7 InlineKeyboardButton, InlineKeyboardMarkup, InlineQueryResultArticle, InputMessageContent,
8 InputMessageContentText, Me,
9 },
10 utils::command::BotCommands,
11};
12
13#[derive(BotCommands)]
15#[command(rename_rule = "lowercase")]
16enum Command {
17 Help,
19 Start,
21}
22
23#[tokio::main]
24async fn main() -> Result<(), Box<dyn Error>> {
25 pretty_env_logger::init();
26 log::info!("Starting buttons bot...");
27
28 let bot = Bot::from_env();
29
30 let handler = dptree::entry()
31 .branch(Update::filter_message().endpoint(message_handler))
32 .branch(Update::filter_callback_query().endpoint(callback_handler))
33 .branch(Update::filter_inline_query().endpoint(inline_query_handler));
34
35 Dispatcher::builder(bot, handler).enable_ctrlc_handler().build().dispatch().await;
36 Ok(())
37}
38
39fn make_keyboard() -> InlineKeyboardMarkup {
41 let mut keyboard: Vec<Vec<InlineKeyboardButton>> = vec![];
42
43 let debian_versions = [
44 "Buzz", "Rex", "Bo", "Hamm", "Slink", "Potato", "Woody", "Sarge", "Etch", "Lenny",
45 "Squeeze", "Wheezy", "Jessie", "Stretch", "Buster", "Bullseye",
46 ];
47
48 for versions in debian_versions.chunks(3) {
49 let row = versions
50 .iter()
51 .map(|&version| InlineKeyboardButton::callback(version.to_owned(), version.to_owned()))
52 .collect();
53
54 keyboard.push(row);
55 }
56
57 InlineKeyboardMarkup::new(keyboard)
58}
59
60async fn message_handler(
64 bot: Bot,
65 msg: Message,
66 me: Me,
67) -> Result<(), Box<dyn Error + Send + Sync>> {
68 if let Some(text) = msg.text() {
69 match BotCommands::parse(text, me.username()) {
70 Ok(Command::Help) => {
71 bot.send_message(msg.chat.id, Command::descriptions().to_string()).await?;
73 }
74 Ok(Command::Start) => {
75 let keyboard = make_keyboard();
77 bot.send_message(msg.chat.id, "Debian versions:").reply_markup(keyboard).await?;
78 }
79
80 Err(_) => {
81 bot.send_message(msg.chat.id, "Command not found!").await?;
82 }
83 }
84 }
85
86 Ok(())
87}
88
89async fn inline_query_handler(
90 bot: Bot,
91 q: InlineQuery,
92) -> Result<(), Box<dyn Error + Send + Sync>> {
93 let choose_debian_version = InlineQueryResultArticle::new(
94 "0",
95 "Chose debian version",
96 InputMessageContent::Text(InputMessageContentText::new("Debian versions:")),
97 )
98 .reply_markup(make_keyboard());
99
100 bot.answer_inline_query(q.id, vec![choose_debian_version.into()]).await?;
101
102 Ok(())
103}
104
105async fn callback_handler(bot: Bot, q: CallbackQuery) -> Result<(), Box<dyn Error + Send + Sync>> {
111 if let Some(ref version) = q.data {
112 let text = format!("You chose: {version}");
113
114 bot.answer_callback_query(q.id.clone()).await?;
118
119 if let Some(message) = q.regular_message() {
121 bot.edit_text(message, text).await?;
122 } else if let Some(id) = q.inline_message_id {
123 bot.edit_message_text_inline(id, text).await?;
124 }
125
126 log::info!("You chose: {version}");
127 }
128
129 Ok(())
130}