Browse Source

Migrate to PostHog 3.0.0

pull/1958/head
Benoit Marty 10 months ago
parent
commit
2b764a1e56
  1. 2
      gradle/libs.versions.toml
  2. 43
      services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PostHogFactory.kt
  3. 43
      services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt

2
gradle/libs.versions.toml

@ -167,7 +167,7 @@ opusencoder = "io.element.android:opusencoder:1.1.0"
kotlinpoet = "com.squareup:kotlinpoet:1.15.3" kotlinpoet = "com.squareup:kotlinpoet:1.15.3"
# Analytics # Analytics
posthog = "com.posthog.android:posthog:2.0.3" posthog = "com.posthog:posthog-android:3.0.0-RC.1"
sentry = "io.sentry:sentry-android:7.0.0" sentry = "io.sentry:sentry-android:7.0.0"
matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:aa14cbcdf81af2746d20a71779ec751f971e1d7f" matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:aa14cbcdf81af2746d20a71779ec751f971e1d7f"

43
services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PostHogFactory.kt

@ -17,7 +17,9 @@
package io.element.android.services.analyticsproviders.posthog package io.element.android.services.analyticsproviders.posthog
import android.content.Context import android.content.Context
import com.posthog.android.PostHog import com.posthog.PostHogInterface
import com.posthog.android.PostHogAndroid
import com.posthog.android.PostHogAndroidConfig
import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.ApplicationContext
import javax.inject.Inject import javax.inject.Inject
@ -27,31 +29,20 @@ class PostHogFactory @Inject constructor(
private val buildMeta: BuildMeta, private val buildMeta: BuildMeta,
private val posthogEndpointConfigProvider: PosthogEndpointConfigProvider, private val posthogEndpointConfigProvider: PosthogEndpointConfigProvider,
) { ) {
fun createPosthog(): PostHogInterface {
fun createPosthog(): PostHog {
val endpoint = posthogEndpointConfigProvider.provide() val endpoint = posthogEndpointConfigProvider.provide()
return PostHog.Builder(context, endpoint.apiKey, endpoint.host) return PostHogAndroid.with(
// Record certain application events automatically! (off/false by default) context,
// .captureApplicationLifecycleEvents() PostHogAndroidConfig(
// Record screen views automatically! (off/false by default) apiKey = endpoint.apiKey,
// .recordScreenViews() host = endpoint.host,
// Capture deep links as part of the screen call. (off by default) captureApplicationLifecycleEvents = false,
// .captureDeepLinks() captureDeepLinks = false,
// Maximum number of events to keep in queue before flushing (default 20) captureScreenViews = false,
// .flushQueueSize(20) ).also {
// Max delay before flushing the queue (30 seconds) it.debug = buildMeta.isDebuggable
// .flushInterval(30, TimeUnit.SECONDS) it.sendFeatureFlagEvent = false
// Enable or disable collection of ANDROID_ID (true) }
.collectDeviceId(false) )
.logLevel(getLogLevel())
.build()
}
private fun getLogLevel(): PostHog.LogLevel {
return if (buildMeta.isDebuggable) {
PostHog.LogLevel.DEBUG
} else {
PostHog.LogLevel.INFO
}
} }
} }

43
services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt

@ -16,8 +16,7 @@
package io.element.android.services.analyticsproviders.posthog package io.element.android.services.analyticsproviders.posthog
import com.posthog.android.PostHog import com.posthog.PostHogInterface
import com.posthog.android.Properties
import com.squareup.anvil.annotations.ContributesMultibinding import com.squareup.anvil.annotations.ContributesMultibinding
import im.vector.app.features.analytics.itf.VectorAnalyticsEvent import im.vector.app.features.analytics.itf.VectorAnalyticsEvent
import im.vector.app.features.analytics.itf.VectorAnalyticsScreen import im.vector.app.features.analytics.itf.VectorAnalyticsScreen
@ -37,30 +36,31 @@ class PosthogAnalyticsProvider @Inject constructor(
) : AnalyticsProvider { ) : AnalyticsProvider {
override val name = "Posthog" override val name = "Posthog"
private var posthog: PostHog? = null private var posthog: PostHogInterface? = null
private var analyticsId: String? = null private var analyticsId: String? = null
override fun init() { override fun init() {
posthog = createPosthog() posthog = createPosthog()
posthog?.optOut(false) posthog?.optIn()
// Timber.e("PostHog distinctId: ${posthog?.distinctId()}")
identifyPostHog() identifyPostHog()
} }
override fun stop() { override fun stop() {
// When opting out, ensure that the queue is flushed first, or it will be flushed later (after user has revoked consent) // When opting out, ensure that the queue is flushed first, or it will be flushed later (after user has revoked consent)
posthog?.flush() posthog?.flush()
posthog?.optOut(true) posthog?.optOut()
posthog?.shutdown() posthog?.close()
posthog = null posthog = null
analyticsId = null analyticsId = null
} }
override fun capture(event: VectorAnalyticsEvent) { override fun capture(event: VectorAnalyticsEvent) {
posthog?.capture(event.getName(), event.getProperties()?.toPostHogProperties()) posthog?.capture(event.getName(), properties = event.getProperties()?.keepOnlyNonNullValues())
} }
override fun screen(screen: VectorAnalyticsScreen) { override fun screen(screen: VectorAnalyticsScreen) {
posthog?.screen(screen.getName(), screen.getProperties()?.toPostHogProperties()) posthog?.screen(screen.getName(), properties = screen.getProperties())
} }
override fun updateUserProperties(userProperties: UserProperties) { override fun updateUserProperties(userProperties: UserProperties) {
@ -74,7 +74,7 @@ class PosthogAnalyticsProvider @Inject constructor(
// Not implemented // Not implemented
} }
private fun createPosthog(): PostHog = postHogFactory.createPosthog() private fun createPosthog(): PostHogInterface = postHogFactory.createPosthog()
private fun identifyPostHog() { private fun identifyPostHog() {
val id = analyticsId ?: return val id = analyticsId ?: return
@ -86,24 +86,15 @@ class PosthogAnalyticsProvider @Inject constructor(
// posthog?.identify(id, lateInitUserPropertiesFactory.createUserProperties()?.getProperties()?.toPostHogUserProperties(), IGNORED_OPTIONS) // posthog?.identify(id, lateInitUserPropertiesFactory.createUserProperties()?.getProperties()?.toPostHogUserProperties(), IGNORED_OPTIONS)
} }
} }
}
private fun Map<String, Any?>?.toPostHogProperties(): Properties? { private fun Map<String, Any?>.keepOnlyNonNullValues(): Map<String, Any> {
if (this == null) return null val result = mutableMapOf<String, Any>()
for (entry in this) {
return Properties().apply { val value = entry.value
putAll(this@toPostHogProperties) if (value != null) {
} result[entry.key] = value
}
/**
* We avoid sending nulls as part of the UserProperties as this will reset the values across all devices.
* The UserProperties event has nullable properties to allow for clients to opt in.
*/
/*
private fun Map<String, Any?>.toPostHogUserProperties(): Properties {
return Properties().apply {
putAll(this@toPostHogUserProperties.filter { it.value != null })
} }
} }
*/ return result
} }

Loading…
Cancel
Save