/*
* 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.0.4
* Contact: support@zernio.com
* Generated by: https://openapi-generator.tech
*/
use crate::models;
use serde::{Deserialize, Serialize};
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct PostAnalytics {
#[serde(rename = "impressions", skip_serializing_if = "Option::is_none")]
pub impressions: Option<i32>,
#[serde(rename = "reach", skip_serializing_if = "Option::is_none")]
pub reach: Option<i32>,
#[serde(rename = "likes", skip_serializing_if = "Option::is_none")]
pub likes: Option<i32>,
#[serde(rename = "comments", skip_serializing_if = "Option::is_none")]
pub comments: Option<i32>,
#[serde(rename = "shares", skip_serializing_if = "Option::is_none")]
pub shares: Option<i32>,
/// Number of saves/bookmarks (Instagram, Pinterest, X/Twitter)
#[serde(rename = "saves", skip_serializing_if = "Option::is_none")]
pub saves: Option<i32>,
#[serde(rename = "clicks", skip_serializing_if = "Option::is_none")]
pub clicks: Option<i32>,
#[serde(rename = "views", skip_serializing_if = "Option::is_none")]
pub views: Option<i32>,
/// Instagram feed posts and stories only: organic accounts that started following from this post. 0 for reels and other platforms.
#[serde(rename = "follows", skip_serializing_if = "Option::is_none")]
pub follows: Option<i32>,
/// Instagram Reels only: average watch time per play, in milliseconds. 0 for non-Reels media and other platforms.
#[serde(
rename = "igReelsAvgWatchTime",
skip_serializing_if = "Option::is_none"
)]
pub ig_reels_avg_watch_time: Option<i32>,
/// Instagram Reels only: total watch time including replays, in milliseconds. 0 for non-Reels media and other platforms.
#[serde(
rename = "igReelsVideoViewTotalTime",
skip_serializing_if = "Option::is_none"
)]
pub ig_reels_video_view_total_time: Option<i32>,
/// Video length in seconds. Currently Instagram Reels only; combine with igReelsAvgWatchTime (ms) to estimate retention. Null when unknown (other platforms, non-video media, or when Instagram does not expose the media URL, e.g. reels with copyrighted audio).
#[serde(
rename = "videoDurationSeconds",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub video_duration_seconds: Option<Option<i32>>,
/// Percentage, rounded to 2 decimals: (likes + comments + shares + saves) / (impressions or reach or views) * 100. Clicks and follows are never counted. The denominator is the FIRST of impressions, reach, views that is non-zero, so it is not the same basis on every post: a post with impressions divides by impressions, one without falls back to reach, then to views. If you need a single consistent basis (e.g. interactions / reach), compute it from the raw fields above. The engagementRate on the LinkedIn account endpoints is a different formula.
#[serde(rename = "engagementRate", skip_serializing_if = "Option::is_none")]
pub engagement_rate: Option<f64>,
#[serde(rename = "lastUpdated", skip_serializing_if = "Option::is_none")]
pub last_updated: Option<String>,
}
impl PostAnalytics {
pub fn new() -> PostAnalytics {
PostAnalytics {
impressions: None,
reach: None,
likes: None,
comments: None,
shares: None,
saves: None,
clicks: None,
views: None,
follows: None,
ig_reels_avg_watch_time: None,
ig_reels_video_view_total_time: None,
video_duration_seconds: None,
engagement_rate: None,
last_updated: None,
}
}
}