NTP-52015: Clickstream tracking for web redirection using CCT (#15591)

This commit is contained in:
Raaj Gopal
2025-04-02 16:58:33 +05:30
committed by GitHub
parent 698294c1c2
commit 2ead86735d
5 changed files with 86 additions and 11 deletions

View File

@@ -1390,14 +1390,14 @@ class NaviAnalytics private constructor() {
"redirection_to_web_data_ingestion_no_data_uploaded"
const val ANDROID_WEB_VIEW_UPDATE_CALLED = "android_web_view_update_called"
const val REDIRECTION_TO_CHROME_CUSTOM_TAB_STARTED = "redirection_to_chrome_tab_started"
const val REDIRECTION_TO_CHROME_CUSTOM_TAB_SUCCESS = "redirection_to_chrome_tab_success"
const val REDIRECTION_TO_CHROME_CUSTOM_TAB_FAILED = "redirection_to_chrome_tab_failed"
const val REDIRECTION_TO_CHROME_CUSTOM_TAB_SUCCESS = "cct_open_success"
const val REDIRECTION_TO_CHROME_CUSTOM_TAB_FAILED = "cct_open_failed"
const val REDIRECTION_TO_CHROME_CUSTOM_TAB_ABORTED = "redirection_to_chrome_tab_aborted"
const val REDIRECTION_TO_CHROME_CUSTOM_TAB_UNRESOLVED =
"redirection_to_chrome_tab_unresolved"
const val OPENING_CUSTOM_CHROME_TAB = "opening_custom_chrome_tab"
const val OPEN_CHROME_TAB_FAILED_FALLBACK_TO_BROWSER =
"open_chrome_tab_failed_fallback_to_browser"
const val OPENING_CUSTOM_CHROME_TAB = "cct_intent_fired"
const val TEMP_SESSION_CREATED = "temp_session_created"
const val OPEN_CHROME_TAB_FAILED_FALLBACK_TO_BROWSER = "cct_open_failure"
const val CHROME_TAB_MINIMISED = "chrome_tab_minimised"
const val CHROME_TAB_UN_MINIMISED = "chrome_tab_un_minimised"
const val CHROME_TAB_SESSION_ENDED = "chrome_tab_session_ended"

View File

@@ -25,6 +25,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.navi.analytics.utils.NaviTrackEvent
import com.navi.base.utils.isNotNullAndNotEmpty
import com.navi.base.utils.orFalse
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.CHROME_CUSTOM_TAB_HEADER_COLOR
@@ -38,6 +39,7 @@ import com.navi.common.useruploaddata.viewmodel.UserDataViewModel
import com.navi.common.utils.Constants.STATUS
import com.navi.common.utils.Constants.URL
import com.navi.common.utils.Constants.VERTICAL_TYPE
import com.navi.common.utils.EMPTY
import com.navi.common.utils.log
import com.navi.common.utils.observeWithTimeout
import com.navi.design.utils.parseColorSafe
@@ -67,6 +69,7 @@ import com.naviapp.webredirection.presentation.utils.WEB_BASE_URL
import com.naviapp.webredirection.presentation.utils.WEB_PLATFORM_IDENTIFIER
import com.naviapp.webredirection.presentation.utils.WEB_REDIRECTION_LOTTIE_URL
import com.naviapp.webredirection.presentation.viewModel.UiState
import com.naviapp.webredirection.presentation.viewModel.WebJourneyTypeIdentifier
import com.naviapp.webredirection.presentation.viewModel.WebPlatformIdentifier.ChromeTab
import com.naviapp.webredirection.presentation.viewModel.WebRedirectionVM
import dagger.hilt.android.AndroidEntryPoint
@@ -174,9 +177,33 @@ class WebRedirectionTransparentActivity : BaseActivity() {
private fun openCustomTab(context: Context, url: String) {
/** The below code returns package if chrome is installed to presented as Custom tabs * */
val journeyEventType =
if (
webRedirectionVM.webJourneyIdentifier.value.toString() ==
WebJourneyTypeIdentifier.PRE_PURCHASE.name
)
WebJourneyTypeIdentifier.PRE_PURCHASE.identifier
else if (
webRedirectionVM.webJourneyIdentifier.value.toString() ==
WebJourneyTypeIdentifier.POST_PURCHASE.name
)
WebJourneyTypeIdentifier.POST_PURCHASE.identifier
else EMPTY
chromeTabManager.journeyTypeIdentifier = journeyEventType
val packageName = CustomTabsClient.getPackageName(context, null)
if (packageName != null) {
NaviTrackEvent.trackEvent(eventName = OPENING_CUSTOM_CHROME_TAB, mapOf(URL to url))
if (journeyEventType.isNotNullAndNotEmpty()) {
NaviTrackEvent.trackEvent(
eventName = "redirection_${journeyEventType}_$OPENING_CUSTOM_CHROME_TAB",
mapOf(URL to url),
)
} else {
NaviTrackEvent.trackEvent(
eventName = "redirection_$OPENING_CUSTOM_CHROME_TAB",
mapOf(URL to url),
)
}
chromeTabManager.setWebUrl(url)
val headerColor =
FirebaseRemoteConfigHelper.getString(CHROME_CUSTOM_TAB_HEADER_COLOR, "")
@@ -199,8 +226,9 @@ class WebRedirectionTransparentActivity : BaseActivity() {
} else {
/** Fallback to opening the Url in browser, if custom tab is not available * */
NaviTrackEvent.trackEvent(
eventName = OPEN_CHROME_TAB_FAILED_FALLBACK_TO_BROWSER,
mapOf(URL to url),
eventName =
"redirection_${journeyEventType}_$OPEN_CHROME_TAB_FAILED_FALLBACK_TO_BROWSER",
mapOf(URL to url, "reason" to "chrome_tab_not_available"),
)
launchWebPageInChrome(url)
}

View File

@@ -20,6 +20,7 @@ import androidx.browser.customtabs.EngagementSignalsCallback
import androidx.browser.customtabs.ExperimentalMinimizationCallback
import com.navi.analytics.utils.NaviTrackEvent
import com.navi.base.AppServiceManager
import com.navi.base.utils.SUCCESS
import com.navi.common.constants.MESSAGE_TEXT
import com.navi.common.utils.Constants.URL
import com.navi.common.utils.log
@@ -41,6 +42,8 @@ object CustomChromeTabManager {
var customTabsSession: CustomTabsSession? = null
private set
var journeyTypeIdentifier: String? = null
private var url: String? = null
private val customTabsCallback: CustomTabsCallback =
@@ -57,15 +60,17 @@ object CustomChromeTabManager {
}
NAVIGATION_FINISHED -> {
NaviTrackEvent.trackEvent(
eventName = REDIRECTION_TO_CHROME_CUSTOM_TAB_SUCCESS,
eventValues = mapOf(URL to url.orEmpty()),
eventName =
"redirection_${journeyTypeIdentifier}_$REDIRECTION_TO_CHROME_CUSTOM_TAB_SUCCESS",
eventValues = mapOf("success" to SUCCESS),
isNeededForAppsflyer = false,
isNeededForFirebase = false,
)
}
NAVIGATION_FAILED -> {
NaviTrackEvent.trackEvent(
eventName = REDIRECTION_TO_CHROME_CUSTOM_TAB_FAILED,
eventName =
"redirection_${journeyTypeIdentifier}_$REDIRECTION_TO_CHROME_CUSTOM_TAB_FAILED",
eventValues = mapOf(URL to url.orEmpty()),
isNeededForAppsflyer = false,
isNeededForFirebase = false,

View File

@@ -21,6 +21,7 @@ const val WEB_REDIRECTION_TITLE = "webRedirectionTitle"
const val WEB_REDIRECTION_SUBTITLE = "webRedirectionSubtitle"
const val WEB_REDIRECTION_PLATFORM = "webRedirectionPlatform"
const val WEB_PLATFORM_IDENTIFIER = "webPlatformIdentifier"
const val WEB_JOURNEY_TYPE_IDENTIFIER = "webJourneyTypeIdentifier"
const val isCCT = "isCCT"
const val APPLICATION_TYPE = "applicationType"
const val WEB_REDIRECTION_DELAY_IN_MILLIS = "webRedirectionDelayInMillis"

View File

@@ -11,10 +11,13 @@ import android.content.Context
import android.os.Build
import android.os.Bundle
import androidx.lifecycle.viewModelScope
import com.navi.analytics.utils.NaviTrackEvent
import com.navi.ap.utils.constants.PL
import com.navi.base.model.CtaData
import com.navi.base.model.LineItem
import com.navi.base.utils.BaseUtils
import com.navi.base.utils.FAILURE
import com.navi.base.utils.SUCCESS
import com.navi.base.utils.generateRandomString
import com.navi.base.utils.generateSHA256Hash
import com.navi.base.utils.isNotNullAndNotEmpty
@@ -29,11 +32,13 @@ import com.navi.common.useruploaddata.model.PreSignedUrlListResponse
import com.navi.common.utils.Constants.TRUE
import com.navi.common.utils.Constants.URL
import com.navi.common.utils.Constants.VERTICAL_TYPE
import com.navi.common.utils.EMPTY
import com.navi.common.utils.buildUrlWithParameters
import com.navi.common.utils.isValidResponse
import com.navi.common.viewmodel.BaseVM
import com.navi.common.webredirection.data.WebRedirectionRepository
import com.naviapp.analytics.utils.NaviAnalytics
import com.naviapp.analytics.utils.NaviAnalytics.Companion.TEMP_SESSION_CREATED
import com.naviapp.common.navigator.NaviDeepLinkNavigator.WEB_URL
import com.naviapp.utils.Constants
import com.naviapp.utils.getVersionCode
@@ -44,6 +49,7 @@ import com.naviapp.webredirection.presentation.utils.DELAY_IN_MS
import com.naviapp.webredirection.presentation.utils.RANDOM_STRING_LENGTH
import com.naviapp.webredirection.presentation.utils.TOKEN
import com.naviapp.webredirection.presentation.utils.WEB_BASE_URL
import com.naviapp.webredirection.presentation.utils.WEB_JOURNEY_TYPE_IDENTIFIER
import com.naviapp.webredirection.presentation.utils.WEB_PLATFORM_IDENTIFIER
import com.naviapp.webredirection.presentation.utils.WEB_REDIRECTION_DELAY_IN_MILLIS
import com.naviapp.webredirection.presentation.utils.WEB_REDIRECTION_FIRST_LAUNCH
@@ -85,6 +91,9 @@ constructor(
private val _webPlatformIdentifier = MutableStateFlow(WebPlatformIdentifier.Default)
val webPlatformIdentifier = _webPlatformIdentifier.asStateFlow()
private val _webJourneyIdentifier = MutableStateFlow(WebJourneyTypeIdentifier.UNKNOWN)
val webJourneyIdentifier = _webJourneyIdentifier.asStateFlow()
private val _backPressCounter = MutableStateFlow(0)
val backPressCounter = _backPressCounter.asStateFlow()
@@ -112,7 +121,23 @@ constructor(
isNae = { !it.isValidResponse() },
),
)
val journeyEventType =
if (
webJourneyIdentifier.value.toString() ==
WebJourneyTypeIdentifier.PRE_PURCHASE.name
)
WebJourneyTypeIdentifier.PRE_PURCHASE.identifier
else if (
webJourneyIdentifier.value.toString() ==
WebJourneyTypeIdentifier.POST_PURCHASE.name
)
WebJourneyTypeIdentifier.POST_PURCHASE.identifier
else EMPTY
if (response.isValidResponse()) {
NaviTrackEvent.trackEvent(
eventName = "redirection_${journeyEventType}_$TEMP_SESSION_CREATED",
mapOf("state" to SUCCESS.lowercase()),
)
generateUrlForWebRedirect(codeVerifier, response.data?.code.toString()).let {
_screenState.value =
UiState.Success(
@@ -123,6 +148,10 @@ constructor(
)
}
} else {
NaviTrackEvent.trackEvent(
eventName = "redirection_${journeyEventType}_$TEMP_SESSION_CREATED",
mapOf("state" to FAILURE.lowercase()),
)
val errorUnifiedResponse =
getErrorUnifiedResponse(errors = response.errors, error = response.error)
_screenState.value = UiState.Error(errorUnifiedResponse.errorResponse)
@@ -229,6 +258,12 @@ constructor(
getValueFromMap(WEB_PLATFORM_IDENTIFIER) ?: WebPlatformIdentifier.Default.name
)
}
_webJourneyIdentifier.update {
WebJourneyTypeIdentifier.valueOf(
getValueFromMap(WEB_JOURNEY_TYPE_IDENTIFIER)
?: WebJourneyTypeIdentifier.UNKNOWN.name
)
}
_webRedirectionData.update {
WebRedirectionData(
baseUrl = getValueFromMap(WEB_BASE_URL).orEmpty(),
@@ -276,6 +311,12 @@ enum class WebPlatformIdentifier {
Default,
}
enum class WebJourneyTypeIdentifier(val identifier: String) {
PRE_PURCHASE("pre"),
POST_PURCHASE("post"),
UNKNOWN("unknown"),
}
data class WebRedirectionData(
val baseUrl: String,
val webRedirectionTitle: String,