umami_api/website_stats/
get_stats.rs1use crate::{Filters, Timestamps, Umami, UmamiError, website_stats::StatsWithComparison};
2
3pub struct GetStatsRequestBuilder<'a> {
4 client: &'a Umami,
5 website_id: String,
6 timestamps: Timestamps,
7 filters: Filters,
8}
9
10impl<'a> GetStatsRequestBuilder<'a> {
11 pub fn new(client: &'a Umami, website_id: String, timestamps: Timestamps) -> Self {
12 Self { client, website_id, timestamps, filters: Filters::default() }
13 }
14
15 pub fn filters(mut self, filters: Filters) -> Self {
17 self.filters = filters;
18 self
19 }
20
21 pub async fn fetch(self) -> Result<StatsWithComparison, UmamiError> {
22 let url = format!("websites/{}/stats", self.website_id);
23
24 let mut filters = self.filters.as_parameters();
25 let timestamps: Vec<_> = vec![
26 ("startAt", self.timestamps.start_at.timestamp_millis().to_string()),
27 ("endAt", self.timestamps.end_at.timestamp_millis().to_string()),
28 ];
29 filters.extend(timestamps);
30
31 self.client.request::<StatsWithComparison, _>("get", &url, filters).await
32 }
33}
34
35#[cfg(test)]
37mod tests {
38 use super::*;
39 use std::env;
40 use chrono::{Days, Utc};
41 use dotenv::dotenv;
42
43 #[tokio::test]
44 async fn good() {
45 dotenv().ok();
46 let instance = env::var("INSTANCE").expect("INSTANCE has to be set");
47 let username = env::var("USERNAME").expect("USERNAME has to be set");
48 let password = env::var("PASSWORD").expect("PASSWORD has to be set");
49
50 let api = Umami::new(instance, username, password).await.unwrap();
51 let request = api.get_stats("02d78ab3-89d2-463a-8a2c-a4552dfea57a", Timestamps {
52 start_at: Utc::now().checked_sub_days(Days::new(7)).unwrap(),
53 end_at: Utc::now(),
54 });
55 let stats = request
56 .filters(Filters {
57 country: Some("SG"),
58 ..Filters::default()
59 })
60 .fetch()
61 .await
62 .inspect_err(|err| eprintln!("Error spotted: {}", err));
63
64 assert!(stats.is_ok());
65 assert!(stats.unwrap().base.pageviews >= 1);
66 }
67}
68