From ea71e6bfa2bf11cda622be9dd92b50b548773e5f Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 25 Jun 2026 21:19:35 -0400 Subject: [PATCH 1/3] Adding code for getting contact --- src/service/contact.rs | 69 ++++++++++++++++++++++++++++++++++++++++++ src/service/core.rs | 13 ++++++++ src/service/message.rs | 0 src/service/mod.rs | 1 + 4 files changed, 83 insertions(+) create mode 100644 src/service/contact.rs create mode 100644 src/service/message.rs diff --git a/src/service/contact.rs b/src/service/contact.rs new file mode 100644 index 0000000..603e3e6 --- /dev/null +++ b/src/service/contact.rs @@ -0,0 +1,69 @@ +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< + textsender_models::contact::Contact, + > = 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..97441db 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!( 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..fa12fdd 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,3 +1,4 @@ +pub mod contact; pub mod core; pub mod event; pub mod queue; -- 2.47.3 From 95dbe2bf82f6a3b135c1f478853be7f2959921c9 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 25 Jun 2026 21:21:15 -0400 Subject: [PATCH 2/3] cargo fmt --- src/service/contact.rs | 11 +++-------- src/service/core.rs | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/service/contact.rs b/src/service/contact.rs index 603e3e6..b452b2e 100644 --- a/src/service/contact.rs +++ b/src/service/contact.rs @@ -7,11 +7,9 @@ impl Contact { pub async fn get( &self, contact_id: &uuid::Uuid, - ) -> Result, std::io::Error> - { + ) -> Result, std::io::Error> { let client = reqwest::Client::new(); - let endpoint = - format!("api/v1/contact?id={contact_id}"); + let endpoint = format!("api/v1/contact?id={contact_id}"); let api_url = format!("{}/{endpoint}", self.app.api_url); println!("Url: {api_url:?}"); @@ -43,9 +41,7 @@ async fn parse_response( if lrs.is_empty() { Err(std::io::Error::other("Error response is empty")) } else { - let mut events: Vec< - textsender_models::contact::Contact, - > = Vec::new(); + let mut events: Vec = Vec::new(); for event in lrs.iter() { let ll: textsender_models::contact::Contact = @@ -66,4 +62,3 @@ async fn parse_response( Err(err) => Err(std::io::Error::other(err.to_string())), } } - diff --git a/src/service/core.rs b/src/service/core.rs index 97441db..c499703 100644 --- a/src/service/core.rs +++ b/src/service/core.rs @@ -53,7 +53,7 @@ impl Service { let contacts = super::contact::Contact { app: self.app.clone(), - token: self.token.clone() + token: self.token.clone(), }; let events = events.unwrap_or_default(); for event in events { -- 2.47.3 From 74432ee09fbad64ae16410a704466e339c80b134 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 25 Jun 2026 21:36:34 -0400 Subject: [PATCH 3/3] Refactoring code --- src/service/auth.rs | 116 ++++++++++++++++++++++++++++++++++++++++++ src/service/core.rs | 4 +- src/service/mod.rs | 120 +------------------------------------------- 3 files changed, 119 insertions(+), 121 deletions(-) create mode 100644 src/service/auth.rs 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/core.rs b/src/service/core.rs index c499703..6953bef 100644 --- a/src/service/core.rs +++ b/src/service/core.rs @@ -82,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/mod.rs b/src/service/mod.rs index fa12fdd..7c8ac02 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,127 +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) { -- 2.47.3