use sfr_types as st;
use crate::Request;
use st::{OauthV2AccessRequest, OauthV2AccessResponse};
use std::collections::HashMap;
#[derive(Clone)]
pub struct Client {
client: reqwest::Client,
token: String,
}
#[derive(Clone)]
pub struct OauthClient {
client: reqwest::Client,
}
impl Client {
pub fn new(client: reqwest::Client, token: String) -> Self {
Self { client, token }
}
pub fn clone_http_client(&self) -> reqwest::Client {
self.client.clone()
}
pub async fn request<R>(&self, request: R) -> Result<R::Response, st::Error>
where
R: Request,
{
request.request(self).await
}
pub async fn upload_file_by_upload_file<M>(
&self,
upload_url: &str,
set: M,
) -> Result<(), st::Error>
where
M: Into<HashMap<String, (&'static str, Vec<u8>)>>,
{
use reqwest::multipart::{Form, Part};
let mut form = Form::new();
for (filename, (mime, bytes)) in set.into().into_iter() {
let part = Part::bytes(bytes)
.file_name(filename.clone())
.mime_str(mime)
.map_err(st::Error::failed_creating_mulipart_data)?;
form = form.part(filename.clone(), part);
}
let response = self
.client()
.post(upload_url)
.multipart(form)
.send()
.await
.map_err(|e| st::Error::failed_to_request_by_http("upload_url", e))?;
tracing::debug!("response = {response:?}");
Ok(())
}
pub(crate) fn client(&self) -> &reqwest::Client {
&self.client
}
pub(crate) fn token(&self) -> &str {
&self.token
}
}
impl OauthClient {
pub fn new(client: reqwest::Client) -> Self {
Self { client }
}
pub async fn oauth_v2_access(
&self,
form: OauthV2AccessRequest<'_>,
) -> Result<OauthV2AccessResponse, st::Error> {
#[allow(clippy::missing_docs_in_private_items)] const URL: &str = "https://slack.com/api/oauth.v2.access";
#[allow(clippy::missing_docs_in_private_items)] const API_CODE: &str = "oauth.v2.access";
tracing::debug!("form = {form:?}");
let response = self
.client
.post(URL)
.form(&form)
.send()
.await
.map_err(|e| st::Error::failed_to_request_by_http(API_CODE, e))?;
tracing::debug!("response = {response:?}");
let body: serde_json::Value = response
.json()
.await
.map_err(|e| st::Error::failed_to_read_json(API_CODE, e))?;
tracing::debug!("body = {body:?}");
body.try_into()
}
}