wordlebot/src/helper.rs

100 lines
2.5 KiB
Rust
Raw Normal View History

2023-07-07 16:16:24 +02:00
use lemmy_api_common::{
community::GetCommunity,
lemmy_db_schema::newtypes::CommunityId,
person::{Login, LoginResponse},
sensitive::Sensitive,
};
use reqwest::Client;
use serde_json::Value;
use std::fmt;
static API_VERSION: i32 = 3;
pub fn lemmy_password() -> Result<Sensitive<String>, std::env::VarError> {
Ok(Sensitive::new(std::env::var("LEMMY_PASSWORD")?))
}
pub fn lemmy_user() -> Sensitive<String> {
Sensitive::new(std::env::var("LEMMY_USER").unwrap_or_else(|_| "wordlebot".to_string()))
}
pub fn lemmy_server() -> String {
std::env::var("LEMMY_SERVER").unwrap_or_else(|_| "https://enterprise.lemmy.ml".to_string())
}
pub fn lemmy_community() -> String {
std::env::var("LEMMY_COMMUNITY").unwrap_or_else(|_| "wordle".to_string())
}
pub fn api_url(suffix: &str) -> String {
format!("{}/api/v{}/{}", lemmy_server(), API_VERSION, suffix)
}
#[derive(Debug)]
pub enum WordleError {
ParseFailed,
LoginFailed,
NoNewPostId,
}
impl std::error::Error for WordleError {}
impl fmt::Display for WordleError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Oh no, something bad went down")
}
}
pub async fn get_community_id(
client: &Client,
community_name: String,
) -> Result<CommunityId, Box<dyn std::error::Error>> {
let params = GetCommunity {
name: Some(community_name),
..Default::default()
};
let response = client
.get(api_url("community"))
.query(&params)
.send()
.await?;
let text = response.text().await?;
// Deserializing from GetCommunityResponse would fail with missing field `followers_url` in Community
let data = serde_json::from_str::<Value>(text.as_str())?;
if let Some(id) = data["community_view"]["community"]
.get("id")
.and_then(|v| v.as_i64())
{
return Ok(CommunityId(i32::try_from(id)?));
}
Err(Box::new(WordleError::ParseFailed))
}
pub async fn lemmy_login(client: &Client) -> Result<Sensitive<String>, Box<dyn std::error::Error>> {
println!("Logging in");
let params = Login {
username_or_email: lemmy_user(),
password: lemmy_password()?,
..Default::default()
};
let response = client
.post(api_url("user/login"))
.json(&params)
.send()
.await?;
response.error_for_status_ref()?;
let data = response.json::<LoginResponse>().await?;
if let Some(jwt) = data.jwt {
return Ok(jwt);
}
Err(Box::new(WordleError::LoginFailed))
}