Skip to main content

stakpak_shared/
telemetry.rs

1//! Telemetry module for anonymous usage tracking
2//!
3//! This module provides integration for tracking local provider usage.
4//! Telemetry is opt-out and collects no personal data, prompts, or session content.
5
6use serde::Serialize;
7use std::fmt;
8
9const TELEMETRY_ENDPOINT: &str = "https://apiv2.stakpak.dev/v1/telemetry";
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
12pub enum TelemetryEvent {
13    FirstOpen,
14    UserPrompted,
15}
16
17impl fmt::Display for TelemetryEvent {
18    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19        match self {
20            TelemetryEvent::FirstOpen => write!(f, "FirstOpen"),
21            TelemetryEvent::UserPrompted => write!(f, "UserPrompted"),
22        }
23    }
24}
25
26#[derive(Serialize)]
27struct TelemetryPayload {
28    event: String,
29    machine_name: String,
30    provider: String,
31    user_id: String,
32}
33
34pub fn capture_event(
35    anonymous_id: &str,
36    machine_name: Option<&str>,
37    enabled: bool,
38    event: TelemetryEvent,
39) {
40    if !enabled {
41        return;
42    }
43
44    let payload = TelemetryPayload {
45        event: event.to_string(),
46        machine_name: machine_name.unwrap_or("").to_string(),
47        provider: "Local".to_string(),
48        user_id: anonymous_id.to_string(),
49    };
50
51    tokio::spawn(async move {
52        let client = match crate::tls_client::create_tls_client(
53            crate::tls_client::TlsClientConfig::default(),
54        ) {
55            Ok(c) => c,
56            Err(_) => return,
57        };
58        let _ = client.post(TELEMETRY_ENDPOINT).json(&payload).send().await;
59    });
60}