mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-20 15:54:53 +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