/*
* Zernio API
*
* API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema).
*
* The version of the OpenAPI document: 1.68.1
* Contact: support@zernio.com
* Generated by: https://openapi-generator.tech
*/
use super::{configuration, ContentType, Error};
use crate::{apis::ResponseContent, models};
use reqwest;
use serde::{de::Error as _, Deserialize, Serialize};
/// struct for typed errors of method [`delete_account`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum DeleteAccountError {
Status401(models::InlineObject1),
Status404(models::InlineObject2),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_account_health`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetAccountHealthError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(models::InlineObject2),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_account_posts`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetAccountPostsError {
Status400(),
Status401(models::InlineObject1),
Status403(),
Status404(models::InlineObject2),
Status502(models::ErrorResponse),
Status503(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_all_accounts_health`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetAllAccountsHealthError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_bluesky_settings`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetBlueskySettingsError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_follower_stats`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetFollowerStatsError {
Status401(models::InlineObject1),
Status403(models::GetFollowerStats403Response),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_instagram_follow_status`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetInstagramFollowStatusError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(models::InlineObject2),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_slack_settings`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetSlackSettingsError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_tik_tok_creator_info`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetTikTokCreatorInfoError {
Status400(models::GetYouTubeDailyViews400Response),
Status401(models::InlineObject1),
Status404(models::InlineObject2),
Status429(models::GetYouTubeDailyViews400Response),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`list_accounts`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ListAccountsError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status503(models::ErrorResponse),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`list_tik_tok_commercial_music`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ListTikTokCommercialMusicError {
Status400(models::ErrorResponse),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`move_account_to_profile`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum MoveAccountToProfileError {
Status400(),
Status401(models::InlineObject1),
Status403(),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`search_tik_tok_locations`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SearchTikTokLocationsError {
Status400(models::ErrorResponse),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`update_account`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UpdateAccountError {
Status400(),
Status401(models::InlineObject1),
Status404(models::InlineObject2),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`update_bluesky_settings`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UpdateBlueskySettingsError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`update_slack_settings`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UpdateSlackSettingsError {
Status400(models::ErrorResponse),
Status401(models::InlineObject1),
Status404(),
UnknownValue(serde_json::Value),
}
/// Disconnects and removes a connected account. Repeating the call for an account already disconnected returns 404, the account stays in its 1h grace window and the disconnect is not re-run.
pub async fn delete_account(
configuration: &configuration::Configuration,
account_id: &str,
) -> Result<models::DeleteAccountGroup200Response, Error<DeleteAccountError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let uri_str = format!(
"{}/v1/accounts/{accountId}",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::DELETE, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::DeleteAccountGroup200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::DeleteAccountGroup200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<DeleteAccountError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Returns detailed health info for a specific account including token status, permissions, and recommendations. For WhatsApp accounts the response also includes `platformConnection`, a live probe of the Meta link behind the channel (the same read as `GET /v1/whatsapp/number-info`). The OAuth token can be perfectly valid while Meta refuses to serve the phone-number object (for example after a phone-side coexistence disconnect), so `tokenStatus` alone is not a liveness signal for WhatsApp. When the Meta link is dead, `platformConnection.status` is `disconnected` and the overall `status` is `error`.
pub async fn get_account_health(
configuration: &configuration::Configuration,
account_id: &str,
) -> Result<models::GetAccountHealth200Response, Error<GetAccountHealthError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let uri_str = format!(
"{}/v1/accounts/{accountId}/health",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetAccountHealth200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetAccountHealth200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetAccountHealthError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Returns the 25 most recent posts that exist on the platform for a connected account, read live from the platform API. This covers everything on the account, including posts that were never created through Zernio. Use it to obtain the platform's own post id, which the analytics endpoints take as input. On YouTube the returned `id` is the video ID that `GET /v1/analytics/youtube/daily-views`, `/video-retention` and `/demographics` expect as `videoId`, so this endpoint is what backs a video picker in your own UI. Not every field applies to every platform: `reactionCount` is Facebook and LinkedIn, `shareCount` is platform dependent, `cid` is the Bluesky content id needed to reply, and `subreddit` is Reddit only. Absent fields are omitted from the response. The account's token is refreshed before the call when it has expired. When the refresh cannot recover it, the response is a 401 with code `TOKEN_EXPIRED` and the account has to be reconnected.
pub async fn get_account_posts(
configuration: &configuration::Configuration,
account_id: &str,
) -> Result<models::GetAccountPosts200Response, Error<GetAccountPostsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let uri_str = format!(
"{}/v1/accounts/{accountId}/posts",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetAccountPosts200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetAccountPosts200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetAccountPostsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Returns health status of all connected accounts including token validity, permissions, and issues needing attention.
pub async fn get_all_accounts_health(
configuration: &configuration::Configuration,
profile_id: Option<&str>,
platform: Option<&str>,
status: Option<&str>,
) -> Result<models::GetAllAccountsHealth200Response, Error<GetAllAccountsHealthError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_profile_id = profile_id;
let p_query_platform = platform;
let p_query_status = status;
let uri_str = format!("{}/v1/accounts/health", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_query_profile_id {
req_builder = req_builder.query(&[("profileId", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_platform {
req_builder = req_builder.query(&[("platform", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_status {
req_builder = req_builder.query(&[("status", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetAllAccountsHealth200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetAllAccountsHealth200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetAllAccountsHealthError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Returns the account's default post languages (defaultLangs), applied at publish time whenever a post's platformSpecificData.langs is absent. Null when no default is set.
pub async fn get_bluesky_settings(
configuration: &configuration::Configuration,
account_id: &str,
) -> Result<models::GetBlueskySettings200Response, Error<GetBlueskySettingsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let uri_str = format!(
"{}/v1/accounts/{accountId}/bluesky-settings",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetBlueskySettings200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetBlueskySettings200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetBlueskySettingsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Returns follower count history and growth metrics for connected accounts. Requires analytics add-on subscription. Follower counts are refreshed once per day.
pub async fn get_follower_stats(
configuration: &configuration::Configuration,
account_ids: Option<&str>,
profile_id: Option<&str>,
from_date: Option<String>,
to_date: Option<String>,
granularity: Option<&str>,
) -> Result<models::FollowerStatsResponse, Error<GetFollowerStatsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_account_ids = account_ids;
let p_query_profile_id = profile_id;
let p_query_from_date = from_date;
let p_query_to_date = to_date;
let p_query_granularity = granularity;
let uri_str = format!("{}/v1/accounts/follower-stats", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_query_account_ids {
req_builder = req_builder.query(&[("accountIds", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_profile_id {
req_builder = req_builder.query(&[("profileId", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_from_date {
req_builder = req_builder.query(&[("fromDate", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_to_date {
req_builder = req_builder.query(&[("toDate", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_granularity {
req_builder = req_builder.query(&[("granularity", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::FollowerStatsResponse`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::FollowerStatsResponse`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetFollowerStatsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Resolves the follow relationship between an Instagram user and the connected account, plus their public profile counters. `userId` is the Instagram-scoped id (IGSID) Meta gives you on a webhook: `sender.id` on `message.received`, `comment.author.id` on `comment.received`. **Meta only answers for people who have MESSAGED the account.** Commenting grants no consent, so a commenter who has never DMed you is unresolvable - that is a platform rule, not a limitation of this endpoint. When it cannot be resolved the response is still `200` with `isFollower: null` and an `unavailableReason`, because \"unknown\" is a normal state to branch on: * `consent_required` - the user has never messaged this account. * `dm_access_disabled` - the account owner turned off Instagram Direct API access. * `not_messageable` - the id is not a messaging-scoped id. * `error` - a transient Graph API failure. To gate a comment automation on this, use the automation's `audience` rules instead of calling this per comment - they run the same lookup only on comments that actually match a keyword, and can ask the commenter to confirm with one tap. Answers are cached briefly per (account, user). Pass `refresh=true` right after asking someone to follow, so a follow from a moment ago is visible.
pub async fn get_instagram_follow_status(
configuration: &configuration::Configuration,
account_id: &str,
user_id: &str,
refresh: Option<bool>,
) -> Result<models::GetInstagramFollowStatus200Response, Error<GetInstagramFollowStatusError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let p_path_user_id = user_id;
let p_query_refresh = refresh;
let uri_str = format!(
"{}/v1/accounts/{accountId}/follow-status/{userId}",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id),
userId = crate::apis::urlencode(p_path_user_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_query_refresh {
req_builder = req_builder.query(&[("refresh", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetInstagramFollowStatus200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetInstagramFollowStatus200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetInstagramFollowStatusError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Returns the connected Slack channel details and the default message identity (name and avatar shown as the author on every post, with Slack's APP badge). The identity applies to messages only; the app's own Slack profile is global and cannot be changed per workspace.
pub async fn get_slack_settings(
configuration: &configuration::Configuration,
account_id: &str,
) -> Result<models::GetSlackSettings200Response, Error<GetSlackSettingsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let uri_str = format!(
"{}/v1/accounts/{accountId}/slack-settings",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetSlackSettings200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetSlackSettings200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetSlackSettingsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Returns TikTok creator details, available privacy levels, posting limits, and commercial content options for a specific TikTok account. Only works with TikTok accounts.
pub async fn get_tik_tok_creator_info(
configuration: &configuration::Configuration,
account_id: &str,
media_type: Option<&str>,
) -> Result<models::GetTikTokCreatorInfo200Response, Error<GetTikTokCreatorInfoError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let p_query_media_type = media_type;
let uri_str = format!(
"{}/v1/accounts/{accountId}/tiktok/creator-info",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_query_media_type {
req_builder = req_builder.query(&[("mediaType", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GetTikTokCreatorInfo200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetTikTokCreatorInfo200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetTikTokCreatorInfoError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Returns connected accounts. Only includes accounts within the plan limit by default. Follower data requires analytics add-on. Supports optional server-side pagination via page/limit params. When omitted, returns all accounts (backward-compatible). page and limit must be supplied together; out-of-range page/limit values are rejected with 400 rather than silently clamped.
pub async fn list_accounts(
configuration: &configuration::Configuration,
profile_id: Option<&str>,
platform: Option<&str>,
status: Option<&str>,
include_over_limit: Option<bool>,
page: Option<i32>,
limit: Option<i32>,
) -> Result<models::AccountsListResponse, Error<ListAccountsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_profile_id = profile_id;
let p_query_platform = platform;
let p_query_status = status;
let p_query_include_over_limit = include_over_limit;
let p_query_page = page;
let p_query_limit = limit;
let uri_str = format!("{}/v1/accounts", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_query_profile_id {
req_builder = req_builder.query(&[("profileId", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_platform {
req_builder = req_builder.query(&[("platform", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_status {
req_builder = req_builder.query(&[("status", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_include_over_limit {
req_builder = req_builder.query(&[("includeOverLimit", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_page {
req_builder = req_builder.query(&[("page", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_limit {
req_builder = req_builder.query(&[("limit", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::AccountsListResponse`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::AccountsListResponse`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ListAccountsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Returns the 100 currently trending tracks of TikTok's Commercial Music Library for a TikTok account connected through the TikTok for Business app. Use a track id as tiktokSettings.musicSoundInfo.musicSoundId when creating a post. The list is not paged; countryCode selects the country chart.
pub async fn list_tik_tok_commercial_music(
configuration: &configuration::Configuration,
account_id: &str,
country_code: Option<&str>,
) -> Result<models::ListTikTokCommercialMusic200Response, Error<ListTikTokCommercialMusicError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let p_query_country_code = country_code;
let uri_str = format!(
"{}/v1/accounts/{accountId}/tiktok/commercial-music",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_query_country_code {
req_builder = req_builder.query(&[("countryCode", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListTikTokCommercialMusic200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListTikTokCommercialMusic200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<ListTikTokCommercialMusicError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Moves a connected account to a different profile owned by the same user. The target profile must belong to the same user as the account. For API keys restricted to specific profiles, BOTH the source account's current profile AND the target profile must be in the key's allowed set. Calls with a target profile outside the key's scope return 403.
pub async fn move_account_to_profile(
configuration: &configuration::Configuration,
account_id: &str,
move_account_to_profile_request: models::MoveAccountToProfileRequest,
) -> Result<models::MoveAccountToProfile200Response, Error<MoveAccountToProfileError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let p_body_move_account_to_profile_request = move_account_to_profile_request;
let uri_str = format!(
"{}/v1/accounts/{accountId}",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::PATCH, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_move_account_to_profile_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::MoveAccountToProfile200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::MoveAccountToProfile200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<MoveAccountToProfileError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Searches the location tags a TikTok account connected through the TikTok for Business app can attach to a video post. Send a result's id and name as tiktokSettings.locationId and locationName when creating a post. TikTok answers the 20 closest matches and fills the list with fuzzy matches when nothing matches, so an unrelated result does not mean the place is missing.
pub async fn search_tik_tok_locations(
configuration: &configuration::Configuration,
account_id: &str,
query: &str,
) -> Result<models::SearchTikTokLocations200Response, Error<SearchTikTokLocationsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let p_query_query = query;
let uri_str = format!(
"{}/v1/accounts/{accountId}/tiktok/locations",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
req_builder = req_builder.query(&[("query", &p_query_query.to_string())]);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SearchTikTokLocations200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SearchTikTokLocations200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<SearchTikTokLocationsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Updates a connected account's display name or username override. For X accounts on usage-based billing, also accepts an `xCapabilities` object to toggle background API operations that incur X API pass-through costs. Both fields are opt-in (default `false`). When off, no analytics syncs or DM polling are performed for that account, and no API call is metered for those operations. Publishing and deleting posts are always available regardless of these toggles. Setting `xCapabilities` on a non-X account returns 400.
pub async fn update_account(
configuration: &configuration::Configuration,
account_id: &str,
update_account_request: models::UpdateAccountRequest,
) -> Result<models::UpdateAccount200Response, Error<UpdateAccountError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let p_body_update_account_request = update_account_request;
let uri_str = format!(
"{}/v1/accounts/{accountId}",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::PUT, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_update_account_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UpdateAccount200Response`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UpdateAccount200Response`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UpdateAccountError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Set or clear the account's default post languages. 1-3 BCP-47 codes (e.g. \"pt\", \"en-US\"), the same validation as per-post langs; explicit null clears the default. Per-post platformSpecificData.langs always overrides this default. Applies to posts published after the change; already-published posts cannot be retagged (Bluesky has no post edit).
pub async fn update_bluesky_settings(
configuration: &configuration::Configuration,
account_id: &str,
update_bluesky_settings_request: models::UpdateBlueskySettingsRequest,
) -> Result<(), Error<UpdateBlueskySettingsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let p_body_update_bluesky_settings_request = update_bluesky_settings_request;
let uri_str = format!(
"{}/v1/accounts/{accountId}/bluesky-settings",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::PATCH, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_update_bluesky_settings_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<UpdateBlueskySettingsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// Set or clear the default message identity for this channel. Empty string clears a field; per-post platformSpecificData.username/iconUrl still override these defaults.
pub async fn update_slack_settings(
configuration: &configuration::Configuration,
account_id: &str,
update_slack_settings_request: models::UpdateSlackSettingsRequest,
) -> Result<(), Error<UpdateSlackSettingsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_account_id = account_id;
let p_body_update_slack_settings_request = update_slack_settings_request;
let uri_str = format!(
"{}/v1/accounts/{accountId}/slack-settings",
configuration.base_path,
accountId = crate::apis::urlencode(p_path_account_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::PATCH, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_update_slack_settings_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<UpdateSlackSettingsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}