|
|
@ -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 |
|
|
|
} |
|
|
|
} |
|
|
|