use dptree::{case, deps};
use teloxide::{
dispatching::dialogue::{self, InMemStorage},
macros::BotCommands,
prelude::*,
types::{Me, ParseMode},
};
pub type MyDialogue = Dialogue<State, InMemStorage<State>>;
pub type HandlerResult = Result<(), Box<dyn std::error::Error + Send + Sync>>;
#[derive(Clone, PartialEq, Debug, Default)]
pub enum State {
#[default]
Start,
WriteToSomeone {
id: ChatId,
},
}
#[derive(BotCommands, Clone, Debug)]
#[command(rename_rule = "lowercase")]
pub enum StartCommand {
Start(String),
}
#[tokio::main]
async fn main() {
pretty_env_logger::init();
log::info!("Starting deep linking bot...");
let bot = Bot::from_env();
let handler = dialogue::enter::<Update, InMemStorage<State>, State, _>()
.branch(
Update::filter_message()
.filter_command::<StartCommand>()
.branch(case![StartCommand::Start(start)].endpoint(start)),
)
.branch(
Update::filter_message()
.branch(case![State::WriteToSomeone { id }].endpoint(send_message)),
);
Dispatcher::builder(bot, handler)
.dependencies(deps![InMemStorage::<State>::new()])
.enable_ctrlc_handler()
.build()
.dispatch()
.await;
}
pub async fn start(
bot: Bot,
dialogue: MyDialogue,
msg: Message,
start: String, me: Me,
) -> HandlerResult {
if start.is_empty() {
bot.send_message(
msg.chat.id,
format!(
"Hello!\n\nThis link allows anyone to message you secretly: {}?start={}",
me.tme_url(),
msg.chat.id
),
)
.await?;
dialogue.exit().await?;
} else {
match start.parse::<i64>() {
Ok(id) => {
bot.send_message(msg.chat.id, "Send your message:").await?;
dialogue.update(State::WriteToSomeone { id: ChatId(id) }).await?;
}
Err(_) => {
bot.send_message(msg.chat.id, "Bad link!").await?;
dialogue.exit().await?;
}
}
}
Ok(())
}
pub async fn send_message(
bot: Bot,
id: ChatId, msg: Message,
dialogue: MyDialogue,
me: Me,
) -> HandlerResult {
match msg.text() {
Some(text) => {
let sent_result = bot
.send_message(id, format!("You have a new message!\n\n<i>{text}</i>"))
.parse_mode(ParseMode::Html)
.await;
if sent_result.is_ok() {
bot.send_message(
msg.chat.id,
format!(
"Message sent!\n\nYour link is: {}?start={}",
me.tme_url(),
msg.chat.id
),
)
.await?;
} else {
bot.send_message(msg.chat.id, "Error sending message! Maybe user blocked the bot?")
.await?;
}
dialogue.exit().await?;
}
None => {
bot.send_message(msg.chat.id, "This bot can send only text.").await?;
}
};
Ok(())
}