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, PartialEq, Eq, Serialize)]
12pub enum TelemetryEvent {
13    FirstOpen,
14    UserPrompted,
15    CommandCalled(String),
16}
17
18impl fmt::Display for TelemetryEvent {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        match self {
21            TelemetryEvent::FirstOpen => write!(f, "FirstOpen"),
22            TelemetryEvent::UserPrompted => write!(f, "UserPrompted"),
23            TelemetryEvent::CommandCalled(command_name) => {
24                write!(f, "{}_command_called", command_name)
25            }
26        }
27    }
28}
29
30#[derive(Serialize)]
31struct TelemetryPayload {
32    event: TelemetryEvent,
33    machine_name: String,
34    provider: String,
35    user_id: String,
36}
37
38pub fn capture_event(
39    anonymous_id: &str,
40    machine_name: Option<&str>,
41    enabled: bool,
42    event: TelemetryEvent,
43) {
44    if !enabled {
45        return;
46    }
47
48    let payload = TelemetryPayload {
49        event,
50        machine_name: machine_name.unwrap_or("").to_string(),
51        provider: "Local".to_string(),
52        user_id: anonymous_id.to_string(),
53    };
54
55    tokio::spawn(async move {
56        let client = match crate::tls_client::create_tls_client(
57            crate::tls_client::TlsClientConfig::default(),
58        ) {
59            Ok(c) => c,
60            Err(_) => return,
61        };
62        let _ = client.post(TELEMETRY_ENDPOINT).json(&payload).send().await;
63    });
64}