use std::env; use log::{info, warn}; use golgi::{sbot::Keystore, Sbot, api::friends::RelationshipQuery}; pub async fn init_sbot() -> Result { let go_sbot_port = env::var("GO_SBOT_PORT").unwrap_or_else(|_| "8021".to_string()); let keystore = Keystore::GoSbot; let ip_port = Some(format!("127.0.0.1:{}", go_sbot_port)); let net_id = None; Sbot::init(keystore, ip_port, net_id) .await .map_err(|e| e.to_string()) } pub async fn whoami() -> Result { let mut sbort = init_sbot().await?; sbort.whoami().await.map_err(|e| e.to_string()) } pub async fn is_following(public_key_a: &str, public_key_b: &str) -> Result { let mut sbot = init_sbot().await?; let query = RelationshipQuery { source: public_key_a.to_string(), dest: public_key_b.to_string(), }; sbot.friends_is_following(query) .await .map_err(|e| e.to_string()) } pub async fn follow_peer(public_key: &str) -> Result { let mut sbot = init_sbot().await?; sbot.follow(public_key).await.map_err(|e| e.to_string()) } pub async fn unfollow_peer(public_key: &str) -> Result { let mut sbot = init_sbot().await?; sbot.unfollow(public_key).await.map_err(|e| e.to_string()) } pub async fn get_name(public_key: &str) -> Result { let mut sbot = init_sbot().await?; sbot.get_name(public_key).await.map_err(|e| e.to_string()) } pub async fn follow_if_not_following(remote_peer: &str) -> Result<(), String> { info!("Seeing whether we should follow {}", remote_peer); if let Ok(whoami) = whoami().await { match is_following(&whoami, remote_peer).await { Ok(status) if status.as_str() != "true" => { info!("Status: '{}'", status); match follow_peer(remote_peer).await { Ok(_) => { info!("Followed peer {}", &remote_peer); Ok(()) }, Err(e) => { let err_msg = format!("Failed to follow peer {}: {}", remote_peer, e); warn!("{}", err_msg); Err(err_msg) }, } }, Ok(status) if status.as_str() == "true" => { info!("Status: '{}'", status); info!("Already following peer {}. No further action taken", &remote_peer); Ok(()) }, _ => Err("Failed to determine follow status: received unrecognised response from local sbot".to_string()), } } else { let err_msg = String::from("Received an error during `whoami` RPC. Please ensure the go-sbot is running and try again."); warn!("{}", err_msg); Err(err_msg) } } pub async fn unfollow_if_not_following(remote_peer: &str) -> Result<(), String> { info!("Seeing whether we should unfollow {}", remote_peer); if let Ok(whoami) = whoami().await { match is_following(&whoami, remote_peer).await { Ok(status) if status != "true" => { info!("Status: '{}'", status); info!("Already not following peer {}. No further action taken", &remote_peer); Ok(()) }, Ok(status) if status == "true" => { info!("Status: '{}'", status); match unfollow_peer(remote_peer).await { Ok(_) => { info!("Unfollowed peer {}", &remote_peer); Ok(()) }, Err(e) => { let err_msg = format!("Failed to unfollow peer {}: {}", remote_peer, e); warn!("{}", err_msg); Err(err_msg) }, } }, _ => Err("Failed to determine follow status: received unrecognised response from local sbot".to_string()), } } else { let err_msg = String::from("Received an error during `whoami` RPC. Please ensure the go-sbot is running and try again."); warn!("{}", err_msg); Err(err_msg) } }