Merge pull request #1958 from vector-im/feature/bma/posthog3
Migrate to PostHog 3.0.0
This commit is contained in:
@@ -167,7 +167,7 @@ opusencoder = "io.element.android:opusencoder:1.1.0"
|
||||
kotlinpoet = "com.squareup:kotlinpoet:1.15.3"
|
||||
|
||||
# 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"
|
||||
matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:aa14cbcdf81af2746d20a71779ec751f971e1d7f"
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
package io.element.android.services.analyticsproviders.posthog
|
||||
|
||||
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.di.ApplicationContext
|
||||
import javax.inject.Inject
|
||||
@@ -27,31 +29,20 @@ class PostHogFactory @Inject constructor(
|
||||
private val buildMeta: BuildMeta,
|
||||
private val posthogEndpointConfigProvider: PosthogEndpointConfigProvider,
|
||||
) {
|
||||
|
||||
fun createPosthog(): PostHog {
|
||||
fun createPosthog(): PostHogInterface {
|
||||
val endpoint = posthogEndpointConfigProvider.provide()
|
||||
return PostHog.Builder(context, endpoint.apiKey, endpoint.host)
|
||||
// Record certain application events automatically! (off/false by default)
|
||||
// .captureApplicationLifecycleEvents()
|
||||
// Record screen views automatically! (off/false by default)
|
||||
// .recordScreenViews()
|
||||
// Capture deep links as part of the screen call. (off by default)
|
||||
// .captureDeepLinks()
|
||||
// Maximum number of events to keep in queue before flushing (default 20)
|
||||
// .flushQueueSize(20)
|
||||
// Max delay before flushing the queue (30 seconds)
|
||||
// .flushInterval(30, TimeUnit.SECONDS)
|
||||
// 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
|
||||
}
|
||||
return PostHogAndroid.with(
|
||||
context,
|
||||
PostHogAndroidConfig(
|
||||
apiKey = endpoint.apiKey,
|
||||
host = endpoint.host,
|
||||
captureApplicationLifecycleEvents = false,
|
||||
captureDeepLinks = false,
|
||||
captureScreenViews = false,
|
||||
).also {
|
||||
it.debug = buildMeta.isDebuggable
|
||||
it.sendFeatureFlagEvent = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
|
||||
package io.element.android.services.analyticsproviders.posthog
|
||||
|
||||
import com.posthog.android.PostHog
|
||||
import com.posthog.android.Properties
|
||||
import com.posthog.PostHogInterface
|
||||
import com.squareup.anvil.annotations.ContributesMultibinding
|
||||
import im.vector.app.features.analytics.itf.VectorAnalyticsEvent
|
||||
import im.vector.app.features.analytics.itf.VectorAnalyticsScreen
|
||||
@@ -37,30 +36,31 @@ class PosthogAnalyticsProvider @Inject constructor(
|
||||
) : AnalyticsProvider {
|
||||
override val name = "Posthog"
|
||||
|
||||
private var posthog: PostHog? = null
|
||||
private var posthog: PostHogInterface? = null
|
||||
private var analyticsId: String? = null
|
||||
|
||||
override fun init() {
|
||||
posthog = createPosthog()
|
||||
posthog?.optOut(false)
|
||||
posthog?.optIn()
|
||||
// Timber.e("PostHog distinctId: ${posthog?.distinctId()}")
|
||||
identifyPostHog()
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
// When opting out, ensure that the queue is flushed first, or it will be flushed later (after user has revoked consent)
|
||||
posthog?.flush()
|
||||
posthog?.optOut(true)
|
||||
posthog?.shutdown()
|
||||
posthog?.optOut()
|
||||
posthog?.close()
|
||||
posthog = null
|
||||
analyticsId = null
|
||||
}
|
||||
|
||||
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) {
|
||||
posthog?.screen(screen.getName(), screen.getProperties()?.toPostHogProperties())
|
||||
posthog?.screen(screen.getName(), properties = screen.getProperties())
|
||||
}
|
||||
|
||||
override fun updateUserProperties(userProperties: UserProperties) {
|
||||
@@ -74,7 +74,7 @@ class PosthogAnalyticsProvider @Inject constructor(
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
private fun createPosthog(): PostHog = postHogFactory.createPosthog()
|
||||
private fun createPosthog(): PostHogInterface = postHogFactory.createPosthog()
|
||||
|
||||
private fun identifyPostHog() {
|
||||
val id = analyticsId ?: return
|
||||
@@ -86,24 +86,15 @@ class PosthogAnalyticsProvider @Inject constructor(
|
||||
// posthog?.identify(id, lateInitUserPropertiesFactory.createUserProperties()?.getProperties()?.toPostHogUserProperties(), IGNORED_OPTIONS)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Map<String, Any?>?.toPostHogProperties(): Properties? {
|
||||
if (this == null) return null
|
||||
|
||||
return Properties().apply {
|
||||
putAll(this@toPostHogProperties)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 })
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private fun Map<String, Any?>.keepOnlyNonNullValues(): Map<String, Any> {
|
||||
val result = mutableMapOf<String, Any>()
|
||||
for (entry in this) {
|
||||
val value = entry.value
|
||||
if (value != null) {
|
||||
result[entry.key] = value
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user