use crate::{AnalyticsEvent, Property};
use std::collections::HashMap;
use time::OffsetDateTime;
pub const PUBLIC_POSTHOG_PROJECT_KEY: &str = "phc_sgKidIE4WYYFSJHd8LEYY1UZqASpnfQKeMqlJfSXwqg";
#[derive(Debug, serde::Serialize)]
#[serde(untagged)]
pub enum PostHogEvent<'a> {
Capture(PostHogCaptureEvent<'a>),
Identify(PostHogIdentifyEvent<'a>),
}
impl<'a> PostHogEvent<'a> {
pub fn from_event(
analytics_id: &'a str,
session_id: &'a str,
event: &'a AnalyticsEvent,
) -> Self {
let properties = event.props.iter().map(|(name, value)| {
(
name.as_ref(),
match value {
&Property::Integer(v) => v.into(),
&Property::Float(v) => v.into(),
Property::String(v) => v.as_str().into(),
&Property::Bool(v) => v.into(),
},
)
});
match event.kind {
crate::EventKind::Append => Self::Capture(PostHogCaptureEvent {
timestamp: event.time_utc,
event: event.name.as_ref(),
distinct_id: analytics_id,
properties: properties
.chain([("session_id", session_id.into())])
.collect(),
}),
crate::EventKind::Update => Self::Identify(PostHogIdentifyEvent {
timestamp: event.time_utc,
event: "$identify",
distinct_id: analytics_id,
properties: [("session_id", session_id.into())].into(),
set: properties.collect(),
}),
}
}
}
#[derive(Debug, serde::Serialize)]
pub struct PostHogCaptureEvent<'a> {
#[serde(with = "::time::serde::rfc3339")]
timestamp: OffsetDateTime,
event: &'a str,
distinct_id: &'a str,
properties: HashMap<&'a str, serde_json::Value>,
}
#[derive(Debug, serde::Serialize)]
pub struct PostHogIdentifyEvent<'a> {
#[serde(with = "::time::serde::rfc3339")]
timestamp: OffsetDateTime,
event: &'a str,
distinct_id: &'a str,
properties: HashMap<&'a str, serde_json::Value>,
#[serde(rename = "$set")]
set: HashMap<&'a str, serde_json::Value>,
}
#[derive(Debug, serde::Serialize)]
pub struct PostHogBatch<'a> {
api_key: &'static str,
batch: &'a [PostHogEvent<'a>],
}
impl<'a> PostHogBatch<'a> {
pub fn from_events(events: &'a [PostHogEvent<'a>]) -> Self {
Self {
api_key: PUBLIC_POSTHOG_PROJECT_KEY,
batch: events,
}
}
}