2023-10-03 08:30:59 +00:00
|
|
|
use reqwest::Client as HTTPClient;
|
|
|
|
use serde_json::Value;
|
2023-10-03 13:29:31 +00:00
|
|
|
use std::collections::HashMap;
|
2023-10-03 08:30:59 +00:00
|
|
|
use std::error::Error;
|
|
|
|
use std::env;
|
|
|
|
|
|
|
|
pub async fn get_auth_id(token: &str) -> Result<i32, Box<dyn Error>> {
|
|
|
|
let api_base = env::var("API_BASE")?;
|
|
|
|
let gql = match 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(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)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-10-03 13:29:31 +00:00
|
|
|
async fn get_shout_followers(shout_id: &str) -> Result<Vec<i32>, Box<dyn Error>> {
|
|
|
|
let api_base = env::var("API_BASE")?;
|
|
|
|
let gql = format!(r#"
|
|
|
|
query {{
|
2023-10-03 13:33:32 +00:00
|
|
|
shoutFollowers(shout: {}) {{
|
2023-10-03 13:29:31 +00:00
|
|
|
follower {{
|
|
|
|
id
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
"#, shout_id);
|
|
|
|
let client = reqwest::Client::new();
|
|
|
|
let response = client
|
|
|
|
.post(&api_base)
|
|
|
|
.body(gql)
|
|
|
|
.send()
|
2023-10-03 08:30:59 +00:00
|
|
|
.await?;
|
|
|
|
|
2023-10-03 13:29:31 +00:00
|
|
|
let response_body: serde_json::Value = response.json().await?;
|
|
|
|
|
|
|
|
let ids: Vec<i32> = 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<String, String>) -> Result<bool, &'static str> {
|
|
|
|
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::<Vec<String>>(members_str).unwrap();
|
|
|
|
Ok(members.contains(&listener_id.to_string()))
|
|
|
|
},
|
2023-10-03 13:33:32 +00:00
|
|
|
_ => {
|
|
|
|
eprintln!("unknown payload kind");
|
|
|
|
eprintln!("{:?}", payload);
|
|
|
|
Ok(false)
|
|
|
|
},
|
2023-10-03 13:29:31 +00:00
|
|
|
}
|
|
|
|
},
|
2023-10-03 13:33:32 +00:00
|
|
|
None => {
|
|
|
|
eprintln!("payload has no kind");
|
|
|
|
eprintln!("{:?}", payload);
|
|
|
|
Ok(false)
|
|
|
|
},
|
2023-10-03 13:29:31 +00:00
|
|
|
}
|
2023-10-03 08:30:59 +00:00
|
|
|
}
|