use reqwest::Client as HTTPClient; use serde_json::Value; use std::collections::HashMap; use std::error::Error; use std::env; pub async fn get_auth_id(token: &str) -> Result> { let auth_api_base = env::var("AUTH_URL")?; let gql = match auth_api_base.contains("v2") { true => r#"mutation { getSession { user { id } } }"#, // v2 _ => r#"query { sessiom { user { id } } }"# // authorizer }; let client = HTTPClient::new(); let response = client .post(auth_api_base) .bearer_auth(token) // NOTE: auth token is here .body(gql) .send() .await?; let response_body: Value = response.json().await?; let id = response_body["data"]["getSession"]["user"]["id"] .as_i64() .ok_or("Failed to get user id by token")? as i32; Ok(id) } async fn get_shout_followers(shout_id: &str) -> Result, Box> { let api_base = env::var("API_BASE")?; let gql = format!(r#" query {{ shoutFollowers(shout: {}) {{ follower {{ id }} }} }} "#, shout_id); let client = reqwest::Client::new(); let response = client .post(&api_base) .body(gql) .send() .await?; let response_body: serde_json::Value = response.json().await?; let ids: Vec = response_body["data"]["shoutFollowers"] .as_array() .ok_or("Failed to parse follower array")? .iter() .filter_map(|f| f["follower"]["id"].as_i64().map(|id| id as i32)) .collect(); Ok(ids) } pub async fn is_fitting(listener_id: i32, payload: HashMap) -> Result { match payload.get("kind") { Some(kind) => { match kind.as_str() { "new_follower" => { // payload is AuthorFollower Ok(payload.get("author").unwrap().to_string() == listener_id.to_string()) }, "new_reaction" => { // payload is Reaction let shout_id = payload.get("shout").unwrap(); let recipients = get_shout_followers(shout_id).await.unwrap(); Ok(recipients.contains(&listener_id)) }, "new_shout" => { // payload is Shout // TODO: check all community subscribers if no then // check all topics subscribers if no then // check all authors subscribers Ok(true) }, "new_message" => { // payload is Chat let members_str = payload.get("members").unwrap(); let members = serde_json::from_str::>(members_str).unwrap(); Ok(members.contains(&listener_id.to_string())) }, _ => { eprintln!("unknown payload kind"); eprintln!("{:?}", payload); Ok(false) }, } }, None => { eprintln!("payload has no kind"); eprintln!("{:?}", payload); Ok(false) }, } }