telemetry: use station callsign as the PostHog distinct_id (dedupe users)

The random per-install UUID lives in the LOCAL SQLite, so one operator running
OpsLog on several machines (laptop / desktop / Maestro) or after a reinstall
counted as several distinct "users" — making the user total unreliable. Use the
station callsign as distinct_id when set (public in ham radio, stable across all
of an op's machines); the install UUID stays as a fallback and rides along as an
install_id property so per-machine detail isn't lost.
This commit is contained in:
2026-07-24 16:20:23 +02:00
parent 384925f24a
commit 3ea7f44fd1
+17 -5
View File
@@ -85,15 +85,27 @@ func (a *App) sendTelemetryHeartbeat() {
return // already counted today
}
// distinct_id identifies the USER. Prefer the station callsign — it's stable
// across every machine/reinstall the same operator runs, so one op counts as
// one user (a callsign is public in amateur radio). The random per-install ID
// is only a fallback until a callsign is configured; without it the same op on
// a laptop + desktop + Maestro showed up as three "users". install_id rides
// along as a property so multiple machines under one callsign stay visible.
installID := a.telemetryInstallID()
distinctID := installID
if call := a.activeCallsign(); call != "" {
distinctID = call
}
payload := map[string]any{
"api_key": posthogAPIKey,
"event": "app_opened",
"distinct_id": a.telemetryInstallID(),
"distinct_id": distinctID,
"properties": map[string]any{
"version": appVersion,
"os": runtime.GOOS,
"arch": runtime.GOARCH,
"$lib": "opslog",
"version": appVersion,
"os": runtime.GOOS,
"arch": runtime.GOARCH,
"install_id": installID,
"$lib": "opslog",
},
"timestamp": time.Now().UTC().Format(time.RFC3339),
}