use CallbackInfo for buttons

This commit is contained in:
Akulij 2025-06-06 03:32:58 +05:00
parent 6e31fa86e6
commit b8bd104f3d

View File

@ -1,5 +1,7 @@
use futures::future::join_all;
use log::{error, info}; use log::{error, info};
use quickjs_rusty::serde::{from_js, to_js}; use quickjs_rusty::serde::{from_js, to_js};
use serde_json::Value;
use std::{ use std::{
str::FromStr, str::FromStr,
sync::{Arc, Mutex, RwLock}, sync::{Arc, Mutex, RwLock},
@ -15,14 +17,18 @@ use teloxide::{
use crate::{ use crate::{
botscript::{self, message_info::MessageInfoBuilder, BotMessage, RunnerConfig}, botscript::{self, message_info::MessageInfoBuilder, BotMessage, RunnerConfig},
commands::BotCommand, commands::BotCommand,
db::{CallDB, DB}, db::{callback_info::CallbackInfo, CallDB, DB},
message_answerer::MessageAnswerer, message_answerer::MessageAnswerer,
notify_admin, update_user_tg, BotError, BotResult, BotRuntime, notify_admin, update_user_tg,
utils::callback_button,
BotError, BotResult, BotRuntime,
}; };
pub type BotHandler = pub type BotHandler =
Handler<'static, DependencyMap, BotResult<()>, teloxide::dispatching::DpHandlerDescription>; Handler<'static, DependencyMap, BotResult<()>, teloxide::dispatching::DpHandlerDescription>;
type CallbackStore = CallbackInfo<Value>;
pub fn script_handler(r: Arc<Mutex<BotRuntime>>) -> BotHandler { pub fn script_handler(r: Arc<Mutex<BotRuntime>>) -> BotHandler {
let cr = r.clone(); let cr = r.clone();
dptree::entry() dptree::entry()
@ -48,14 +54,38 @@ pub fn script_handler(r: Arc<Mutex<BotRuntime>>) -> BotHandler {
) )
.branch( .branch(
Update::filter_callback_query() Update::filter_callback_query()
.filter_map(move |q: CallbackQuery| { .filter_map_async(move |q: CallbackQuery, mut db: DB| {
q.data.and_then(|data| { let r = Arc::clone(&cr);
let r = std::sync::Arc::clone(&cr); async move {
let data = match q.data {
Some(data) => data,
None => return None,
};
let ci = match CallbackStore::get(&mut db, &data).await {
Ok(ci) => ci,
Err(err) => {
notify_admin(&format!(
"Failed to get callback from CallbackInfo, err: {err}"
))
.await;
return None;
}
};
let ci = match ci {
Some(ci) => ci,
None => return None,
};
let data = match ci.literal {
Some(data) => data,
None => return None,
};
let r = r.lock().expect("RwLock lock on commands map failed"); let r = r.lock().expect("RwLock lock on commands map failed");
let rc = &r.rc; let rc = &r.rc;
rc.get_callback_message(&data) rc.get_callback_message(&data)
}) }
}) })
.endpoint(handle_callback), .endpoint(handle_callback),
) )
@ -126,25 +156,40 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) -
return Ok(()); return Ok(());
} }
let buttons = bm let button_db = db.clone();
.resolve_buttons(&mut db) let buttons = bm.resolve_buttons(&mut db).await?.map(async |buttons| {
.await? join_all(buttons.iter().map(async |r| {
.map(|buttons| InlineKeyboardMarkup { join_all(r.iter().map(async |b| {
inline_keyboard: buttons match b {
.iter() botscript::ButtonLayout::Callback {
.map(|r| { name,
r.iter() literal: _,
.map(|b| match b { callback,
botscript::ButtonLayout::Callback { } => {
name, callback_button(
literal: _, name,
callback, callback.to_string(),
} => InlineKeyboardButton::callback(name, callback), None::<bool>,
}) &mut button_db.clone(),
.collect() )
}) .await
.collect(), }
}); }
}))
.await
.into_iter()
.collect::<Result<_, _>>()
}))
.await
.into_iter()
.collect::<Result<_, _>>()
});
let buttons = match buttons {
Some(b) => Some(InlineKeyboardMarkup {
inline_keyboard: b.await?,
}),
None => None,
};
let literal = bm.literal().map_or("", |s| s.as_str()); let literal = bm.literal().map_or("", |s| s.as_str());
let ma = MessageAnswerer::new(&bot, &mut db, msg.chat.id.0); let ma = MessageAnswerer::new(&bot, &mut db, msg.chat.id.0);
@ -207,25 +252,40 @@ async fn handle_callback(bot: Bot, mut db: DB, bm: BotMessage, q: CallbackQuery)
return Ok(()); return Ok(());
} }
let buttons = bm let button_db = db.clone();
.resolve_buttons(&mut db) let buttons = bm.resolve_buttons(&mut db).await?.map(async |buttons| {
.await? join_all(buttons.iter().map(async |r| {
.map(|buttons| InlineKeyboardMarkup { join_all(r.iter().map(async |b| {
inline_keyboard: buttons match b {
.iter() botscript::ButtonLayout::Callback {
.map(|r| { name,
r.iter() literal: _,
.map(|b| match b { callback,
botscript::ButtonLayout::Callback { } => {
name, callback_button(
literal: _, name,
callback, callback.to_string(),
} => InlineKeyboardButton::callback(name, callback), None::<bool>,
}) &mut button_db.clone(),
.collect() )
}) .await
.collect(), }
}); }
}))
.await
.into_iter()
.collect::<Result<_, _>>()
}))
.await
.into_iter()
.collect::<Result<_, _>>()
});
let buttons = match buttons {
Some(b) => Some(InlineKeyboardMarkup {
inline_keyboard: b.await?,
}),
None => None,
};
let literal = bm.literal().map_or("", |s| s.as_str()); let literal = bm.literal().map_or("", |s| s.as_str());
let (chat_id, msg_id) = { let (chat_id, msg_id) = {