diff --git a/bot/src/bluesky.rs b/bot/src/bluesky.rs index 3e06088..5b39db5 100644 --- a/bot/src/bluesky.rs +++ b/bot/src/bluesky.rs @@ -1,8 +1,10 @@ pub(crate) mod atproto; mod token; -use crate::bluesky::atproto::ATProtoServerCreateSession; +use crate::bluesky::atproto::{ATProtoServerCreateSession, BlobResponse}; use anyhow::anyhow; +use base64::prelude::BASE64_STANDARD; +use base64::Engine; use reqwest::Body; use token::Token; @@ -13,6 +15,7 @@ pub struct BlueSkyClient { } impl BlueSkyClient { + /// Creates a new BlueSky client instance for the given account credentials. pub async fn new(user_handle: &str, user_password: &str) -> Result { let client = reqwest::Client::new(); let server_create_session = ATProtoServerCreateSession { @@ -35,6 +38,7 @@ impl BlueSkyClient { }) } + /// Makes a new tweet. pub async fn post(&mut self, body: T) -> Result<(), anyhow::Error> where T: Into, @@ -62,6 +66,7 @@ impl BlueSkyClient { Ok(()) } + /// Renews the Authentication JWT bearer token using the refresh token. async fn renew_token(&mut self) -> Result<(), anyhow::Error> { let result: Token = self .client @@ -78,4 +83,22 @@ impl BlueSkyClient { self.auth_token = result; Ok(()) } + + /// Uploads an image. + async fn upload_image(&mut self, payload: Vec) -> Result { + let base64_data = BASE64_STANDARD.encode(payload); + Ok(self + .client + .post("https://bsky.social/xrpc/com.atproto.repo.uploadBlob") + .header("Content-Type", "image/png") + .header( + "Authorization", + format!("Bearer {}", self.auth_token.access_jwt), + ) + .body(base64_data) + .send() + .await? + .json() + .await?) + } }