From 9dfa7c52d9bb538db7ad270a83053ef5d2198ab9 Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 21:48:47 +0500 Subject: [PATCH 01/19] add field created_at to db::Message struct --- src/db/mod.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/db/mod.rs b/src/db/mod.rs index 508bdbe..f78eb2c 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -7,7 +7,7 @@ pub mod raw_calls; use std::time::Duration; use async_trait::async_trait; -use chrono::{DateTime, Utc}; +use chrono::{DateTime, FixedOffset, Local, Utc}; use enum_stringify::EnumStringify; use futures::stream::TryStreamExt; @@ -108,6 +108,7 @@ pub struct Message { pub message_id: i64, pub token: String, pub variant: Option, + pub created_at: DateTime, } #[derive(Serialize, Deserialize)] @@ -343,7 +344,10 @@ pub trait CallDB { "message_id": messageid as i64 }, doc! { - "$set": { "token": literal } + "$set": { + "token": literal, + "created_at": Into::>::into(Local::now()), + } }, ) .upsert(true) @@ -369,7 +373,11 @@ pub trait CallDB { "message_id": messageid as i64 }, doc! { - "$set": { "token": literal, "variant": variant } + "$set": { + "token": literal, + "variant": variant, + "created_at": Into::>::into(Local::now()), + } }, ) .upsert(true) From f58f559f8d27721d09424f628e48a60f5706fae0 Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 22:21:14 +0500 Subject: [PATCH 02/19] create BotMessage.meta flag --- src/botscript.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/botscript.rs b/src/botscript.rs index 63231f6..ce890af 100644 --- a/src/botscript.rs +++ b/src/botscript.rs @@ -499,6 +499,10 @@ pub struct BotMessage { buttons: Option, state: Option, + /// flag options to command is meta, so it will be appended to user.metas in db + #[serde(default)] + meta: bool, + handler: Option, } @@ -517,6 +521,10 @@ impl BotMessage { pub fn get_handler(&self) -> Option<&BotFunction> { self.handler.as_ref() } + + pub fn meta(&self) -> bool { + self.meta + } } impl BotMessage { From 3b4ab9b4816d03d42d75bf75675207880492ea0d Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 22:21:44 +0500 Subject: [PATCH 03/19] implement usage of BotMessage.meta flag in handle_botmessage --- src/bot_handler.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/bot_handler.rs b/src/bot_handler.rs index 39fd973..1e09919 100644 --- a/src/bot_handler.rs +++ b/src/bot_handler.rs @@ -17,7 +17,7 @@ use crate::{ commands::BotCommand, db::{CallDB, DB}, message_answerer::MessageAnswerer, - update_user_tg, BotError, BotResult, BotRuntime, + notify_admin, update_user_tg, BotError, BotResult, BotRuntime, }; pub type BotHandler = @@ -69,6 +69,20 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - let user = update_user_tg(user, &tguser); user.update_user(&mut db).await?; + if bm.meta() == true { + let meta = match BotCommand::from_str(msg.text().unwrap_or("")) { + Ok(cmd) => cmd.args().map(|m| m.to_string()), + Err(err) => { + notify_admin(&format!("Error while parsing cmd in `meta`, possibly meta is set not in command, err: {err}")).await; + None + } + }; + + if let Some(meta) = meta { + user.insert_meta(&mut db, &meta).await?; + } + } + let is_propagate: bool = match bm.get_handler() { Some(handler) => 'prop: { let ctx = match handler.context() { From b202f385feea35929355f3da4899b195535f8168 Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 22:33:55 +0500 Subject: [PATCH 04/19] fix: make BotMessage.fill_literal consuming self --- src/botscript.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/botscript.rs b/src/botscript.rs index ce890af..d081842 100644 --- a/src/botscript.rs +++ b/src/botscript.rs @@ -507,10 +507,10 @@ pub struct BotMessage { } impl BotMessage { - pub fn fill_literal(&self, l: String) -> Self { + pub fn fill_literal(self, l: String) -> Self { BotMessage { literal: self.clone().literal.or(Some(l)), - ..self.clone() + ..self } } From 303dbfdaa8f005557af4c7a5d82c270fda4146f8 Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 22:35:51 +0500 Subject: [PATCH 05/19] make BotMessage.meta optional --- src/botscript.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/botscript.rs b/src/botscript.rs index d081842..b0ec98a 100644 --- a/src/botscript.rs +++ b/src/botscript.rs @@ -500,8 +500,7 @@ pub struct BotMessage { state: Option, /// flag options to command is meta, so it will be appended to user.metas in db - #[serde(default)] - meta: bool, + meta: Option, handler: Option, } @@ -523,7 +522,7 @@ impl BotMessage { } pub fn meta(&self) -> bool { - self.meta + self.meta.unwrap_or(false) } } From 4103c5dfbe00e55f987e77f01ea7cba0163eefa0 Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 22:36:30 +0500 Subject: [PATCH 06/19] create BotMessage.update_defaults method for some logic for default values --- src/botscript.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/botscript.rs b/src/botscript.rs index b0ec98a..04d3ac5 100644 --- a/src/botscript.rs +++ b/src/botscript.rs @@ -513,6 +513,24 @@ impl BotMessage { } } + /// chain of modifications on BotMessage + pub fn update_defaults(self) -> Self { + let bm = self; + // if message is `start`, defaulting meta to true, if not set + let bm = match bm.meta { + Some(_) => bm, + None => match &bm.literal { + Some(l) if l == "start" => Self { + meta: Some(true), + ..bm + }, + _ => bm, + }, + }; + + bm + } + pub fn is_replace(&self) -> bool { self.replace } @@ -868,7 +886,7 @@ impl RunnerConfig { pub fn get_command_message(&self, command: &str) -> Option { let bm = self.dialog.commands.get(command).cloned(); - bm.map(|bm| bm.fill_literal(command.to_string())) + bm.map(|bm| bm.fill_literal(command.to_string()).update_defaults()) } pub fn get_callback_message(&self, callback: &str) -> Option { From c301b72f0cfa08ffc4b55d77a9fe82b66d0b107e Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 22:56:52 +0500 Subject: [PATCH 07/19] create MessageVariant --- src/botscript.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/botscript.rs b/src/botscript.rs index 04d3ac5..a1c99e5 100644 --- a/src/botscript.rs +++ b/src/botscript.rs @@ -501,10 +501,32 @@ pub struct BotMessage { /// flag options to command is meta, so it will be appended to user.metas in db meta: Option, + variants: Vec, handler: Option, } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct MessageVariant(String); + +impl MessageVariant { + pub fn get_name(&self) -> &str { + &self.0 + } +} + +impl PartialEq for &MessageVariant { + fn eq(&self, other: &String) -> bool { + self.0 == *other + } +} + +impl PartialEq<&str> for &MessageVariant { + fn eq(&self, other: &&str) -> bool { + self.0 == *other + } +} + impl BotMessage { pub fn fill_literal(self, l: String) -> Self { BotMessage { @@ -542,6 +564,10 @@ impl BotMessage { pub fn meta(&self) -> bool { self.meta.unwrap_or(false) } + + pub fn variants(&self) -> &[MessageVariant] { + &self.variants + } } impl BotMessage { From 50e2d6e824d4b6db99139161a63081d95d8b9823 Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 22:59:12 +0500 Subject: [PATCH 08/19] use variants of messages --- src/bot_handler.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/bot_handler.rs b/src/bot_handler.rs index 1e09919..a96af0e 100644 --- a/src/bot_handler.rs +++ b/src/bot_handler.rs @@ -69,7 +69,7 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - let user = update_user_tg(user, &tguser); user.update_user(&mut db).await?; - if bm.meta() == true { + let variant = if bm.meta() == true { let meta = match BotCommand::from_str(msg.text().unwrap_or("")) { Ok(cmd) => cmd.args().map(|m| m.to_string()), Err(err) => { @@ -78,10 +78,14 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - } }; - if let Some(meta) = meta { - user.insert_meta(&mut db, &meta).await?; - } - } + if let Some(ref meta) = meta { + user.insert_meta(&mut db, meta).await?; + }; + + meta + } else { + None + }; let is_propagate: bool = match bm.get_handler() { Some(handler) => 'prop: { @@ -143,7 +147,8 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - let literal = bm.literal().map_or("", |s| s.as_str()); let ma = MessageAnswerer::new(&bot, &mut db, msg.chat.id.0); - ma.answer(literal, None, buttons).await?; + ma.answer(literal, variant.as_ref().map(|v| v.as_str()), buttons) + .await?; Ok(()) } From 8a3e8c470543ea43622dcaa1a8c23c908f23d20e Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 22:59:28 +0500 Subject: [PATCH 09/19] filter variant to use only defined in runtime config --- src/bot_handler.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/bot_handler.rs b/src/bot_handler.rs index a96af0e..c5998c4 100644 --- a/src/bot_handler.rs +++ b/src/bot_handler.rs @@ -87,6 +87,16 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - None }; + // Filtering to use only defined variants + let variant = match bm + .variants() + .iter() + .any(|v| v == variant.as_ref().map_or("", |v| v)) + { + true => variant, + false => None, + }; + let is_propagate: bool = match bm.get_handler() { Some(handler) => 'prop: { let ctx = match handler.context() { From 6d017b1993201e844b012475d922b28585e56b60 Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 23:12:34 +0500 Subject: [PATCH 10/19] fix: provide default serde value for BotMessage.variants --- src/botscript.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/botscript.rs b/src/botscript.rs index a1c99e5..85dfa68 100644 --- a/src/botscript.rs +++ b/src/botscript.rs @@ -501,6 +501,7 @@ pub struct BotMessage { /// flag options to command is meta, so it will be appended to user.metas in db meta: Option, + #[serde(default)] variants: Vec, handler: Option, From 5669de716a42179f77b3904a28ffb47f475ded41 Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 23:13:39 +0500 Subject: [PATCH 11/19] create MessageInfo and MessageInfoBuilder --- src/botscript.rs | 1 + src/botscript/message_info.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/botscript/message_info.rs diff --git a/src/botscript.rs b/src/botscript.rs index 85dfa68..2fe5068 100644 --- a/src/botscript.rs +++ b/src/botscript.rs @@ -1,5 +1,6 @@ pub mod application; pub mod db; +pub mod message_info; use std::collections::HashMap; use std::sync::{Arc, Mutex, PoisonError}; use std::time::Duration; diff --git a/src/botscript/message_info.rs b/src/botscript/message_info.rs new file mode 100644 index 0000000..36dcdd9 --- /dev/null +++ b/src/botscript/message_info.rs @@ -0,0 +1,27 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Default, Debug, Clone)] +pub struct MessageInfo { + variant: Option, +} + +pub struct MessageInfoBuilder { + inner: MessageInfo, +} + +impl MessageInfoBuilder { + pub fn new() -> Self { + Self { + inner: Default::default(), + } + } + + pub fn set_variant(mut self, variant: Option) -> Self { + self.inner.variant = variant; + self + } + + pub fn build(self) -> MessageInfo { + self.inner + } +} From 2662a0077650c42a4788f5961059ee7ef5699363 Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 5 Jun 2025 23:14:05 +0500 Subject: [PATCH 12/19] provide MessageInfo to BotMessage's handler --- src/bot_handler.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/bot_handler.rs b/src/bot_handler.rs index c5998c4..d489287 100644 --- a/src/bot_handler.rs +++ b/src/bot_handler.rs @@ -13,7 +13,7 @@ use teloxide::{ }; use crate::{ - botscript::{self, BotMessage, RunnerConfig}, + botscript::{self, message_info::MessageInfoBuilder, BotMessage, RunnerConfig}, commands::BotCommand, db::{CallDB, DB}, message_answerer::MessageAnswerer, @@ -105,12 +105,16 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - None => break 'prop true, }; let jsuser = to_js(ctx, &tguser).unwrap(); + let mi = MessageInfoBuilder::new() + .set_variant(variant.clone()) + .build(); + let mi = to_js(ctx, &mi).unwrap(); info!( "Calling handler {:?} with msg literal: {:?}", handler, bm.literal() ); - match handler.call_args(vec![jsuser]) { + match handler.call_args(vec![jsuser, mi]) { Ok(v) => { if v.is_bool() { v.to_bool().unwrap_or(true) @@ -181,12 +185,14 @@ async fn handle_callback(bot: Bot, mut db: DB, bm: BotMessage, q: CallbackQuery) None => break 'prop true, }; let jsuser = to_js(ctx, &tguser).unwrap(); + let mi = MessageInfoBuilder::new().build(); + let mi = to_js(ctx, &mi).unwrap(); println!( "Calling handler {:?} with msg literal: {:?}", handler, bm.literal() ); - match handler.call_args(vec![jsuser]) { + match handler.call_args(vec![jsuser, mi]) { Ok(v) => { println!("Ok branch, got value: {v:?}"); if v.is_bool() { From 2e356ac06749eefb25617b46f60aa67657d9f5ec Mon Sep 17 00:00:00 2001 From: Akulij Date: Fri, 6 Jun 2025 00:19:37 +0500 Subject: [PATCH 13/19] make BotMessage's handler to recursively generate BotMessage --- src/bot_handler.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/bot_handler.rs b/src/bot_handler.rs index d489287..f1c3e04 100644 --- a/src/bot_handler.rs +++ b/src/bot_handler.rs @@ -1,5 +1,5 @@ use log::{error, info}; -use quickjs_rusty::serde::to_js; +use quickjs_rusty::serde::{from_js, to_js}; use std::{ str::FromStr, sync::{Arc, Mutex, RwLock}, @@ -120,6 +120,23 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - v.to_bool().unwrap_or(true) } else if v.is_int() { v.to_int().unwrap_or(1) != 0 + } else if v.is_object() { + if let Ok(obj) = v.try_into_object() { + if let Ok(bm) = from_js::<'_, BotMessage>(obj.context(), &obj) { + Box::pin(handle_botmessage( + bot.clone(), + db.clone(), + bm, + msg.clone(), + )) + .await + .is_err() + } else { + true + } + } else { + true + } } else { // falling back to propagation true @@ -199,6 +216,18 @@ async fn handle_callback(bot: Bot, mut db: DB, bm: BotMessage, q: CallbackQuery) v.to_bool().unwrap_or(true) } else if v.is_int() { v.to_int().unwrap_or(1) != 0 + } else if v.is_object() { + if let Ok(obj) = v.try_into_object() { + if let Ok(bm) = from_js::<'_, BotMessage>(obj.context(), &obj) { + Box::pin(handle_callback(bot.clone(), db.clone(), bm, q.clone())) + .await + .is_err() + } else { + true + } + } else { + true + } } else { // falling back to propagation true From 0bc7978c99a75d27bba6c912e39248b7142c4134 Mon Sep 17 00:00:00 2001 From: Akulij Date: Fri, 6 Jun 2025 01:35:25 +0500 Subject: [PATCH 14/19] fix deserialization Message's created_at --- src/db/mod.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/db/mod.rs b/src/db/mod.rs index f78eb2c..df2f41e 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -12,6 +12,7 @@ use enum_stringify::EnumStringify; use futures::stream::TryStreamExt; use futures::StreamExt; +use mongodb::bson::serde_helpers::chrono_datetime_as_bson_datetime; use mongodb::options::IndexOptions; use mongodb::{bson::doc, options::ClientOptions, Client}; use mongodb::{Collection, Database, IndexModel}; @@ -108,7 +109,8 @@ pub struct Message { pub message_id: i64, pub token: String, pub variant: Option, - pub created_at: DateTime, + #[serde(with = "chrono_datetime_as_bson_datetime")] + pub created_at: DateTime, } #[derive(Serialize, Deserialize)] @@ -346,7 +348,7 @@ pub trait CallDB { doc! { "$set": { "token": literal, - "created_at": Into::>::into(Local::now()), + "created_at": Into::>::into(Local::now()), } }, ) @@ -376,7 +378,7 @@ pub trait CallDB { "$set": { "token": literal, "variant": variant, - "created_at": Into::>::into(Local::now()), + "created_at": Into::>::into(Local::now()), } }, ) From 06a65423498011f9963a0bacef49dd663cd425ca Mon Sep 17 00:00:00 2001 From: Akulij Date: Fri, 6 Jun 2025 01:37:03 +0500 Subject: [PATCH 15/19] change design of variants implementation in BotConfig --- src/botscript.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/botscript.rs b/src/botscript.rs index 2fe5068..97deab2 100644 --- a/src/botscript.rs +++ b/src/botscript.rs @@ -502,8 +502,6 @@ pub struct BotMessage { /// flag options to command is meta, so it will be appended to user.metas in db meta: Option, - #[serde(default)] - variants: Vec, handler: Option, } @@ -566,10 +564,6 @@ impl BotMessage { pub fn meta(&self) -> bool { self.meta.unwrap_or(false) } - - pub fn variants(&self) -> &[MessageVariant] { - &self.variants - } } impl BotMessage { @@ -642,6 +636,7 @@ pub struct BotDialog { pub commands: HashMap, pub buttons: HashMap, stateful_msg_handlers: HashMap, + variants: HashMap>, } impl Parcelable for BotDialog { From 591244b5a1c3240a96f3d35e98bc15d0cded4665 Mon Sep 17 00:00:00 2001 From: Akulij Date: Fri, 6 Jun 2025 01:37:35 +0500 Subject: [PATCH 16/19] craate getter for varianted commands --- src/botscript.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/botscript.rs b/src/botscript.rs index 97deab2..7bf6f78 100644 --- a/src/botscript.rs +++ b/src/botscript.rs @@ -912,6 +912,28 @@ impl RunnerConfig { bm.map(|bm| bm.fill_literal(command.to_string()).update_defaults()) } + pub fn get_command_message_varianted( + &self, + command: &str, + variant: &str, + ) -> Option { + if !self.dialog.commands.contains_key(command) { + return None; + } + // fallback to regular if not found + let bm = match self.dialog.variants.get(command).cloned() { + Some(bm) => bm, + None => return self.get_command_message(command), + }; + // get variant of message + let bm = match bm.get(variant).cloned() { + Some(bm) => bm, + None => return self.get_command_message(command), + }; + + Some(bm.fill_literal(command.to_string()).update_defaults()) + } + pub fn get_callback_message(&self, callback: &str) -> Option { let bm = self.dialog.buttons.get(callback).cloned(); From b114c80097782f3585c3c2061313890923609b50 Mon Sep 17 00:00:00 2001 From: Akulij Date: Fri, 6 Jun 2025 01:38:22 +0500 Subject: [PATCH 17/19] update handling of varianted messages --- src/bot_handler.rs | 66 +++++++++------------------------------------- 1 file changed, 12 insertions(+), 54 deletions(-) diff --git a/src/bot_handler.rs b/src/bot_handler.rs index f1c3e04..b373dc6 100644 --- a/src/bot_handler.rs +++ b/src/bot_handler.rs @@ -38,7 +38,11 @@ pub fn script_handler(r: Arc>) -> BotHandler { let r = r.lock().expect("RwLock lock on commands map failed"); let rc = &r.rc; - rc.get_command_message(command) + // it's not necessary, but avoiding some hashmap lookups + match bc.args() { + Some(variant) => rc.get_command_message_varianted(command, variant), + None => rc.get_command_message(command), + } }) .endpoint(handle_botmessage), ) @@ -69,32 +73,15 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - let user = update_user_tg(user, &tguser); user.update_user(&mut db).await?; - let variant = if bm.meta() == true { - let meta = match BotCommand::from_str(msg.text().unwrap_or("")) { - Ok(cmd) => cmd.args().map(|m| m.to_string()), - Err(err) => { - notify_admin(&format!("Error while parsing cmd in `meta`, possibly meta is set not in command, err: {err}")).await; - None - } - }; - - if let Some(ref meta) = meta { - user.insert_meta(&mut db, meta).await?; - }; - - meta - } else { - None + let variant = match BotCommand::from_str(msg.text().unwrap_or("")) { + Ok(cmd) => cmd.args().map(|m| m.to_string()), + Err(_) => None, }; - // Filtering to use only defined variants - let variant = match bm - .variants() - .iter() - .any(|v| v == variant.as_ref().map_or("", |v| v)) - { - true => variant, - false => None, + if bm.meta() == true { + if let Some(ref meta) = variant { + user.insert_meta(&mut db, meta).await?; + }; }; let is_propagate: bool = match bm.get_handler() { @@ -120,23 +107,6 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - v.to_bool().unwrap_or(true) } else if v.is_int() { v.to_int().unwrap_or(1) != 0 - } else if v.is_object() { - if let Ok(obj) = v.try_into_object() { - if let Ok(bm) = from_js::<'_, BotMessage>(obj.context(), &obj) { - Box::pin(handle_botmessage( - bot.clone(), - db.clone(), - bm, - msg.clone(), - )) - .await - .is_err() - } else { - true - } - } else { - true - } } else { // falling back to propagation true @@ -216,18 +186,6 @@ async fn handle_callback(bot: Bot, mut db: DB, bm: BotMessage, q: CallbackQuery) v.to_bool().unwrap_or(true) } else if v.is_int() { v.to_int().unwrap_or(1) != 0 - } else if v.is_object() { - if let Ok(obj) = v.try_into_object() { - if let Ok(bm) = from_js::<'_, BotMessage>(obj.context(), &obj) { - Box::pin(handle_callback(bot.clone(), db.clone(), bm, q.clone())) - .await - .is_err() - } else { - true - } - } else { - true - } } else { // falling back to propagation true From a869362bf55b2cc8dfc1107156d5fbaaf8db231d Mon Sep 17 00:00:00 2001 From: Akulij Date: Fri, 6 Jun 2025 01:51:27 +0500 Subject: [PATCH 18/19] notify admin when literal not found instead of silently failing --- src/botscript.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/botscript.rs b/src/botscript.rs index 7bf6f78..1000e77 100644 --- a/src/botscript.rs +++ b/src/botscript.rs @@ -7,6 +7,7 @@ use std::time::Duration; use crate::db::raw_calls::RawCallError; use crate::db::{CallDB, DbError, User, DB}; +use crate::notify_admin; use crate::utils::parcelable::{ParcelType, Parcelable, ParcelableError, ParcelableResult}; use chrono::{DateTime, Days, NaiveTime, ParseError, TimeDelta, Timelike, Utc}; use db::attach_db_obj; @@ -477,9 +478,12 @@ impl ButtonName { Ok(match value { Some(value) => Ok(value), - None => Err(ResolveError::IncorrectLiteral(format!( - "not found literal `{literal}` in DB" - ))), + None => { + notify_admin(&format!("Literal `{literal}` is not set!!!")).await; + Err(ResolveError::IncorrectLiteral(format!( + "not found literal `{literal}` in DB" + ))) + } }?) } } From 37d2480b4af044fe022d46f7512a8a6c97fa3ca3 Mon Sep 17 00:00:00 2001 From: Akulij Date: Fri, 6 Jun 2025 01:52:18 +0500 Subject: [PATCH 19/19] update mainbot.js --- mainbot.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/mainbot.js b/mainbot.js index 693892e..2b97256 100644 --- a/mainbot.js +++ b/mainbot.js @@ -13,7 +13,10 @@ const start_msg = { }; const dialog = { commands: { - start: start_msg, + start: { + meta: true, + ...start_msg + }, }, buttons: { more_info: { @@ -41,6 +44,17 @@ const dialog = { state: "none" }, }, + variants: { + start: { + free_tgads: { + ...start_msg, + buttons: [ + [{ name: { literal: "free_doc_btn" }, callback_name: "free_doc" }], + ...start_msg.buttons, + ], + }, + }, + }, } function leave_application(user) {