Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/8031.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Do not send any request to Posthog if no consent is provided.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.matrix.android.sdk.api.extensions.orFalse
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
Expand Down Expand Up @@ -60,6 +61,9 @@ class DefaultVectorAnalytics @Inject constructor(
private var userConsent: Boolean? = null
private var analyticsId: String? = null

// Cache for the properties to send
private var pendingUserProperties: UserProperties? = null

override fun init() {
observeUserConsent()
observeAnalyticsId()
Expand Down Expand Up @@ -112,6 +116,7 @@ class DefaultVectorAnalytics @Inject constructor(

private suspend fun identifyPostHog() {
val id = analyticsId ?: return
if (!userConsent.orFalse()) return
if (id.isEmpty()) {
Timber.tag(analyticsTag.value).d("reset")
posthog?.reset()
Expand All @@ -126,7 +131,7 @@ class DefaultVectorAnalytics @Inject constructor(
.onEach { consent ->
Timber.tag(analyticsTag.value).d("User consent updated to $consent")
userConsent = consent
optOutPostHog()
initOrStopPostHog()
initOrStopSentry()
}
.launchIn(globalScope)
Expand All @@ -141,8 +146,22 @@ class DefaultVectorAnalytics @Inject constructor(
}
}

private fun optOutPostHog() {
userConsent?.let { posthog?.optOut(!it) }
private suspend fun initOrStopPostHog() {
userConsent?.let { _userConsent ->
when (_userConsent) {
true -> {
posthog?.optOut(false)
identifyPostHog()
pendingUserProperties?.let { doUpdateUserProperties(it) }
pendingUserProperties = null
}
false -> {
// 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)
}
}
}
}

override fun capture(event: VectorAnalyticsEvent) {
Expand All @@ -160,7 +179,17 @@ class DefaultVectorAnalytics @Inject constructor(
}

override fun updateUserProperties(userProperties: UserProperties) {
posthog?.identify(REUSE_EXISTING_ID, userProperties.getProperties()?.toPostHogUserProperties(), IGNORED_OPTIONS)
if (userConsent == true) {
doUpdateUserProperties(userProperties)
} else {
pendingUserProperties = userProperties
}
}

private fun doUpdateUserProperties(userProperties: UserProperties) {
posthog
?.takeIf { userConsent == true }
?.identify(REUSE_EXISTING_ID, userProperties.getProperties()?.toPostHogUserProperties(), IGNORED_OPTIONS)
}

private fun Map<String, Any?>?.toPostHogProperties(): Properties? {
Expand Down