mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-03 09:49:07 +01:00
Add a bot example for SqliteStorage
This commit is contained in:
parent
5e1fe064cd
commit
ef2a3b36ae
7 changed files with 128 additions and 0 deletions
20
examples/sqlite_remember_bot/Cargo.toml
Normal file
20
examples/sqlite_remember_bot/Cargo.toml
Normal file
|
@ -0,0 +1,20 @@
|
|||
[package]
|
||||
name = "sqlite_remember_bot"
|
||||
version = "0.1.0"
|
||||
authors = ["Sergey Levitin <selevit@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.8"
|
||||
pretty_env_logger = "0.4.0"
|
||||
tokio = { version = "0.2.11", features = ["rt-threaded", "macros"] }
|
||||
|
||||
# You can also choose "cbor-serializer" or built-in JSON serializer
|
||||
teloxide = { path = "../../", features = ["sqlite-storage", "bincode-serializer", "redis-storage"] }
|
||||
teloxide-macros = { git = "https://github.com/teloxide/teloxide-macros", branch = "master" }
|
||||
|
||||
serde = "1.0.104"
|
||||
futures = "0.3.5"
|
||||
|
||||
thiserror = "1.0.15"
|
||||
derive_more = "0.99.9"
|
BIN
examples/sqlite_remember_bot/sqlite.db
Normal file
BIN
examples/sqlite_remember_bot/sqlite.db
Normal file
Binary file not shown.
BIN
examples/sqlite_remember_bot/sqlite.db-shm
Normal file
BIN
examples/sqlite_remember_bot/sqlite.db-shm
Normal file
Binary file not shown.
BIN
examples/sqlite_remember_bot/sqlite.db-wal
Normal file
BIN
examples/sqlite_remember_bot/sqlite.db-wal
Normal file
Binary file not shown.
50
examples/sqlite_remember_bot/src/main.rs
Normal file
50
examples/sqlite_remember_bot/src/main.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
#[macro_use]
|
||||
extern crate derive_more;
|
||||
|
||||
mod states;
|
||||
mod transitions;
|
||||
|
||||
use states::*;
|
||||
|
||||
use teloxide::{
|
||||
dispatching::dialogue::{serializer::JSON, SqliteStorage, Storage},
|
||||
prelude::*,
|
||||
};
|
||||
use thiserror::Error;
|
||||
|
||||
type StorageError = <SqliteStorage<JSON> as Storage<Dialogue>>::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum Error {
|
||||
#[error("error from Telegram: {0}")]
|
||||
TelegramError(#[from] RequestError),
|
||||
#[error("error from storage: {0}")]
|
||||
StorageError(#[from] StorageError),
|
||||
}
|
||||
|
||||
type In = DialogueWithCx<Message, Dialogue, StorageError>;
|
||||
|
||||
async fn handle_message(cx: UpdateWithCx<Message>, dialogue: Dialogue) -> TransitionOut<Dialogue> {
|
||||
match cx.update.text_owned() {
|
||||
None => {
|
||||
cx.answer_str("Send me a text message.").await?;
|
||||
next(dialogue)
|
||||
}
|
||||
Some(ans) => dialogue.react(cx, ans).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let bot = Bot::from_env();
|
||||
Dispatcher::new(bot)
|
||||
.messages_handler(DialogueDispatcher::with_storage(
|
||||
|DialogueWithCx { cx, dialogue }: In| async move {
|
||||
let dialogue = dialogue.expect("std::convert::Infallible");
|
||||
handle_message(cx, dialogue).await.expect("Something wrong with the bot!")
|
||||
},
|
||||
SqliteStorage::open("sqlite.db", JSON).await.unwrap(),
|
||||
))
|
||||
.dispatch()
|
||||
.await;
|
||||
}
|
23
examples/sqlite_remember_bot/src/states.rs
Normal file
23
examples/sqlite_remember_bot/src/states.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use teloxide_macros::Transition;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Transition, From, Serialize, Deserialize)]
|
||||
pub enum Dialogue {
|
||||
Start(StartState),
|
||||
HaveNumber(HaveNumberState),
|
||||
}
|
||||
|
||||
impl Default for Dialogue {
|
||||
fn default() -> Self {
|
||||
Self::Start(StartState)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StartState;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct HaveNumberState {
|
||||
pub number: i32,
|
||||
}
|
35
examples/sqlite_remember_bot/src/transitions.rs
Normal file
35
examples/sqlite_remember_bot/src/transitions.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use teloxide::prelude::*;
|
||||
use teloxide_macros::teloxide;
|
||||
|
||||
use super::states::*;
|
||||
|
||||
#[teloxide(subtransition)]
|
||||
async fn start(state: StartState, cx: TransitionIn, ans: String) -> TransitionOut<Dialogue> {
|
||||
if let Ok(number) = ans.parse() {
|
||||
cx.answer_str(format!("Remembered number {}. Now use /get or /reset", number)).await?;
|
||||
next(HaveNumberState { number })
|
||||
} else {
|
||||
cx.answer_str("Please, send me a number").await?;
|
||||
next(state)
|
||||
}
|
||||
}
|
||||
|
||||
#[teloxide(subtransition)]
|
||||
async fn have_number(
|
||||
state: HaveNumberState,
|
||||
cx: TransitionIn,
|
||||
ans: String,
|
||||
) -> TransitionOut<Dialogue> {
|
||||
let num = state.number;
|
||||
|
||||
if ans.starts_with("/get") {
|
||||
cx.answer_str(format!("Here is your number: {}", num)).await?;
|
||||
next(state)
|
||||
} else if ans.starts_with("/reset") {
|
||||
cx.answer_str("Resetted number").await?;
|
||||
next(StartState)
|
||||
} else {
|
||||
cx.answer_str("Please, send /get or /reset").await?;
|
||||
next(state)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue