deep_linking/
deep_linking.rs1use dptree::{case, deps};
14use teloxide::{
15 dispatching::dialogue::{self, InMemStorage},
16 macros::BotCommands,
17 prelude::*,
18 types::{Me, ParseMode},
19};
20
21pub type MyDialogue = Dialogue<State, InMemStorage<State>>;
22pub type HandlerResult = Result<(), Box<dyn std::error::Error + Send + Sync>>;
23
24#[derive(Clone, PartialEq, Debug, Default)]
25pub enum State {
26 #[default]
27 Start,
28 WriteToSomeone {
29 id: ChatId,
30 },
31}
32
33#[derive(BotCommands, Clone, Debug)]
34#[command(rename_rule = "lowercase")]
35pub enum StartCommand {
36 Start(String),
37}
38
39#[tokio::main]
40async fn main() {
41 pretty_env_logger::init();
42 log::info!("Starting deep linking bot...");
43
44 let bot = Bot::from_env();
45
46 let handler = dialogue::enter::<Update, InMemStorage<State>, State, _>()
47 .branch(
48 Update::filter_message()
49 .filter_command::<StartCommand>()
50 .branch(case![StartCommand::Start(start)].endpoint(start)),
51 )
52 .branch(
53 Update::filter_message()
54 .branch(case![State::WriteToSomeone { id }].endpoint(send_message)),
55 );
56
57 Dispatcher::builder(bot, handler)
58 .dependencies(deps![InMemStorage::<State>::new()])
59 .enable_ctrlc_handler()
60 .build()
61 .dispatch()
62 .await;
63}
64
65pub async fn start(
66 bot: Bot,
67 dialogue: MyDialogue,
68 msg: Message,
69 start: String, me: Me,
71) -> HandlerResult {
72 if start.is_empty() {
73 bot.send_message(
75 msg.chat.id,
76 format!(
77 "Hello!\n\nThis link allows anyone to message you secretly: {}?start={}",
78 me.tme_url(),
79 msg.chat.id
80 ),
81 )
82 .await?;
83 dialogue.exit().await?;
84 } else {
85 match start.parse::<i64>() {
88 Ok(id) => {
89 bot.send_message(msg.chat.id, "Send your message:").await?;
90 dialogue.update(State::WriteToSomeone { id: ChatId(id) }).await?;
91 }
92 Err(_) => {
93 bot.send_message(msg.chat.id, "Bad link!").await?;
94 dialogue.exit().await?;
95 }
96 }
97 }
98 Ok(())
99}
100
101pub async fn send_message(
102 bot: Bot,
103 id: ChatId, msg: Message,
105 dialogue: MyDialogue,
106 me: Me,
107) -> HandlerResult {
108 match msg.text() {
109 Some(text) => {
110 let sent_result = bot
112 .send_message(id, format!("You have a new message!\n\n<i>{text}</i>"))
113 .parse_mode(ParseMode::Html)
114 .await;
115
116 if sent_result.is_ok() {
118 bot.send_message(
119 msg.chat.id,
120 format!(
121 "Message sent!\n\nYour link is: {}?start={}",
122 me.tme_url(),
123 msg.chat.id
124 ),
125 )
126 .await?;
127 } else {
128 bot.send_message(msg.chat.id, "Error sending message! Maybe user blocked the bot?")
129 .await?;
130 }
131 dialogue.exit().await?;
132 }
133 None => {
134 bot.send_message(msg.chat.id, "This bot can send only text.").await?;
135 }
136 };
137 Ok(())
138}