2020-04-19 19:47:12 +02:00
|
|
|
use teloxide::{
|
2022-01-06 12:54:07 +01:00
|
|
|
dispatching2::dialogue::{serializer::Bincode, RedisStorage, Storage},
|
2020-04-19 19:47:12 +02:00
|
|
|
prelude::*,
|
2021-03-15 04:22:10 +01:00
|
|
|
RequestError,
|
2020-04-19 19:47:12 +02:00
|
|
|
};
|
|
|
|
use thiserror::Error;
|
|
|
|
|
2022-01-06 12:54:07 +01:00
|
|
|
type Store = RedisStorage<Bincode>;
|
|
|
|
// FIXME: naming
|
|
|
|
type MyDialogue = Dialogue<BotDialogue, Store>;
|
|
|
|
type StorageError = <RedisStorage<Bincode> as Storage<BotDialogue>>::Error;
|
2020-04-19 19:47:12 +02:00
|
|
|
|
|
|
|
#[derive(Debug, Error)]
|
|
|
|
enum Error {
|
|
|
|
#[error("error from Telegram: {0}")]
|
|
|
|
TelegramError(#[from] RequestError),
|
|
|
|
#[error("error from storage: {0}")]
|
|
|
|
StorageError(#[from] StorageError),
|
|
|
|
}
|
|
|
|
|
2022-01-06 12:54:07 +01:00
|
|
|
#[derive(serde::Serialize, serde::Deserialize)]
|
|
|
|
pub enum BotDialogue {
|
|
|
|
Start,
|
|
|
|
HaveNumber(i32),
|
|
|
|
}
|
2020-04-19 19:47:12 +02:00
|
|
|
|
2022-01-06 12:54:07 +01:00
|
|
|
impl Default for BotDialogue {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::Start
|
|
|
|
}
|
2020-04-19 19:47:12 +02:00
|
|
|
}
|
2020-07-26 19:16:49 +02:00
|
|
|
|
2021-03-05 22:24:10 +01:00
|
|
|
async fn handle_message(
|
2022-01-06 12:54:07 +01:00
|
|
|
bot: AutoSend<Bot>,
|
|
|
|
mes: Message,
|
|
|
|
dialogue: MyDialogue,
|
|
|
|
) -> Result<(), Error> {
|
|
|
|
match mes.text() {
|
2020-07-26 19:16:49 +02:00
|
|
|
None => {
|
2022-01-06 12:54:07 +01:00
|
|
|
bot.send_message(mes.chat.id, "Send me a text message.").await?;
|
|
|
|
}
|
|
|
|
Some(ans) => {
|
|
|
|
let state = dialogue.current_state_or_default().await?;
|
|
|
|
match state {
|
|
|
|
BotDialogue::Start => {
|
|
|
|
if let Ok(number) = ans.parse() {
|
|
|
|
dialogue.next(BotDialogue::HaveNumber(number)).await?;
|
|
|
|
bot.send_message(
|
|
|
|
mes.chat.id,
|
|
|
|
format!("Remembered number {}. Now use /get or /reset", number),
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
} else {
|
|
|
|
bot.send_message(mes.chat.id, "Please, send me a number").await?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BotDialogue::HaveNumber(num) => {
|
|
|
|
if ans.starts_with("/get") {
|
|
|
|
bot.send_message(mes.chat.id, format!("Here is your number: {}", num))
|
|
|
|
.await?;
|
|
|
|
} else if ans.starts_with("/reset") {
|
|
|
|
dialogue.reset().await?;
|
|
|
|
bot.send_message(mes.chat.id, "Resetted number").await?;
|
|
|
|
} else {
|
|
|
|
bot.send_message(mes.chat.id, "Please, send /get or /reset").await?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-07-26 19:16:49 +02:00
|
|
|
}
|
|
|
|
}
|
2022-01-06 12:54:07 +01:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() {
|
|
|
|
let bot = Bot::from_env().auto_send();
|
|
|
|
// You can also choose serializer::JSON or serializer::CBOR
|
|
|
|
// All serializers but JSON require enabling feature
|
|
|
|
// "serializer-<name>", e. g. "serializer-cbor"
|
|
|
|
// or "serializer-bincode"
|
|
|
|
let storage = RedisStorage::open("redis://127.0.0.1:6379", Bincode).await.unwrap();
|
|
|
|
|
|
|
|
Dispatcher::new(bot)
|
|
|
|
.dependencies(dptree::deps![storage])
|
|
|
|
.messages_handler(|h| {
|
|
|
|
h.add_dialogue::<Message, Store, BotDialogue>().branch(dptree::endpoint(handle_message))
|
|
|
|
})
|
|
|
|
.dispatch()
|
|
|
|
.await;
|
2020-07-26 19:16:49 +02:00
|
|
|
}
|