Compare commits

..

31 Commits

Author SHA1 Message Date
akulij
ff816c4fdc update revision of quickjs-rusty
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m6s
2025-06-02 05:21:45 +00:00
akulij
0ba10a1600 mainbot.js: do not print user
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m25s
2025-06-01 14:01:26 +00:00
akulij
0c94673766 update quickjs-rusty revision 2025-06-01 14:01:08 +00:00
akulij
4aa3cb5080 specify commit for own quickjs-rusty
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m21s
2025-06-01 13:36:25 +00:00
Akulij
af4cad6765 refactor debug prints
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m2s
2025-06-01 17:48:40 +05:00
Akulij
bdc0d6432c print info value returned
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m6s
2025-06-01 17:42:14 +05:00
Akulij
e74f875e3b create /commit command to get commit hash from which this bot was built
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m7s
2025-06-01 17:37:58 +05:00
Akulij
1669327df2 cargo add git-const 2025-06-01 17:37:49 +05:00
Akulij
1e046e2e19 do not use private function of quickjs-rusty
All checks were successful
Build && Deploy / cargo build (push) Successful in 3m32s
2025-06-01 17:07:35 +05:00
Akulij
79acdc283e use my fork of quickjs-rusty
Some checks are pending
Build && Deploy / cargo build (push) Waiting to run
2025-06-01 16:41:04 +05:00
Akulij
97e7886149 resture jsuser as argument 2025-06-01 16:40:41 +05:00
Akulij
585c3599ab exp
Some checks are pending
Build && Deploy / cargo build (push) Waiting to run
2025-06-01 13:53:29 +05:00
Akulij
f08af9609e sdfalkajsdfj
Some checks failed
Build && Deploy / cargo build (push) Failing after 10m46s
2025-06-01 13:39:10 +05:00
12288ced5c Merge pull request 'lsjdf' (#16) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m2s
Reviewed-on: #16
2025-06-01 07:18:44 +00:00
5955fc297d Merge pull request 'use js to string' (#15) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m2s
Reviewed-on: #15
2025-06-01 07:14:29 +00:00
bf816c4c5c Merge pull request 'dev' (#14) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m0s
Reviewed-on: #14
2025-06-01 07:07:17 +00:00
92c97abd4a Merge pull request 'change order of drop for BotController' (#13) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m0s
Reviewed-on: #13
2025-06-01 06:38:48 +00:00
ab3cf214d1 Merge pull request 'fix cd.yaml: build release version' (#12) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m53s
Reviewed-on: #12
2025-06-01 06:17:39 +00:00
a5f02631e8 Merge pull request 'sdafasklj' (#11) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 2m59s
Reviewed-on: #11
2025-06-01 06:03:23 +00:00
e71cde3735 Merge pull request 'more debug info' (#10) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m23s
Reviewed-on: #10
2025-05-31 10:29:38 +00:00
c80fcbe025 Merge pull request 'temporarly use debug version' (#9) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 1m34s
Reviewed-on: #9
2025-05-31 10:23:08 +00:00
7b39cd18cf Merge branch 'main' into dev
Some checks failed
Build && Deploy / cargo build (push) Has been cancelled
2025-05-31 10:22:37 +00:00
a0b22e2ef3 Merge pull request 'more debug info' (#8) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 57s
Reviewed-on: #8
2025-05-31 10:19:34 +00:00
0c1f08a9db Merge pull request 'more debug info' (#7) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 52s
Reviewed-on: #7
2025-05-31 10:14:05 +00:00
40dec27adc Merge pull request 'more debug info' (#6) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 55s
Reviewed-on: #6
2025-05-31 10:06:20 +00:00
1d80fd056b Merge pull request 'temporarly use println' (#5) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 56s
Reviewed-on: #5
2025-05-31 09:58:09 +00:00
62b68a6451 Merge pull request 'more debug info' (#4) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 52s
Reviewed-on: #4
2025-05-31 09:40:50 +00:00
9be1f3ec1d Merge pull request 'set literal for leave_application' (#3) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 57s
Reviewed-on: #3
2025-05-31 09:33:57 +00:00
fe08b42581 Merge branch 'main' into dev
Some checks failed
Build && Deploy / cargo build (push) Has been cancelled
2025-05-31 09:33:34 +00:00
d49971995c Merge pull request 'fix cd.yaml: install clang for quickjs-ng compilation' (#2) from dev into main
All checks were successful
Build && Deploy / cargo build (push) Successful in 51s
Reviewed-on: #2
2025-05-31 09:12:23 +00:00
f7318f3661 Merge pull request 'migration to JS engine' (#1) from dev into main
Some checks failed
Build && Deploy / cargo build (push) Failing after 1m17s
Reviewed-on: #1
2025-05-31 08:49:52 +00:00
7 changed files with 41 additions and 76 deletions

13
Cargo.lock generated
View File

@ -897,6 +897,12 @@ version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "git-const"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4f63cc0cd93d91bcc11b46f61db771bc36c405d96043506ae40facd87b31f7"
[[package]] [[package]]
name = "glob" name = "glob"
version = "0.3.2" version = "0.3.2"
@ -915,6 +921,7 @@ dependencies = [
"enum_stringify", "enum_stringify",
"envconfig", "envconfig",
"futures", "futures",
"git-const",
"itertools 0.14.0", "itertools 0.14.0",
"lazy_static", "lazy_static",
"log", "log",
@ -1463,8 +1470,7 @@ dependencies = [
[[package]] [[package]]
name = "libquickjs-ng-sys" name = "libquickjs-ng-sys"
version = "0.9.0" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/akulij/quickjs-rusty.git?rev=549f830#549f8308b737006098293b2f0a5ff8ed420442b5"
checksum = "3c98c1ad542ec61348faba7ce5386fef9060e35fbeea19dda64ce41862084e0a"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"cc", "cc",
@ -2009,8 +2015,7 @@ dependencies = [
[[package]] [[package]]
name = "quickjs-rusty" name = "quickjs-rusty"
version = "0.9.0" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/akulij/quickjs-rusty.git?rev=549f830#549f8308b737006098293b2f0a5ff8ed420442b5"
checksum = "b3b4d659d1bc37e9112a14ad9a7727d182b0fb12216eb6684bdbada3e9991a22"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",

View File

@ -14,12 +14,13 @@ dotenvy = "0.15.7"
enum_stringify = "0.6.3" enum_stringify = "0.6.3"
envconfig = "0.11.0" envconfig = "0.11.0"
futures = "0.3.31" futures = "0.3.31"
git-const = "1.1.0"
itertools = "0.14.0" itertools = "0.14.0"
lazy_static = "1.5.0" lazy_static = "1.5.0"
log = "0.4.27" log = "0.4.27"
mongodb = "3.2.3" mongodb = "3.2.3"
pretty_env_logger = "0.5.0" pretty_env_logger = "0.5.0"
quickjs-rusty = "0.9.0" quickjs-rusty = { git = "https://github.com/akulij/quickjs-rusty.git", rev = "549f830" }
serde = { version = "1.0.219", features = ["derive", "serde_derive"] } serde = { version = "1.0.219", features = ["derive", "serde_derive"] }
serde_json = "1.0.140" serde_json = "1.0.140"
teloxide = { version = "0.14.0", features = ["macros", "postgres-storage-nativetls"] } teloxide = { version = "0.14.0", features = ["macros", "postgres-storage-nativetls"] }

View File

@ -43,7 +43,6 @@ const dialog = {
function leave_application(user) { function leave_application(user) {
print("point of reach") print("point of reach")
print(JSON.stringify(user))
user_application(user) user_application(user)
return false return false

View File

@ -1,3 +1,4 @@
use git_const::git_hash;
use itertools::Itertools; use itertools::Itertools;
use teloxide::{ use teloxide::{
prelude::*, prelude::*,
@ -44,6 +45,8 @@ pub enum AdminCommands {
Cancel, Cancel,
/// Create new instance of telegram bot /// Create new instance of telegram bot
Deploy { token: String }, Deploy { token: String },
/// Get commit hash of this bot
Commit,
} }
pub async fn admin_command_handler( pub async fn admin_command_handler(
@ -189,6 +192,12 @@ pub async fn admin_command_handler(
.await?; .await?;
Ok(()) Ok(())
} }
AdminCommands::Commit => {
let hash = git_hash!();
bot.send_message(msg.chat.id, format!("Commit: {hash}"))
.await?;
Ok(())
}
} }
} }

View File

@ -2,7 +2,7 @@ use log::{error, info};
use quickjs_rusty::serde::to_js; use quickjs_rusty::serde::to_js;
use std::{ use std::{
str::FromStr, str::FromStr,
sync::{Arc, RwLock}, sync::{Arc, Mutex, RwLock},
}; };
use teloxide::{ use teloxide::{
dispatching::{dialogue::GetChatId, UpdateFilterExt}, dispatching::{dialogue::GetChatId, UpdateFilterExt},
@ -23,7 +23,7 @@ use crate::{
pub type BotHandler = pub type BotHandler =
Handler<'static, DependencyMap, BotResult<()>, teloxide::dispatching::DpHandlerDescription>; Handler<'static, DependencyMap, BotResult<()>, teloxide::dispatching::DpHandlerDescription>;
pub fn script_handler(r: Arc<BotRuntime>) -> BotHandler { pub fn script_handler(r: Arc<Mutex<BotRuntime>>) -> BotHandler {
let cr = r.clone(); let cr = r.clone();
dptree::entry() dptree::entry()
.branch( .branch(
@ -35,7 +35,8 @@ pub fn script_handler(r: Arc<BotRuntime>) -> BotHandler {
let r = std::sync::Arc::clone(&r); let r = std::sync::Arc::clone(&r);
let command = bc.command(); let command = bc.command();
let rc = r.rc.lock().expect("RwLock lock on commands map failed"); let r = r.lock().expect("RwLock lock on commands map failed");
let rc = &r.rc;
rc.get_command_message(command) rc.get_command_message(command)
}) })
@ -46,7 +47,8 @@ pub fn script_handler(r: Arc<BotRuntime>) -> BotHandler {
.filter_map(move |q: CallbackQuery| { .filter_map(move |q: CallbackQuery| {
q.data.and_then(|data| { q.data.and_then(|data| {
let r = std::sync::Arc::clone(&cr); let r = std::sync::Arc::clone(&cr);
let rc = r.rc.lock().expect("RwLock lock on commands map failed"); let r = r.lock().expect("RwLock lock on commands map failed");
let rc = &r.rc;
rc.get_callback_message(&data) rc.get_callback_message(&data)
}) })
@ -155,9 +157,9 @@ async fn handle_callback(bot: Bot, mut db: DB, bm: BotMessage, q: CallbackQuery)
handler, handler,
bm.literal() bm.literal()
); );
match handler.call_args(vec![]) { match handler.call_args(vec![jsuser]) {
Ok(v) => { Ok(v) => {
println!("Ok branch, value: {:?}", v.js_to_string()); println!("Ok branch, got value: {v:?}");
if v.is_bool() { if v.is_bool() {
v.to_bool().unwrap_or(true) v.to_bool().unwrap_or(true)
} else if v.is_int() { } else if v.is_int() {

View File

@ -1,7 +1,7 @@
use std::{ use std::{
collections::HashMap, collections::HashMap,
future::Future, future::Future,
sync::{Arc, RwLock}, sync::{Arc, Mutex, RwLock},
thread::JoinHandle, thread::JoinHandle,
time::Duration, time::Duration,
}; };
@ -14,6 +14,7 @@ use teloxide::{
prelude::{Dispatcher, Requester}, prelude::{Dispatcher, Requester},
Bot, Bot,
}; };
use tokio::runtime::Handle;
use crate::{ use crate::{
bot_handler::{script_handler, BotHandler}, bot_handler::{script_handler, BotHandler},
@ -28,18 +29,11 @@ pub struct BotRunner {
thread: Option<JoinHandle<BotResult<()>>>, thread: Option<JoinHandle<BotResult<()>>>,
} }
unsafe impl Sync for BotRunner {}
unsafe impl Send for BotRunner {}
#[derive(Clone)] #[derive(Clone)]
pub struct BotInfo { pub struct BotInfo {
pub name: String, pub name: String,
} }
lazy_static! {
static ref BOT_POOL: RwLock<HashMap<String, BotRunner>> = RwLock::new(HashMap::new());
}
pub static DEFAULT_SCRIPT: &str = pub static DEFAULT_SCRIPT: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/default_script.js")); include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/default_script.js"));
@ -171,7 +165,10 @@ where
} }
} }
async fn script_handler_gen(r: Arc<BotRuntime>, plug_handlers: Vec<BotHandler>) -> BotHandler { async fn script_handler_gen(
r: Arc<Mutex<BotRuntime>>,
plug_handlers: Vec<BotHandler>,
) -> BotHandler {
let handler = script_handler(r.clone()); let handler = script_handler(r.clone());
// each handler will be added to dptree::entry() // each handler will be added to dptree::entry()
let handler = plug_handlers let handler = plug_handlers
@ -182,48 +179,6 @@ async fn script_handler_gen(r: Arc<BotRuntime>, plug_handlers: Vec<BotHandler>)
handler handler
} }
pub async fn start_bot(
bi: BotInstance,
db: &mut DB,
plug_handlers: Vec<BotHandler>,
) -> BotResult<BotInfo> {
let db = db.clone().with_name(bi.name.clone());
let controller = BotController::with_db(db.clone(), &bi.token, &bi.script).await?;
let handler = script_handler(controller.runtime.clone());
// each handler will be added to dptree::entry()
let handler = plug_handlers
.into_iter()
// as well as the script handler at the end
.chain(std::iter::once(handler))
.fold(dptree::entry(), |h, plug| h.branch(plug));
let thread = spawn_bot_thread(controller.bot.clone(), controller.db.clone(), handler).await?;
let info = BotInfo {
name: bi.name.clone(),
};
let runner = BotRunner {
controller,
info: info.clone(),
thread: Some(thread),
};
BOT_POOL
.write()
.map_or_else(
|err| {
Err(BotError::RwLockError(format!(
"Failed to lock BOT_POOL because previous thread paniced, err: {err}"
)))
},
Ok,
)?
.insert(bi.name.clone(), runner);
Ok(info)
}
pub async fn spawn_bot_thread( pub async fn spawn_bot_thread(
bot: Bot, bot: Bot,
mut db: DB, mut db: DB,
@ -235,9 +190,10 @@ pub async fn spawn_bot_thread(
let thread = std::thread::spawn(move || -> BotResult<()> { let thread = std::thread::spawn(move || -> BotResult<()> {
let state_mgr = state_mgr; let state_mgr = state_mgr;
let rt = tokio::runtime::Builder::new_current_thread() // let rt = tokio::runtime::Builder::new_current_thread()
.enable_all() // .enable_all()
.build()?; // .build()?;
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on( rt.block_on(
Dispatcher::builder(bot, handler) Dispatcher::builder(bot, handler)

View File

@ -104,16 +104,14 @@ type CallbackStore = CallbackInfo<Callback>;
pub struct BotController { pub struct BotController {
pub bot: Bot, pub bot: Bot,
pub db: DB, pub db: DB,
pub runtime: Arc<BotRuntime>, pub runtime: Arc<Mutex<BotRuntime>>,
} }
pub struct BotRuntime { pub struct BotRuntime {
pub rc: Mutex<RunnerConfig>, pub rc: RunnerConfig,
pub runner: Runner, pub runner: Runner,
} }
unsafe impl Send for BotRuntime {} unsafe impl Send for BotRuntime {}
unsafe impl Sync for BotRuntime {}
impl Drop for BotController { impl Drop for BotController {
fn drop(&mut self) { fn drop(&mut self) {
@ -121,8 +119,6 @@ impl Drop for BotController {
} }
} }
unsafe impl Send for BotController {}
const MAIN_BOT_SCRIPT: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/mainbot.js")); const MAIN_BOT_SCRIPT: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/mainbot.js"));
impl BotController { impl BotController {
@ -148,10 +144,7 @@ impl BotController {
let mut runner = Runner::init_with_db(&mut db)?; let mut runner = Runner::init_with_db(&mut db)?;
runner.call_attacher(|c, o| attach_user_application(c, o, &db, &bot))??; runner.call_attacher(|c, o| attach_user_application(c, o, &db, &bot))??;
let rc = runner.init_config(script)?; let rc = runner.init_config(script)?;
let runtime = Arc::new(BotRuntime { let runtime = Arc::new(Mutex::new(BotRuntime { rc, runner }));
rc: Mutex::new(rc),
runner,
});
Ok(Self { bot, db, runtime }) Ok(Self { bot, db, runtime })
} }