mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 22:46:39 +01:00
update dialogue_bot example
This commit is contained in:
parent
b10288f751
commit
50f37cf43b
9 changed files with 94 additions and 125 deletions
|
@ -7,7 +7,9 @@ edition = "2018"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
teloxide = { path = "../../", features = ["frunk", "macros", "auto-send"] }
|
||||
teloxide = { path = "../../", features = ["frunk", "macros", "auto-send", "sqlite-storage"] }
|
||||
anyhow = "1.0.52"
|
||||
serde = "1"
|
||||
|
||||
futures = "0.3.5"
|
||||
tokio = { version = "1.3.0", features = ["rt-multi-thread", "macros"] }
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
mod states;
|
||||
|
||||
use crate::dialogue::states::{
|
||||
ReceiveAgeState, ReceiveFullNameState, ReceiveLocationState, StartState,
|
||||
};
|
||||
use derive_more::From;
|
||||
use teloxide::macros::Transition;
|
||||
|
||||
#[derive(Transition, Clone, From)]
|
||||
pub enum Dialogue {
|
||||
Start(StartState),
|
||||
ReceiveFullName(ReceiveFullNameState),
|
||||
ReceiveAge(ReceiveAgeState),
|
||||
ReceiveLocation(ReceiveLocationState),
|
||||
}
|
||||
|
||||
impl Default for Dialogue {
|
||||
fn default() -> Self {
|
||||
Self::Start(StartState)
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
mod receive_age;
|
||||
mod receive_full_name;
|
||||
mod receive_location;
|
||||
mod start;
|
||||
|
||||
pub use receive_age::ReceiveAgeState;
|
||||
pub use receive_full_name::ReceiveFullNameState;
|
||||
pub use receive_location::ReceiveLocationState;
|
||||
pub use start::StartState;
|
|
@ -1,25 +0,0 @@
|
|||
use crate::dialogue::{states::receive_location::ReceiveLocationState, Dialogue};
|
||||
use teloxide::prelude::*;
|
||||
|
||||
#[derive(Clone, Generic)]
|
||||
pub struct ReceiveAgeState {
|
||||
pub full_name: String,
|
||||
}
|
||||
|
||||
#[teloxide(subtransition)]
|
||||
async fn receive_age_state(
|
||||
state: ReceiveAgeState,
|
||||
cx: TransitionIn<AutoSend<Bot>>,
|
||||
ans: String,
|
||||
) -> TransitionOut<Dialogue> {
|
||||
match ans.parse::<u8>() {
|
||||
Ok(ans) => {
|
||||
cx.answer("What's your location?").await?;
|
||||
next(ReceiveLocationState::up(state, ans))
|
||||
}
|
||||
_ => {
|
||||
cx.answer("Send me a number.").await?;
|
||||
next(state)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
use crate::dialogue::{states::receive_age::ReceiveAgeState, Dialogue};
|
||||
use teloxide::prelude::*;
|
||||
|
||||
#[derive(Clone, Generic)]
|
||||
pub struct ReceiveFullNameState;
|
||||
|
||||
#[teloxide(subtransition)]
|
||||
async fn receive_full_name(
|
||||
state: ReceiveFullNameState,
|
||||
cx: TransitionIn<AutoSend<Bot>>,
|
||||
ans: String,
|
||||
) -> TransitionOut<Dialogue> {
|
||||
cx.answer("How old are you?").await?;
|
||||
next(ReceiveAgeState::up(state, ans))
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
use crate::dialogue::Dialogue;
|
||||
use teloxide::prelude::*;
|
||||
|
||||
#[derive(Clone, Generic)]
|
||||
pub struct ReceiveLocationState {
|
||||
pub full_name: String,
|
||||
pub age: u8,
|
||||
}
|
||||
|
||||
#[teloxide(subtransition)]
|
||||
async fn receive_location(
|
||||
state: ReceiveLocationState,
|
||||
cx: TransitionIn<AutoSend<Bot>>,
|
||||
ans: String,
|
||||
) -> TransitionOut<Dialogue> {
|
||||
cx.answer(format!("Full name: {}\nAge: {}\nLocation: {}", state.full_name, state.age, ans))
|
||||
.await?;
|
||||
exit()
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
use crate::dialogue::{states::ReceiveFullNameState, Dialogue};
|
||||
use teloxide::prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct StartState;
|
||||
|
||||
#[teloxide(subtransition)]
|
||||
async fn start(
|
||||
_state: StartState,
|
||||
cx: TransitionIn<AutoSend<Bot>>,
|
||||
_ans: String,
|
||||
) -> TransitionOut<Dialogue> {
|
||||
cx.answer("Let's start! What's your full name?").await?;
|
||||
next(ReceiveFullNameState)
|
||||
}
|
|
@ -13,17 +13,30 @@
|
|||
// Age: 223
|
||||
// Location: Middle-earth
|
||||
// ```
|
||||
use crate::state::State;
|
||||
use teloxide::{
|
||||
dispatching2::dialogue::{serializer::Json, SqliteStorage},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
#![allow(clippy::trivial_regex)]
|
||||
#![allow(dead_code)]
|
||||
// FIXME: naming
|
||||
type MyBot = AutoSend<Bot>;
|
||||
type Store = SqliteStorage<Json>;
|
||||
type BotDialogue = Dialogue<State, Store>;
|
||||
|
||||
#[macro_use]
|
||||
extern crate frunk;
|
||||
#[derive(Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub enum State {
|
||||
Start,
|
||||
ReceiveFullName,
|
||||
ReceiveAge { full_name: String },
|
||||
ReceiveLocation { full_name: String, age: u8 },
|
||||
}
|
||||
|
||||
mod dialogue;
|
||||
|
||||
use crate::dialogue::Dialogue;
|
||||
use teloxide::prelude::*;
|
||||
impl Default for State {
|
||||
fn default() -> Self {
|
||||
Self::Start
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
@ -35,22 +48,80 @@ async fn run() {
|
|||
log::info!("Starting dialogue_bot...");
|
||||
|
||||
let bot = Bot::from_env().auto_send();
|
||||
let storage = SqliteStorage::open("db.sqlite", Json).await.unwrap();
|
||||
|
||||
teloxide::dialogues_repl(bot, |message, dialogue| async move {
|
||||
handle_message(message, dialogue).await.expect("Something wrong with the bot!")
|
||||
})
|
||||
.await;
|
||||
Dispatcher::new(bot)
|
||||
.dependencies(dptree::deps![storage])
|
||||
.messages_handler(|h| {
|
||||
h.add_dialogue::<Message, Store, State>().branch(dptree::endpoint(handle_message))
|
||||
})
|
||||
.dispatch()
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn handle_message(
|
||||
cx: UpdateWithCx<AutoSend<Bot>, Message>,
|
||||
dialogue: Dialogue,
|
||||
) -> TransitionOut<Dialogue> {
|
||||
match cx.update.text().map(ToOwned::to_owned) {
|
||||
async fn handle_message(bot: MyBot, mes: Message, dialogue: BotDialogue) -> anyhow::Result<()> {
|
||||
match mes.text().map(ToOwned::to_owned) {
|
||||
None => {
|
||||
cx.answer("Send me a text message.").await?;
|
||||
next(dialogue)
|
||||
bot.send_message(mes.chat_id(), "Send me a text message.").await?;
|
||||
Ok(())
|
||||
}
|
||||
Some(ans) => dialogue.react(cx, ans).await,
|
||||
Some(_) => match dialogue.current_state_or_default().await? {
|
||||
State::Start => handle_start(bot, mes, dialogue).await,
|
||||
State::ReceiveFullName => handle_receive_full_name(bot, mes, dialogue).await,
|
||||
State::ReceiveAge { full_name } => {
|
||||
handle_receive_age(bot, mes, dialogue, full_name).await
|
||||
}
|
||||
State::ReceiveLocation { full_name, age } => {
|
||||
handle_receive_location(bot, mes, dialogue, full_name, age).await
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_start(bot: MyBot, mes: Message, dialogue: BotDialogue) -> anyhow::Result<()> {
|
||||
bot.send_message(mes.chat_id(), "Let's start! What's your full name?").await?;
|
||||
dialogue.next(State::ReceiveFullName).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_receive_full_name(
|
||||
bot: MyBot,
|
||||
mes: Message,
|
||||
dialogue: BotDialogue,
|
||||
) -> anyhow::Result<()> {
|
||||
bot.send_message(mes.chat_id(), "How old are you?").await?;
|
||||
dialogue.next(State::ReceiveAge { full_name: mes.text().unwrap().into() }).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_receive_age(
|
||||
bot: MyBot,
|
||||
mes: Message,
|
||||
dialogue: BotDialogue,
|
||||
full_name: String,
|
||||
) -> anyhow::Result<()> {
|
||||
match mes.text().unwrap().parse::<u8>() {
|
||||
Ok(age) => {
|
||||
bot.send_message(mes.chat_id(), "What's your location?").await?;
|
||||
dialogue.next(State::ReceiveLocation { full_name, age }).await?;
|
||||
}
|
||||
_ => {
|
||||
bot.send_message(mes.chat_id(), "Send me a number.").await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_receive_location(
|
||||
bot: MyBot,
|
||||
mes: Message,
|
||||
dialogue: BotDialogue,
|
||||
full_name: String,
|
||||
age: u8,
|
||||
) -> anyhow::Result<()> {
|
||||
let location = mes.text().unwrap();
|
||||
let message = format!("Full name: {}\nAge: {}\nLocation: {}", full_name, age, location);
|
||||
bot.send_message(mes.chat_id(), message).await?;
|
||||
dialogue.exit().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
0
examples/dialogue_bot/src/state.rs
Normal file
0
examples/dialogue_bot/src/state.rs
Normal file
Loading…
Reference in a new issue