use crate::error::TikTokApiError;
use reqwest::Client;
use super::{
ListVideoRequest, ListVideoResponse, QueryVideoRequest, QueryVideoResponse,
UserVideoListPostResponseData, Video, VideoField, VideoFilters,
};
pub struct Service {
base_url: String,
}
impl Service {
pub fn new() -> Self {
Self {
base_url: String::from("https://open.tiktokapis.com"),
}
}
pub fn with_base_url(mut self, base_url: &str) -> Self {
self.base_url = base_url.into();
self
}
pub async fn query_videos(
&self,
access_token: &str,
video_ids: Vec<String>,
fields: Vec<VideoField>,
) -> Result<Vec<Video>, TikTokApiError> {
let client = Client::new();
let url = format!("{}/v2/video/query/", self.base_url);
let fields_str = fields
.iter()
.map(|f| f.as_str())
.collect::<Vec<_>>()
.join(",");
let request_body = QueryVideoRequest {
filters: VideoFilters { video_ids },
};
let response = client
.post(&url)
.query(&[("fields", fields_str)])
.header("Authorization", format!("Bearer {}", access_token))
.header("Content-Type", "application/json")
.json(&request_body)
.send()
.await
.map_err(|e| TikTokApiError::RequestFailed(e.to_string()))?;
let status = response.status();
let body = response
.text()
.await
.map_err(|e| TikTokApiError::ResponseReadFailed(e.to_string()))?;
let query_video_response: QueryVideoResponse =
serde_json::from_str(&body).map_err(|e| TikTokApiError::ParseFailed(e.to_string()))?;
if status.is_success() && query_video_response.error.code == "ok" {
Ok(query_video_response.data.videos)
} else {
Err(TikTokApiError::from(query_video_response.error))
}
}
pub async fn list_videos(
&self,
access_token: &str,
cursor: Option<i64>,
max_count: Option<i32>,
fields: Vec<VideoField>,
) -> Result<UserVideoListPostResponseData, TikTokApiError> {
let client = Client::new();
let url = format!("{}/v2/video/list/", self.base_url);
let fields_str = fields
.iter()
.map(|f| f.as_str())
.collect::<Vec<_>>()
.join(",");
let request_body = ListVideoRequest { cursor, max_count };
let response = client
.post(&url)
.query(&[("fields", fields_str)])
.header("Authorization", format!("Bearer {}", access_token))
.header("Content-Type", "application/json")
.json(&request_body)
.send()
.await
.map_err(|e| TikTokApiError::RequestFailed(e.to_string()))?;
let status = response.status();
let body = response
.text()
.await
.map_err(|e| TikTokApiError::ResponseReadFailed(e.to_string()))?;
let list_video_response: ListVideoResponse =
serde_json::from_str(&body).map_err(|e| TikTokApiError::ParseFailed(e.to_string()))?;
if status.is_success() && list_video_response.error.code == "ok" {
Ok(list_video_response.data)
} else {
Err(TikTokApiError::from(list_video_response.error))
}
}
}