diff --git a/src/service/auth.rs b/src/service/auth.rs new file mode 100644 index 0000000..52ec5ec --- /dev/null +++ b/src/service/auth.rs @@ -0,0 +1,116 @@ +pub struct Auth { + pub app: crate::app::App, +} + +impl Auth { + pub async fn get_token(&self) -> Result { + let client = reqwest::Client::new(); + let endpoint = String::from("api/v1/service/login"); + let api_url = format!("{}/{endpoint}", self.app.auth_url); + + println!("Url: {api_url:?}"); + + let payload = serde_json::json!({ + "username": &self.app.service_username, + "passphrase": &self.app.service_passphrase, + }); + + println!("Payload: {payload:?}"); + + match client.post(api_url).json(&payload).send().await { + Ok(response) => match response.status() { + reqwest::StatusCode::OK => { + println!("Response: {response:?}"); + match response.text().await { + Ok(val) => match parse_token_response(&val).await { + Ok(login_result) => Ok(login_result), + Err(err) => Err(err), + }, + Err(err) => Err(std::io::Error::other(err)), + } + } + _ => Err(std::io::Error::other("Error getting token")), + }, + Err(err) => Err(std::io::Error::other(err.to_string())), + } + } + + pub async fn get_refresh_token( + &self, + login_result: &textsender_models::token::Login, + ) -> Result { + let client = reqwest::Client::new(); + let endpoint = String::from("api/v1/token/refresh"); + let api_url = format!("{}/{endpoint}", self.app.auth_url); + + println!("Url: {api_url:?}"); + + let payload = serde_json::json!({ + "access_token": login_result.access_token + }); + + match client.post(api_url).json(&payload).send().await { + Ok(response) => match response.status() { + reqwest::StatusCode::OK => { + println!("Response: {response:?}"); + match response.text().await { + Ok(val) => match parse_token_response(&val).await { + Ok(login_result) => Ok(login_result), + Err(err) => Err(err), + }, + Err(err) => Err(std::io::Error::other(err)), + } + } + _ => Err(std::io::Error::other("Error getting token")), + }, + Err(err) => Err(std::io::Error::other(err.to_string())), + } + } +} + +async fn parse_token_response( + response: &str, +) -> Result { + match serde_json::from_str::(response) { + Ok(j) => { + println!("Good"); + let message = &j["message"]; + let data = &j["data"]; + + println!("Message: {message:?}"); + println!("Data: {data:?}"); + match j.get("data") { + Some(serde_json::Value::Array(lrs)) => { + if lrs.is_empty() { + Err(std::io::Error::other("Error response is empty")) + } else { + let lr = lrs[0].clone(); + let ll: textsender_models::token::LoginResult = + match serde_json::from_value(lr) { + Ok(lr) => lr, + Err(err) => { + return Err(std::io::Error::other(err.to_string())); + } + }; + Ok(ll) + } + } + _ => Err(std::io::Error::other("Error parsing response")), + } + } + Err(err) => Err(std::io::Error::other(err.to_string())), + } +} + +pub async fn has_token_expired(token: &textsender_models::token::LoginResult) -> bool { + let now = time::OffsetDateTime::now_utc(); + let expire = match time::OffsetDateTime::from_unix_timestamp(token.expires_in) { + Ok(res) => res, + Err(err) => { + eprintln!("Error: {err:?}"); + return false; + } + }; + + now > expire +} diff --git a/src/service/contact.rs b/src/service/contact.rs new file mode 100644 index 0000000..b452b2e --- /dev/null +++ b/src/service/contact.rs @@ -0,0 +1,64 @@ +pub struct Contact { + pub app: crate::app::App, + pub token: textsender_models::token::LoginResult, +} + +impl Contact { + pub async fn get( + &self, + contact_id: &uuid::Uuid, + ) -> Result, std::io::Error> { + let client = reqwest::Client::new(); + let endpoint = format!("api/v1/contact?id={contact_id}"); + let api_url = format!("{}/{endpoint}", self.app.api_url); + + println!("Url: {api_url:?}"); + + let (key, header) = super::auth_header(&self.token.access_token); + + match client.get(api_url).header(key, header).send().await { + Ok(response) => match response.status() { + reqwest::StatusCode::OK => match response.text().await { + Ok(val) => match parse_response(&val).await { + Ok(login_result) => Ok(login_result), + Err(err) => Err(err), + }, + Err(err) => Err(std::io::Error::other(err)), + }, + _ => Err(std::io::Error::other("Error getting token")), + }, + Err(err) => Err(std::io::Error::other(err.to_string())), + } + } +} + +async fn parse_response( + response: &str, +) -> Result, std::io::Error> { + match serde_json::from_str::(response) { + Ok(j) => match j.get("data") { + Some(serde_json::Value::Array(lrs)) => { + if lrs.is_empty() { + Err(std::io::Error::other("Error response is empty")) + } else { + let mut events: Vec = Vec::new(); + + for event in lrs.iter() { + let ll: textsender_models::contact::Contact = + match serde_json::from_value(event.clone()) { + Ok(lr) => lr, + Err(err) => { + return Err(std::io::Error::other(err.to_string())); + } + }; + events.push(ll); + } + + Ok(events) + } + } + _ => Err(std::io::Error::other("Error parsing response")), + }, + Err(err) => Err(std::io::Error::other(err.to_string())), + } +} diff --git a/src/service/core.rs b/src/service/core.rs index 6de4c83..6953bef 100644 --- a/src/service/core.rs +++ b/src/service/core.rs @@ -51,9 +51,22 @@ impl Service { } }; + let contacts = super::contact::Contact { + app: self.app.clone(), + token: self.token.clone(), + }; let events = events.unwrap_or_default(); for event in events { println!("Event: {event:?}"); + let contact = &match contacts.get(&event.contact_id).await { + Ok(contact) => contact, + Err(err) => { + eprintln!("Error: {err:?}"); + continue; + } + }[0]; + + println!("Contact Id: {:?}", contact.id); } todo!( @@ -69,8 +82,8 @@ impl Service { 2. If there is an item, get the data - Done 3. Evaluate if it is schedulable - Done 4. Get the events and iterate each one - Done - 5. starting with the message - 6. Get the contact + 5. Starting with the message + 6. Get the contact - Done 7. Send the message 8. Record the message event response 9. Add to scheduler diff --git a/src/service/message.rs b/src/service/message.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/service/mod.rs b/src/service/mod.rs index 0095e9d..7c8ac02 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,126 +1,9 @@ +pub mod auth; +pub mod contact; pub mod core; pub mod event; pub mod queue; -pub mod auth { - pub struct Auth { - pub app: crate::app::App, - } - - impl Auth { - pub async fn get_token(&self) -> Result { - let client = reqwest::Client::new(); - let endpoint = String::from("api/v1/service/login"); - let api_url = format!("{}/{endpoint}", self.app.auth_url); - - println!("Url: {api_url:?}"); - - let payload = serde_json::json!({ - "username": &self.app.service_username, - "passphrase": &self.app.service_passphrase, - }); - - println!("Payload: {payload:?}"); - - match client.post(api_url).json(&payload).send().await { - Ok(response) => match response.status() { - reqwest::StatusCode::OK => { - println!("Response: {response:?}"); - match response.text().await { - Ok(val) => match parse_token_response(&val).await { - Ok(login_result) => Ok(login_result), - Err(err) => Err(err), - }, - Err(err) => Err(std::io::Error::other(err)), - } - } - _ => Err(std::io::Error::other("Error getting token")), - }, - Err(err) => Err(std::io::Error::other(err.to_string())), - } - } - - pub async fn get_refresh_token( - &self, - login_result: &textsender_models::token::Login, - ) -> Result { - let client = reqwest::Client::new(); - let endpoint = String::from("api/v1/token/refresh"); - let api_url = format!("{}/{endpoint}", self.app.auth_url); - - println!("Url: {api_url:?}"); - - let payload = serde_json::json!({ - "access_token": login_result.access_token - }); - - match client.post(api_url).json(&payload).send().await { - Ok(response) => match response.status() { - reqwest::StatusCode::OK => { - println!("Response: {response:?}"); - match response.text().await { - Ok(val) => match parse_token_response(&val).await { - Ok(login_result) => Ok(login_result), - Err(err) => Err(err), - }, - Err(err) => Err(std::io::Error::other(err)), - } - } - _ => Err(std::io::Error::other("Error getting token")), - }, - Err(err) => Err(std::io::Error::other(err.to_string())), - } - } - } - - async fn parse_token_response( - response: &str, - ) -> Result { - match serde_json::from_str::(response) { - Ok(j) => { - println!("Good"); - let message = &j["message"]; - let data = &j["data"]; - - println!("Message: {message:?}"); - println!("Data: {data:?}"); - match j.get("data") { - Some(serde_json::Value::Array(lrs)) => { - if lrs.is_empty() { - Err(std::io::Error::other("Error response is empty")) - } else { - let lr = lrs[0].clone(); - let ll: textsender_models::token::LoginResult = - match serde_json::from_value(lr) { - Ok(lr) => lr, - Err(err) => { - return Err(std::io::Error::other(err.to_string())); - } - }; - Ok(ll) - } - } - _ => Err(std::io::Error::other("Error parsing response")), - } - } - Err(err) => Err(std::io::Error::other(err.to_string())), - } - } - - pub async fn has_token_expired(token: &textsender_models::token::LoginResult) -> bool { - let now = time::OffsetDateTime::now_utc(); - let expire = match time::OffsetDateTime::from_unix_timestamp(token.expires_in) { - Ok(res) => res, - Err(err) => { - eprintln!("Error: {err:?}"); - return false; - } - }; - - now > expire - } -} - pub fn auth_header( access_token: &str, ) -> (reqwest::header::HeaderName, reqwest::header::HeaderValue) {