db_remember/
db_remember.rs1use teloxide::{
5 dispatching::dialogue::{
6 serializer::{Bincode, Json},
7 ErasedStorage, RedisStorage, SqliteStorage, Storage,
8 },
9 prelude::*,
10 utils::command::BotCommands,
11};
12
13type MyDialogue = Dialogue<State, ErasedStorage<State>>;
14type MyStorage = std::sync::Arc<ErasedStorage<State>>;
15type HandlerResult = Result<(), Box<dyn std::error::Error + Send + Sync>>;
16
17#[derive(Clone, Default, serde::Serialize, serde::Deserialize)]
18pub enum State {
19 #[default]
20 Start,
21 GotNumber(i32),
22}
23
24#[derive(Clone, BotCommands)]
26#[command(rename_rule = "lowercase")]
27pub enum Command {
28 Get,
30 Reset,
32}
33
34#[tokio::main]
35async fn main() {
36 pretty_env_logger::init();
37 log::info!("Starting DB remember bot...");
38
39 let bot = Bot::from_env();
40
41 let storage: MyStorage = if std::env::var("DB_REMEMBER_REDIS").is_ok() {
42 RedisStorage::open("redis://127.0.0.1:6379", Bincode).await.unwrap().erase()
43 } else {
44 SqliteStorage::open("db.sqlite", Json).await.unwrap().erase()
45 };
46
47 let handler = Update::filter_message()
48 .enter_dialogue::<Message, ErasedStorage<State>, State>()
49 .branch(dptree::case![State::Start].endpoint(start))
50 .branch(
51 dptree::case![State::GotNumber(n)]
52 .branch(dptree::entry().filter_command::<Command>().endpoint(got_number))
53 .branch(dptree::endpoint(invalid_command)),
54 );
55
56 Dispatcher::builder(bot, handler)
57 .dependencies(dptree::deps![storage])
58 .enable_ctrlc_handler()
59 .build()
60 .dispatch()
61 .await;
62}
63
64async fn start(bot: Bot, dialogue: MyDialogue, msg: Message) -> HandlerResult {
65 match msg.text().map(|text| text.parse::<i32>()) {
66 Some(Ok(n)) => {
67 dialogue.update(State::GotNumber(n)).await?;
68 bot.send_message(
69 msg.chat.id,
70 format!("Remembered number {n}. Now use /get or /reset."),
71 )
72 .await?;
73 }
74 _ => {
75 bot.send_message(msg.chat.id, "Please, send me a number.").await?;
76 }
77 }
78
79 Ok(())
80}
81
82async fn got_number(
83 bot: Bot,
84 dialogue: MyDialogue,
85 num: i32, msg: Message,
87 cmd: Command,
88) -> HandlerResult {
89 match cmd {
90 Command::Get => {
91 bot.send_message(msg.chat.id, format!("Here is your number: {num}.")).await?;
92 }
93 Command::Reset => {
94 dialogue.reset().await?;
95 bot.send_message(msg.chat.id, "Number reset.").await?;
96 }
97 }
98 Ok(())
99}
100
101async fn invalid_command(bot: Bot, msg: Message) -> HandlerResult {
102 bot.send_message(msg.chat.id, "Please, send /get or /reset.").await?;
103 Ok(())
104}