diff --git a/crates/teloxide/examples/deep_linking.rs b/crates/teloxide/examples/deep_linking.rs index 1b7502bd..22a8a035 100644 --- a/crates/teloxide/examples/deep_linking.rs +++ b/crates/teloxide/examples/deep_linking.rs @@ -1,3 +1,15 @@ +//! This example demonstrates how to use deep linking in Telegram +//! by making a simple anonymous message bot. +//! +//! Deep linking (links like https://t.me/some_bot?start=123456789) +//! is handled by telegram in the same way as just sending /start {argument}. +//! So, in the StartCommand enum we need to write Start(String) to get the argument, +//! just as in command.rs example. +//! +//! Also, deep linking is only supported with /start command! +//! "https://t.me/some_bot?argument=123456789" will not work +//! +//! https://core.telegram.org/bots/features#deep-linking use dptree::{case, deps}; use teloxide::{ dispatching::dialogue::{self, InMemStorage}, @@ -14,7 +26,7 @@ pub enum State { #[default] Start, WriteToSomeone { - id: i64, + id: ChatId, }, } @@ -22,24 +34,20 @@ pub enum State { #[command(rename_rule = "lowercase")] pub enum StartCommand { #[command()] - Start(String), /* Because deep linking (links like https://t.me/some_bot?start=123456789) - * is the same as sending "/start 123456789", - * we can treat it as just an argument to a command - * - * https://core.telegram.org/bots/features#deep-linking */ + Start(String), } #[tokio::main] async fn main() { pretty_env_logger::init(); - log::info!("Starting dialogue bot..."); + log::info!("Starting deep linking bot..."); let bot = Bot::from_env(); let handler = dialogue::enter::, State, _>() .branch( Update::filter_message() - .filter_command::() // Nessary to get cmd as an argument + .filter_command::() .branch(case![StartCommand::Start(start)].endpoint(start)), ) .branch( @@ -59,30 +67,28 @@ pub async fn start( bot: Bot, dialogue: MyDialogue, msg: Message, - cmd: StartCommand, + start: String, // Available from `case![StartCommand::Start(start)]` me: Me, ) -> HandlerResult { - // If you have multiple commands, this will need to become a match - let StartCommand::Start(arg) = cmd; - - if arg.is_empty() { + if start.is_empty() { // This means that it is just a regular link like https://t.me/some_bot, or a /start command bot.send_message( msg.chat.id, format!( "Hello!\n\nThis link allows anyone to message you secretly: {}?start={}", me.tme_url(), - msg.chat.id.0 + msg.chat.id ), ) .await?; dialogue.exit().await?; } else { - // And this means that the link is like this: https://t.me/some_bot?start=123456789 - match arg.parse::() { + // And this means that the link is like this: https://t.me/some_bot?start=123456789, + // or a /start 123456789 command + match start.parse::() { Ok(id) => { bot.send_message(msg.chat.id, "Send your message:").await?; - dialogue.update(State::WriteToSomeone { id }).await?; + dialogue.update(State::WriteToSomeone { id: ChatId(id) }).await?; } Err(_) => { bot.send_message(msg.chat.id, "Bad link!").await?; @@ -95,7 +101,7 @@ pub async fn start( pub async fn send_message( bot: Bot, - id: i64, // Available from `State::WriteToSomeone`. + id: ChatId, // Available from `State::WriteToSomeone` msg: Message, dialogue: MyDialogue, me: Me, @@ -104,7 +110,7 @@ pub async fn send_message( Some(text) => { // Trying to send a message to the user let sent_result = bot - .send_message(ChatId(id), format!("You have a new message!\n\n{text}")) + .send_message(id, format!("You have a new message!\n\n{text}")) .parse_mode(teloxide::types::ParseMode::Html) .await; @@ -115,7 +121,7 @@ pub async fn send_message( format!( "Message sent!\n\nYour link is: {}?start={}", me.tme_url(), - msg.chat.id.0 + msg.chat.id ), ) .await?;