1use teloxide::{dispatching::dialogue::InMemStorage, prelude::*};
17
18type MyDialogue = Dialogue<State, InMemStorage<State>>;
19type HandlerResult = Result<(), Box<dyn std::error::Error + Send + Sync>>;
20
21#[derive(Clone, Default)]
22pub enum State {
23 #[default]
24 Start,
25 ReceiveFullName,
26 ReceiveAge {
27 full_name: String,
28 },
29 ReceiveLocation {
30 full_name: String,
31 age: u8,
32 },
33}
34
35#[tokio::main]
36async fn main() {
37 pretty_env_logger::init();
38 log::info!("Starting dialogue bot...");
39
40 let bot = Bot::from_env();
41
42 Dispatcher::builder(
43 bot,
44 Update::filter_message()
45 .enter_dialogue::<Message, InMemStorage<State>, State>()
46 .branch(dptree::case![State::Start].endpoint(start))
47 .branch(dptree::case![State::ReceiveFullName].endpoint(receive_full_name))
48 .branch(dptree::case![State::ReceiveAge { full_name }].endpoint(receive_age))
49 .branch(
50 dptree::case![State::ReceiveLocation { full_name, age }].endpoint(receive_location),
51 ),
52 )
53 .dependencies(dptree::deps![InMemStorage::<State>::new()])
54 .enable_ctrlc_handler()
55 .build()
56 .dispatch()
57 .await;
58}
59
60async fn start(bot: Bot, dialogue: MyDialogue, msg: Message) -> HandlerResult {
61 bot.send_message(msg.chat.id, "Let's start! What's your full name?").await?;
62 dialogue.update(State::ReceiveFullName).await?;
63 Ok(())
64}
65
66async fn receive_full_name(bot: Bot, dialogue: MyDialogue, msg: Message) -> HandlerResult {
67 match msg.text() {
68 Some(text) => {
69 bot.send_message(msg.chat.id, "How old are you?").await?;
70 dialogue.update(State::ReceiveAge { full_name: text.into() }).await?;
71 }
72 None => {
73 bot.send_message(msg.chat.id, "Send me plain text.").await?;
74 }
75 }
76
77 Ok(())
78}
79
80async fn receive_age(
81 bot: Bot,
82 dialogue: MyDialogue,
83 full_name: String, msg: Message,
85) -> HandlerResult {
86 match msg.text().map(|text| text.parse::<u8>()) {
87 Some(Ok(age)) => {
88 bot.send_message(msg.chat.id, "What's your location?").await?;
89 dialogue.update(State::ReceiveLocation { full_name, age }).await?;
90 }
91 _ => {
92 bot.send_message(msg.chat.id, "Send me a number.").await?;
93 }
94 }
95
96 Ok(())
97}
98
99async fn receive_location(
100 bot: Bot,
101 dialogue: MyDialogue,
102 (full_name, age): (String, u8), msg: Message,
104) -> HandlerResult {
105 match msg.text() {
106 Some(location) => {
107 let report = format!("Full name: {full_name}\nAge: {age}\nLocation: {location}");
108 bot.send_message(msg.chat.id, report).await?;
109 dialogue.exit().await?;
110 }
111 None => {
112 bot.send_message(msg.chat.id, "Send me plain text.").await?;
113 }
114 }
115
116 Ok(())
117}