From 4f768b109a4f5d5ac465d189a7696896244157ea Mon Sep 17 00:00:00 2001 From: Pakin Date: Tue, 21 Apr 2026 15:52:20 +0700 Subject: [PATCH] update: - sheet api - wip resolver Signed-off-by: Pakin --- src/main.rs | 111 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 037456b..8bd61ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,6 +58,7 @@ pub struct DevConfig { api_domain: String, api_recipe_service: String, api_redis_url: String, + api_resolver: String, } impl DevConfig { @@ -66,12 +67,14 @@ impl DevConfig { domain: String, rp_service: String, api_redis_url: String, + api_resolver: String, ) -> DevConfig { DevConfig { api_key: key, api_domain: domain, api_recipe_service: rp_service, api_redis_url, + api_resolver, } } @@ -86,6 +89,10 @@ impl DevConfig { pub fn get_api_header(&self) -> (String, String) { ("X-API-Key".to_string(), self.api_key.clone()) } + + pub fn get_yuki_resolver(&self) -> String { + format!("{}/resolve", self.api_resolver) + } } // async fn test_send(dev_cfg: DevConfig) -> Result<(), Box> { @@ -258,7 +265,7 @@ async fn fetch_content_from_redis_byte(redis: redis::Client, key: &str) -> Resul } } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Clone)] struct WebsocketMessageRequest { #[serde(rename = "type")] type_w: String, @@ -289,6 +296,23 @@ struct CommandRequestPayload { values: serde_json::Value, } +#[derive(Debug, Serialize, Deserialize, Clone)] +struct LogReportPayload { + // expect either `email` or `unknown` + user: String, + action: String, + // expect either country name or `unknown dep` + country: String, + values: serde_json::Value, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +struct SaveRecipePayload { + user: String, + country: String, + values: serde_json::Value, +} + fn convert_ack_command(cmd_req: &serde_json::Value) -> Option { match serde_json::from_value(cmd_req.clone()) { Ok(req) => Some(req), @@ -323,6 +347,7 @@ async fn read( match msg { Message::Text(t) => { let req: WebsocketMessageRequest = serde_json::from_str(t.as_str())?; + let req_clone = req.clone(); match req.type_w.as_str() { "recipe" if req.payload.is_some() => { // guard expect value @@ -532,6 +557,76 @@ async fn read( "heartbeat" => { *last_seen.lock().await = Instant::now(); } + "sheet" if let Some(sheet_req) = req.payload => { + // CommandRequestPayload struct-like + + let payload_sheet_request: CommandRequestPayload = + match serde_json::from_value(sheet_req) { + Ok(sreq) => sreq, + Err(e) => { + error!("error deserialize body sheet request: {e:?} ---> Skip"); + continue; + } + }; + + info!( + "get sheet request: {}, {:?}", + payload_sheet_request.srv_name, payload_sheet_request + ); + + let parameters = payload_sheet_request + .values + .get("param") + .unwrap_or_default(); + + let ch_target = if let Some(pm) = parameters.as_str() { + match pm { + "get_all_catalogs" => "catalogs", + "get_catalog" | "enter" => "enter", + "heartbeat" => "heartbeat", + _ => "junk", + } + } else { + "junk" + }; + + let channel = format!("{}/{}", payload_sheet_request.srv_name, ch_target); + info!("publishing to {channel}"); + + let mut rcl = redis.clone(); + let pub_res = rcl.publish( + channel, + serde_json::to_string(&req_clone.clone()).unwrap_or("{}".to_string()), + ); + + if let Err(e) = pub_res { + error!("error on publish result cmd: {e:?}"); + } + } + "log_report" if let Some(log_payload) = req.payload => { + let log_report_payload: LogReportPayload = + match serde_json::from_value(log_payload) { + Ok(lreq) => lreq, + Err(e) => { + error!("error deserialize body log request: {e:?} ---> Skip"); + continue; + } + }; + // generate timestamp + // + let now = Instant::now(); + } + "save_recipe" if let Some(save_recipe_payload) = req.payload => { + let save_recipe_payload: SaveRecipePayload = + match serde_json::from_value(save_recipe_payload) { + Ok(lreq) => lreq, + Err(e) => { + error!("error deserialize body log request: {e:?} ---> Skip"); + continue; + } + }; + } + _ => { // not implemented } @@ -756,7 +851,10 @@ impl AppState { if pending_command.len() < 10 { pending_command.push_back(fail_payload) } else { - let user_name = fail_payload.user_info.get("name").unwrap_or_default(); + let user_name = fail_payload + .user_info + .get("displayName") + .unwrap_or_default(); let _ = tx_new.send(serde_json::json!({ "type": "notify", @@ -840,11 +938,11 @@ impl AppState { #[tokio::main] async fn main() -> Result<(), Box> { - println!("Hello, world!"); - //println!("{}", include_str!("main.rs")); dotenv::dotenv().ok(); - env_logger::init(); + env_logger::builder() + .filter_level(log::LevelFilter::Info) + .init(); // send req to repo service let server_port = env::var("PORT").unwrap_or("36579".to_string()); @@ -856,11 +954,14 @@ async fn main() -> Result<(), Box> { let api_redis = env::var("DEV_API_REDIS").unwrap_or("0.0.0.0".to_string()); let api_redis_port = env::var("DEV_API_REDIS_PORT").unwrap_or("6379".to_string()); + let api_resolver = env::var("RESOLVER_SERVICE_URL").expect("no available resolver"); + let dev_cfg = DevConfig::new( api_key, api_domain, api_recipe_service, format!("redis://{api_redis}:{api_redis_port}"), + api_resolver, ); // test_send(dev_cfg).await?;