mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 22:46:39 +01:00
Update redis_remember_bot
This commit is contained in:
parent
fb6156a3b9
commit
03ab247262
5 changed files with 89 additions and 69 deletions
|
@ -45,9 +45,9 @@ async fn run() {
|
|||
|
||||
Dispatcher::new(bot)
|
||||
.messages_handler(DialogueDispatcher::new(
|
||||
|cx: DialogueWithCx<Message, Dialogue, Infallible>| async move {
|
||||
|input: TransitionIn<Dialogue, Infallible>| async move {
|
||||
// Unwrap without panic because of std::convert::Infallible.
|
||||
dispatch(cx.cx, cx.dialogue.unwrap())
|
||||
dispatch(input.cx, input.dialogue.unwrap())
|
||||
.await
|
||||
.expect("Something wrong with the bot!")
|
||||
},
|
||||
|
|
|
@ -6,8 +6,11 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
tokio = "0.2.9"
|
||||
smart-default = "0.6.0"
|
||||
|
||||
# You can also choose "cbor-serializer" or built-in JSON serializer
|
||||
teloxide = { path = "../../", features = ["redis-storage", "bincode-serializer"] }
|
||||
serde = "1.0.104"
|
||||
|
||||
thiserror = "1.0.15"
|
||||
smart-default = "0.6.0"
|
||||
derive_more = "0.99.9"
|
|
@ -1,5 +1,14 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use smart_default::SmartDefault;
|
||||
#[macro_use]
|
||||
extern crate smart_default;
|
||||
#[macro_use]
|
||||
extern crate derive_more;
|
||||
|
||||
mod states;
|
||||
mod transitions;
|
||||
|
||||
use states::*;
|
||||
use transitions::*;
|
||||
|
||||
use std::sync::Arc;
|
||||
use teloxide::{
|
||||
dispatching::dialogue::{serializer::Bincode, RedisStorage, Storage},
|
||||
|
@ -7,13 +16,6 @@ use teloxide::{
|
|||
};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(SmartDefault, Serialize, Deserialize)]
|
||||
enum Dialogue {
|
||||
#[default]
|
||||
Start,
|
||||
HaveNumber(i32),
|
||||
}
|
||||
|
||||
type StorageError = <RedisStorage<Bincode> as Storage<Dialogue>>::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
@ -24,70 +26,20 @@ enum Error {
|
|||
StorageError(#[from] StorageError),
|
||||
}
|
||||
|
||||
type Cx<State> = DialogueDispatcherHandlerCx<Message, State, StorageError>;
|
||||
type In = TransitionIn<Dialogue, StorageError>;
|
||||
|
||||
type Res = Result<DialogueStage<Dialogue>, Error>;
|
||||
async fn handle_message(input: In) -> Out {
|
||||
let (cx, dialogue) = input.unpack();
|
||||
|
||||
async fn handle_message(cx: Cx<Dialogue>) -> Res {
|
||||
let DialogueDispatcherHandlerCx { bot, update, dialogue } = cx;
|
||||
let text = match update.text() {
|
||||
let text = match cx.update.text_owned() {
|
||||
Some(text) => text,
|
||||
None => {
|
||||
bot.send_message(
|
||||
update.chat_id(),
|
||||
"Please, send me a text message",
|
||||
)
|
||||
.send()
|
||||
.await?;
|
||||
return next(Dialogue::Start);
|
||||
cx.answer_str("Please, send me a text message").await?;
|
||||
return next(StartState);
|
||||
}
|
||||
};
|
||||
|
||||
match dialogue? {
|
||||
Dialogue::Start => {
|
||||
if let Ok(number) = text.parse() {
|
||||
bot.send_message(
|
||||
update.chat_id(),
|
||||
format!(
|
||||
"Remembered number {}. Now use /get or /reset",
|
||||
number
|
||||
),
|
||||
)
|
||||
.send()
|
||||
.await?;
|
||||
next(Dialogue::HaveNumber(number))
|
||||
} else {
|
||||
bot.send_message(update.chat_id(), "Please, send me a number")
|
||||
.send()
|
||||
.await?;
|
||||
next(Dialogue::Start)
|
||||
}
|
||||
}
|
||||
Dialogue::HaveNumber(num) => {
|
||||
if text.starts_with("/get") {
|
||||
bot.send_message(
|
||||
update.chat_id(),
|
||||
format!("Here is your number: {}", num),
|
||||
)
|
||||
.send()
|
||||
.await?;
|
||||
next(Dialogue::HaveNumber(num))
|
||||
} else if text.starts_with("/reset") {
|
||||
bot.send_message(update.chat_id(), format!("Resetted number"))
|
||||
.send()
|
||||
.await?;
|
||||
next(Dialogue::Start)
|
||||
} else {
|
||||
bot.send_message(
|
||||
update.chat_id(),
|
||||
"Please, send /get or /reset",
|
||||
)
|
||||
.send()
|
||||
.await?;
|
||||
next(Dialogue::HaveNumber(num))
|
||||
}
|
||||
}
|
||||
}
|
||||
dispatch(cx, dialogue, &text).await
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
use teloxide::prelude::*;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Default, Serialize, Deserialize)]
|
||||
pub struct StartState;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct HaveNumberState {
|
||||
rest: StartState,
|
||||
pub number: i32,
|
||||
}
|
||||
|
||||
up!(
|
||||
StartState + [number: i32] -> HaveNumberState,
|
||||
);
|
||||
|
||||
#[derive(SmartDefault, From, Serialize, Deserialize)]
|
||||
pub enum Dialogue {
|
||||
#[default]
|
||||
Start(StartState),
|
||||
HaveNumber(HaveNumberState),
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
use teloxide::prelude::*;
|
||||
|
||||
use super::states::*;
|
||||
|
||||
pub type Cx = UpdateWithCx<Message>;
|
||||
pub type Out = TransitionOut<Dialogue>;
|
||||
|
||||
async fn start(cx: Cx, state: StartState, text: &str) -> Out {
|
||||
if let Ok(number) = text.parse() {
|
||||
cx.answer_str(format!(
|
||||
"Remembered number {}. Now use /get or /reset",
|
||||
number
|
||||
))
|
||||
.await?;
|
||||
next(state.up(number))
|
||||
} else {
|
||||
cx.answer_str("Please, send me a number").await?;
|
||||
next(state)
|
||||
}
|
||||
}
|
||||
|
||||
async fn have_number(cx: Cx, state: HaveNumberState, text: &str) -> Out {
|
||||
let num = state.number;
|
||||
|
||||
if text.starts_with("/get") {
|
||||
cx.answer_str(format!("Here is your number: {}", num)).await?;
|
||||
next(state)
|
||||
} else if text.starts_with("/reset") {
|
||||
cx.answer_str(format!("Resetted number")).await?;
|
||||
next(StartState)
|
||||
} else {
|
||||
cx.answer_str("Please, send /get or /reset").await?;
|
||||
next(state)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn dispatch(cx: Cx, dialogue: Dialogue, text: &str) -> Out {
|
||||
match dialogue {
|
||||
Dialogue::Start(state) => start(cx, state, text).await,
|
||||
Dialogue::HaveNumber(state) => have_number(cx, state, text).await,
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue