Download crates/forge_tracker/src/collect/posthog.rs from SaylorTwift/forgecode: direct link, hf CLI and curl.
- Browser
- Download file 2.96 kB
-
https://huggingface.co/SaylorTwift/forgecode/resolve/main/crates/forge_tracker/src/collect/posthog.rs
- Command line
-
hf download hf://SaylorTwift/forgecode/crates/forge_tracker/src/collect/posthog.rs
-
curl -L -o posthog.rs https://huggingface.co/SaylorTwift/forgecode/resolve/main/crates/forge_tracker/src/collect/posthog.rs
2.96 kB
| use std::collections::HashMap; | |
| use std::time::Duration; | |
| use chrono::NaiveDateTime; | |
| use http::header::{HeaderName, HeaderValue}; | |
| use reqwest::Client; | |
| use serde::Serialize; | |
| use serde_json::Value; | |
| use super::super::Result; | |
| use super::Collect; | |
| use crate::Event; | |
| pub struct Tracker { | |
| api_secret: &'static str, | |
| client: Client, | |
| } | |
| impl Tracker { | |
| pub fn new(api_secret: &'static str) -> Self { | |
| // Configure HTTP client with connection pooling similar to forge_provider | |
| let client = Client::builder() | |
| .connect_timeout(Duration::from_secs(10)) | |
| .read_timeout(Duration::from_secs(30)) | |
| .pool_idle_timeout(Duration::from_secs(90)) | |
| .pool_max_idle_per_host(5) | |
| .build() | |
| .expect("Failed to build HTTP client for PostHog tracker"); | |
| Self { api_secret, client } | |
| } | |
| } | |
| struct Payload { | |
| api_key: String, | |
| event: String, | |
| distinct_id: String, | |
| properties: Option<HashMap<String, serde_json::Value>>, | |
| set: Option<serde_json::Value>, | |
| timestamp: Option<NaiveDateTime>, | |
| } | |
| impl Payload { | |
| fn new(api_key: String, mut input: Event) -> Self { | |
| let mut properties = HashMap::new(); | |
| let distinct_id = input.client_id.to_string(); | |
| let event = input.event_name.to_string(); | |
| let mut set = None; | |
| if let Some(identity) = input.identity.take() | |
| && let Ok(value) = serde_json::to_value(identity) | |
| { | |
| set = Some(value); | |
| } | |
| if let Ok(Value::Object(map)) = serde_json::to_value(input) { | |
| for (key, value) in map { | |
| properties.insert(key, value); | |
| } | |
| } | |
| Self { | |
| api_key, | |
| event, | |
| distinct_id, | |
| properties: Some(properties), | |
| set, | |
| timestamp: Some(chrono::Utc::now().naive_utc()), | |
| } | |
| } | |
| } | |
| impl Tracker { | |
| fn create_request(&self, event: Event) -> Result<reqwest::Request> { | |
| let url = reqwest::Url::parse("https://us.i.posthog.com/capture/")?; | |
| let mut request = reqwest::Request::new(reqwest::Method::POST, url); | |
| request.headers_mut().insert( | |
| HeaderName::from_static("content-type"), | |
| HeaderValue::from_static("application/json"), | |
| ); | |
| let payload = Payload::new(self.api_secret.to_string(), event); | |
| let _ = request | |
| .body_mut() | |
| .insert(reqwest::Body::from(serde_json::to_string(&payload)?)); | |
| Ok(request) | |
| } | |
| } | |
| impl Collect for Tracker { | |
| // TODO: move http request to a dispatch | |
| async fn collect(&self, event: Event) -> Result<()> { | |
| let request = self.create_request(event)?; | |
| self.client.execute(request).await?; | |
| Ok(()) | |
| } | |
| } | |