NTP-24283 | Navi link changes (#14927)

This commit is contained in:
Venkat Praneeth Reddy
2025-02-12 20:45:34 +05:30
committed by GitHub
parent a021f36bc2
commit e868d70806
22 changed files with 346 additions and 73 deletions

View File

@@ -34,6 +34,7 @@ import com.naviapp.analytics.utils.NaviAnalytics.Companion.LOGIN_FLAG
import com.naviapp.app.NaviApplication
import com.naviapp.common.helper.ReferralHelper
import com.naviapp.common.navigator.NaviDeepLinkNavigator
import com.naviapp.common.navigator.NaviDeepLinkNavigator.HOME_SMALL
import com.naviapp.common.navigator.ScreenNavigator
import com.naviapp.models.request.DeeplinkRequestData
import com.naviapp.models.request.OnboardingActionRequest
@@ -71,6 +72,7 @@ class DeeplinkManager(
private const val NAVI_PAY_HOME_PAGE_URL = "naviPayHomePageUrl"
const val DEEPLINK_TYPE = "deeplinkType"
const val DEEPLINK_MANAGER = "DeeplinkManager"
const val NAVILINK_IDENTIFIER = "naviLinkIdentifier"
}
fun handleDeeplinkData(
@@ -82,6 +84,7 @@ class DeeplinkManager(
originalLink: String? = null,
finish: Boolean? = false,
ctaData: CtaData? = null,
isDeeplinkNaviLink: Boolean? = false,
onRedirectListener: (bundle: Bundle) -> Unit = {},
) {
try {
@@ -118,6 +121,7 @@ class DeeplinkManager(
onRedirectListener = onRedirectListener,
)
}
DeeplinkType.FB.name -> {
naviAnalytics.sendHandleFacebookDeeplinkEvent(deepLinkValue, originalLink)
uriData?.let { uri ->
@@ -161,6 +165,7 @@ class DeeplinkManager(
)
}
}
DeeplinkType.BRANCH_IO.name -> {
naviAnalytics.sendHandleBranchDeeplinkEvent(deepLinkValue, originalLink)
val customObject = jsonObject?.optJSONObject(CUSTOM_OBJECT)
@@ -193,6 +198,7 @@ class DeeplinkManager(
onRedirectListener = onRedirectListener,
)
}
DeeplinkType.NAVI_PAY.name -> {
val bundle =
Bundle().apply {
@@ -207,14 +213,35 @@ class DeeplinkManager(
needsResult = false,
)
}
DeeplinkType.NATIVE.name -> {
naviAnalytics.sendNativeDeeplinkEvent(originalLink)
navigateTo(
activity = activity,
bundle = ctaData?.bundle ?: Bundle(),
finish = originalLink == NaviDeepLinkNavigator.CHAT_ACTIVITY,
ctaData = ctaData ?: CtaData(url = originalLink),
)
if (isDeeplinkNaviLink == true) {
naviAnalytics.sendNaviLinkDeeplinkEvent(originalLink)
if (BaseUtils.isUserLoggedIn().not()) {
onRedirectListener(
Bundle().apply {
putString(DEEPLINK_TYPE, DeeplinkType.NATIVE.name)
putString(NAVILINK_IDENTIFIER, originalLink)
}
)
} else {
naviAnalytics.sendNaviLinkSuccessEvent(ctaData, wasUserLoggedIn = true)
navigateTo(
activity,
ctaData = ctaData ?: CtaData(url = HOME_SMALL),
bundle = ctaData?.bundle ?: Bundle(),
finish = finish,
)
}
} else {
naviAnalytics.sendNativeDeeplinkEvent(originalLink)
navigateTo(
activity = activity,
bundle = ctaData?.bundle ?: Bundle(),
finish = originalLink == NaviDeepLinkNavigator.CHAT_ACTIVITY,
ctaData = ctaData ?: CtaData(url = originalLink),
)
}
}
}
} catch (ex: Exception) {

View File

@@ -12,8 +12,9 @@ import com.navi.common.model.ModuleName
import com.naviapp.models.request.OnboardingRequest
import com.naviapp.network.retrofit.ResponseCallback
import com.naviapp.utils.superAppRetrofitService
import javax.inject.Inject
class DeeplinkRepository : ResponseCallback() {
class DeeplinkRepository @Inject constructor() : ResponseCallback() {
suspend fun fetchBranchSDKData(deeplink: String) =
superAppRetrofitService().fetchBranchSDKData(deeplink, ModuleName.GROOT.name)
@@ -37,4 +38,14 @@ class DeeplinkRepository : ResponseCallback() {
isNae = { false },
),
)
suspend fun fetchNaviLinkData(naviLinkIdentifier: String) =
apiResponseCallback(
response = superAppRetrofitService().fetchNaviLink(naviLinkIdentifier),
metricInfo =
MetricInfo.CommonMetric(
screen = DeeplinkManager.DEEPLINK_MANAGER,
isNae = { false },
),
)
}

View File

@@ -183,6 +183,16 @@ class NaviAnalytics private constructor() {
)
}
fun sendNaviLinkSuccessEvent(ctaData: CtaData?, wasUserLoggedIn: Boolean) {
NaviTrackEvent.trackEventOnClickStream(
"NaviLink_Deeplink_Success_Event",
mapOf(
Pair("ctaData", ctaData.toString()),
Pair("wasUserLoggedIn", wasUserLoggedIn.toString()),
),
)
}
fun noDeeplink() {
NaviTrackEvent.trackEvent("Lending_Deeplink_Absent")
}
@@ -916,6 +926,23 @@ class NaviAnalytics private constructor() {
mapOf(Pair("originalLink", originalLink.orEmpty())),
)
}
fun sendNaviLinkDeeplinkEvent(originalLink: String?) {
NaviTrackEvent.trackEventOnClickStream(
"Handle_NaviLink_Deeplink_Event",
mapOf(Pair("originalLink", originalLink.orEmpty())),
)
}
fun sendNaviLinkSuccessEvent(ctaData: CtaData?, wasUserLoggedIn: Boolean) {
NaviTrackEvent.trackEventOnClickStream(
"NaviLink_Deeplink_Success_Event",
mapOf(
Pair("ctaData", ctaData.toString()),
Pair("wasUserLoggedIn", wasUserLoggedIn.toString()),
),
)
}
}
inner class TopUpLoanIntro(val screenName: String? = null) {

View File

@@ -76,4 +76,26 @@ class NaviDeeplinkAnalytics @Inject constructor() {
eventValues = mapOf("reason" to reason),
)
}
fun sendProcessNaviLinkEvent(naviLinkIdentifier: String) {
NaviTrackEvent.trackEventOnClickStream(
eventName = "Process_NaviLink_Event",
eventValues = mapOf("naviLinkIdentifier" to naviLinkIdentifier),
)
}
fun sendNaviLinkDataEvent(deeplinkData: DeeplinkData?, isUserLoggedIn: Boolean) {
NaviTrackEvent.trackEventOnClickStream(
eventName = "NaviLink_Data_Event",
eventValues =
mapOf(
"deeplinkData" to deeplinkData.toString(),
"isUserLoggedIn" to isUserLoggedIn.toString(),
),
)
}
fun sendNaviLinkDataFailEvent() {
NaviTrackEvent.trackEventOnClickStream(eventName = "NaviLink_Data_Fail_Event")
}
}

View File

@@ -27,6 +27,7 @@ class AppsFlyerDeeplinkManager : IDeeplinkManager {
isReInit: Boolean,
activity: Activity?,
processDeeplink: KFunction1<DeeplinkData, Unit>,
processNaviLink: ((String) -> Unit)?,
) {
Timber.d("DeeplinkManagement: handleAppsFlyerDeeplink subscribeForDeepLink")
AppsFlyerUtil.instance.subscribeForDeepLink(

View File

@@ -68,32 +68,37 @@ constructor(private val analyticsTracker: NaviDeeplinkAnalytics) : IDeeplinkMana
isReInit: Boolean,
activity: Activity?,
processDeeplink: KFunction1<DeeplinkData, Unit>,
processNaviLink: ((String) -> Unit)?,
) {
processDeeplinkCallback = processDeeplink
intentData = intent.data.toString()
try {
if (
isReInit &&
intent.hasExtra("branch_force_new_session") &&
intent.getBooleanExtra("branch_force_new_session", false)
) {
Branch.sessionBuilder(activity)
.withCallback(branchReferralInitListener)
.withData(intent.data)
.reInit()
analyticsTracker.sendBranchInitEvent()
} else {
Branch.sessionBuilder(activity)
.withCallback(branchReferralInitListener)
.withData(intent.data)
.init()
analyticsTracker.sendBranchInitEvent()
val naviLinkIdentifier = getNaviLinkIdentifier(intent)
if (naviLinkIdentifier == null) {
try {
if (
isReInit &&
intent.hasExtra("branch_force_new_session") &&
intent.getBooleanExtra("branch_force_new_session", false)
) {
Branch.sessionBuilder(activity)
.withCallback(branchReferralInitListener)
.withData(intent.data)
.reInit()
analyticsTracker.sendBranchInitEvent()
} else {
Branch.sessionBuilder(activity)
.withCallback(branchReferralInitListener)
.withData(intent.data)
.init()
analyticsTracker.sendBranchInitEvent()
}
} catch (e: Exception) {
Timber.d("DeeplinkManagement: Branch init failed ${e.message}")
// DeviceId id not being populated in Crashlytics for this crash. Hence sending
// message
// in click-stream
analyticsTracker.sendBranchInitFailedEvent(e.message.orEmpty())
}
} catch (e: Exception) {
Timber.d("DeeplinkManagement: Branch init failed ${e.message}")
// DeviceId id not being populated in Crashlytics for this crash. Hence sending message
// in click-stream
analyticsTracker.sendBranchInitFailedEvent(e.message.orEmpty())
}
}
}

View File

@@ -63,6 +63,7 @@ constructor(
originalLink = deeplinkData?.originalDeeplink,
finish = finish,
ctaData = deeplinkData?.ctaData,
isDeeplinkNaviLink = deeplinkData?.isDeeplinkNaviLink,
)
}

View File

@@ -28,6 +28,7 @@ class FacebookDeeplinkManager : IDeeplinkManager {
isReInit: Boolean,
activity: Activity?,
processDeeplink: KFunction1<DeeplinkData, Unit>,
processNaviLink: ((String) -> Unit)?,
) {
Timber.d("DeeplinkManagement: in handleFacebookDeeplink")
val appLinkData: Bundle? = AppLinks.getAppLinkData(intent)

View File

@@ -16,5 +16,6 @@ interface IDeeplinkManager {
isReInit: Boolean = false,
activity: Activity? = null,
processDeeplink: kotlin.reflect.KFunction1<com.naviapp.models.DeeplinkData, Unit>,
processNaviLink: ((String) -> Unit)? = null,
)
}

View File

@@ -22,6 +22,7 @@ import com.naviapp.models.DeeplinkData
import com.naviapp.registration.helper.getChatParams
import com.naviapp.registration.helper.isNotificationAlive
import com.naviapp.utils.Constants
import com.naviapp.utils.Constants.NAVILINK
import com.naviapp.utils.isPublicPage
import kotlin.reflect.KFunction1
@@ -32,29 +33,31 @@ class NativeDeeplinkManager : IDeeplinkManager {
isReInit: Boolean,
activity: Activity?,
processDeeplink: KFunction1<DeeplinkData, Unit>,
processNaviLink: ((String) -> Unit)?,
) {
var deeplink = intent.getStringExtra(Constants.DEEPLINK)
if (Regex(Constants.HTTP_REGEX).containsMatchIn(deeplink.orEmpty())) {
return
}
var deeplink = intent.getStringExtra(Constants.DEEPLINK).orEmpty()
var param: ArrayList<LineItem>? = null
if (deeplink == NaviDeepLinkNavigator.CHAT_ACTIVITY) {
if (isNotificationAlive(intent = intent)) {
param = getChatParams(intent = intent)
} else {
deeplink = NaviDeepLinkNavigator.HOME
NaviTrackEvent.trackEventOnClickStream(
eventName = CHAT_PN_OPENED,
eventValues = mapOf(SCREEN_NAME to HOME_SCREEN),
)
when {
handleNaviLink(intent, processNaviLink) -> return
isHttpLink(deeplink) -> return
deeplink == NaviDeepLinkNavigator.CHAT_ACTIVITY -> {
if (isNotificationAlive(intent = intent)) {
param = getChatParams(intent = intent)
} else {
deeplink = NaviDeepLinkNavigator.HOME
NaviTrackEvent.trackEventOnClickStream(
eventName = CHAT_PN_OPENED,
eventValues = mapOf(SCREEN_NAME to HOME_SCREEN),
)
}
}
}
val ctaData = CtaData(url = deeplink, bundle = intent.extras)
param?.let { ctaData.parameters = it }
if (BaseUtils.isUserLoggedIn() || isPublicPage(deeplink)) {
if (!deeplink.isNullOrEmpty()) {
if (deeplink.isNotEmpty()) {
processDeeplink(
DeeplinkData(
deeplinkType = DeeplinkType.NATIVE.name,
@@ -66,3 +69,33 @@ class NativeDeeplinkManager : IDeeplinkManager {
}
}
}
private fun isHttpLink(deeplink: String): Boolean {
return Regex(Constants.HTTP_REGEX).containsMatchIn(deeplink)
}
private fun handleNaviLink(intent: Intent, processNaviLink: ((String) -> Unit)?): Boolean {
val naviLinkIdentifier = getNaviLinkIdentifier(intent)
if (naviLinkIdentifier != null) {
processNaviLink?.invoke(naviLinkIdentifier)
return true
}
return false
}
fun getNaviLinkIdentifier(intent: Intent): String? {
val navilink = intent.getStringExtra(Constants.NAVILINK_SMALL).orEmpty()
val identifiers =
when {
navilink.isNotEmpty() -> navilink.split("/")
else -> emptyList()
}
val naviLinkIdentifier = identifiers.getOrNull(1)
return if (identifiers.firstOrNull() == NAVILINK && !naviLinkIdentifier.isNullOrEmpty()) {
naviLinkIdentifier
} else {
null
}
}

View File

@@ -22,6 +22,7 @@ class NaviPayDeeplinkManager : IDeeplinkManager {
isReInit: Boolean,
activity: Activity?,
processDeeplink: KFunction1<DeeplinkData, Unit>,
processNaviLink: ((String) -> Unit)?,
) {
if (intent.isNaviPayIntent()) {
Timber.d("DeeplinkManagement: in handleNaviPayDeeplink processDeeplink ${intent.data}")

View File

@@ -10,7 +10,10 @@ package com.naviapp.deeplinkmanagement.vm
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.viewModelScope
import com.navi.base.utils.BaseUtils
import com.navi.common.utils.isValidResponse
import com.navi.common.viewmodel.BaseVM
import com.naviapp.analytics.deeplink.DeeplinkRepository
import com.naviapp.analytics.deeplink.DeeplinkType
import com.naviapp.deeplinkmanagement.analytics.NaviDeeplinkAnalytics
import com.naviapp.deeplinkmanagement.usecase.DeeplinkManagerFactory
@@ -29,6 +32,7 @@ class DeeplinkManagementViewModel
constructor(
private val deeplinkManagerFactory: DeeplinkManagerFactory,
private val naviDeeplinkAnalytics: NaviDeeplinkAnalytics,
private val deeplinkRepository: DeeplinkRepository,
) : BaseVM() {
private val _deeplinkData = MutableSharedFlow<DeeplinkData>()
@@ -48,7 +52,11 @@ constructor(
.handleDeeplink(intent = intent, processDeeplink = ::processDeeplink)
deeplinkManagerFactory
.getDeeplinkManager(DeeplinkType.NATIVE, naviDeeplinkAnalytics)
.handleDeeplink(intent = intent, processDeeplink = ::processDeeplink)
.handleDeeplink(
intent = intent,
processDeeplink = ::processDeeplink,
processNaviLink = ::processNaviLink,
)
}
}
@@ -60,8 +68,8 @@ constructor(
deeplinkManagerFactory
.getDeeplinkManager(DeeplinkType.BRANCH_IO, naviDeeplinkAnalytics)
.handleDeeplink(
isReInit = isReInit,
intent = intent,
isReInit = isReInit,
activity = activity,
processDeeplink = ::processDeeplink,
)
@@ -73,4 +81,35 @@ constructor(
_deeplinkData.emit(deeplinkData)
}
}
private fun processNaviLink(naviLinkIdentifier: String) {
viewModelScope.safeLaunch(Dispatchers.IO) {
naviDeeplinkAnalytics.sendProcessNaviLinkEvent(naviLinkIdentifier)
if (BaseUtils.isUserLoggedIn()) {
val response = deeplinkRepository.fetchNaviLinkData(naviLinkIdentifier)
if (response.isValidResponse()) {
val data =
DeeplinkData(
deeplinkType = DeeplinkType.NATIVE.name,
originalDeeplink = naviLinkIdentifier,
ctaData = response.data?.nextCta,
isDeeplinkNaviLink = true,
)
_deeplinkData.emit(data)
naviDeeplinkAnalytics.sendNaviLinkDataEvent(data, isUserLoggedIn = true)
} else {
naviDeeplinkAnalytics.sendNaviLinkDataFailEvent()
}
} else {
val data =
DeeplinkData(
deeplinkType = DeeplinkType.NATIVE.name,
originalDeeplink = naviLinkIdentifier,
isDeeplinkNaviLink = true,
)
_deeplinkData.emit(data)
naviDeeplinkAnalytics.sendNaviLinkDataEvent(data, isUserLoggedIn = false)
}
}
}
}

View File

@@ -35,6 +35,7 @@ data class NotificationPayload(
@Parcelize
data class NotificationDynamicDeeplink(
@SerializedName("url") val url: String? = null,
@SerializedName("naviLink") val naviLink: String? = null,
@SerializedName("isDynamicDeeplink") val isDynamicDeeplink: Boolean? = null,
) : Parcelable

View File

@@ -16,6 +16,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.core.net.toUri
import com.navi.base.model.LineItem
import com.navi.base.utils.isNotNullAndNotEmpty
import com.navi.design.font.FontWeightEnum
import com.navi.design.font.getFontWeight
import com.navi.pay.utils.IS_FROM_IAN
@@ -27,6 +28,7 @@ import com.naviapp.home.model.NotificationStatus
import com.naviapp.home.model.NotificationUpdateStatus
import com.naviapp.home.model.ToastBarState
import com.naviapp.home.viewmodel.NotificationVM
import com.naviapp.utils.Constants.NAVILINK_SMALL
fun createAnnotatedStringWithBold(text: String): AnnotatedString {
val regex = "\\*\\*(.*?)\\*\\*".toRegex()
@@ -110,11 +112,20 @@ fun handleNotificationClick(
if (notification.notificationPayload?.dynamicDeeplink?.isDynamicDeeplink == true) {
try {
notification.notificationPayload.dynamicDeeplink.url?.let {
if (notification.notificationPayload.dynamicDeeplink.naviLink.isNotNullAndNotEmpty()) {
val intent = Intent(activity, DeeplinkManagementActivity::class.java)
intent.data = it.toUri()
intent.putExtra("branch_force_new_session", true)
intent.putExtra(
NAVILINK_SMALL,
notification.notificationPayload.dynamicDeeplink.naviLink,
)
activity.startActivity(intent)
} else {
notification.notificationPayload.dynamicDeeplink.url?.let {
val intent = Intent(activity, DeeplinkManagementActivity::class.java)
intent.data = it.toUri()
intent.putExtra("branch_force_new_session", true)
activity.startActivity(intent)
}
}
} catch (e: Exception) {
NaviAnalytics.naviAnalytics

View File

@@ -19,4 +19,5 @@ data class DeeplinkData(
var originalDeeplink: String? = null,
var deeplinkValue: String? = null,
var ctaData: CtaData? = null,
var isDeeplinkNaviLink: Boolean? = false,
) : Serializable

View File

@@ -0,0 +1,12 @@
/*
*
* * Copyright © 2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.models
import com.navi.base.model.CtaData
data class NaviLinkData(val nextCta: CtaData? = null)

View File

@@ -69,6 +69,7 @@ import com.naviapp.home.model.NotificationUpdateStatus
import com.naviapp.lending_permission.model.LendingPermissionScreenResponse
import com.naviapp.models.ABSettings
import com.naviapp.models.LoginSettings
import com.naviapp.models.NaviLinkData
import com.naviapp.models.UserInstalledApp
import com.naviapp.models.request.CustomPaymentRequest
import com.naviapp.models.request.EmailRequest
@@ -151,6 +152,12 @@ interface RetrofitService {
@Header(HEADER_X_PLATFORM) platform: String = Constants.OS_ANDROID,
): Response<GenericResponse<OnboardingResponse>>
@GET("navi-link/v1/{identifier}")
suspend fun fetchNaviLink(
@Path("identifier") naviLinkIdentifier: String,
@Header(HEADER_X_PLATFORM) platform: String = Constants.OS_ANDROID,
): Response<GenericResponse<NaviLinkData>>
@POST("/auth/v1/session")
suspend fun createNewSession(): Response<GenericResponse<CreateSessionResponse>>

View File

@@ -57,9 +57,11 @@ import com.naviapp.pushnotification.utils.clearSharedDbWithKeys
import com.naviapp.pushnotification.utils.removeSpecificImageCache
import com.naviapp.pushnotification.utils.removeSpecificPreferenceKeys
import com.naviapp.utils.Constants
import com.naviapp.utils.Constants.BRANCH
import com.naviapp.utils.Constants.DELIVERED
import com.naviapp.utils.Constants.FCM_DELIVERED_V2
import com.naviapp.utils.Constants.MESSAGE_ID
import com.naviapp.utils.Constants.NAVILINK_SMALL
import com.naviapp.utils.Constants.NOTIFICATION_PERMISSION_DENIED
import com.naviapp.utils.Constants.STATUS
import com.naviapp.utils.Constants.TEMPLATE_NAME
@@ -259,6 +261,9 @@ class NaviFirebaseMessagingService : FirebaseMessagingService() {
intent.putExtra(key, value)
}
}
if (intent.getStringExtra(NAVILINK_SMALL).isNotNullAndNotEmpty()) {
intent.removeExtra(BRANCH)
}
if (intent.getStringExtra(Constants.DEEPLINK) == CHAT_ACTIVITY) {
NaviTrackEvent.trackEventOnClickStream(CHAT_PN_RECEIVED)
if (NaviChatActivity.isChatActivityVisible) {

View File

@@ -108,4 +108,10 @@ class RegisterRepository : ResponseCallback() {
retrofitService().updateMarketingDataToSaphyra(request = saphyraRequestData),
metricInfo = MetricInfo.AppMetric(screen = naeScreenName, isNae = { false }),
)
suspend fun fetchNaviLinkCta(naviLinkIdentifier: String, screenName: String) =
apiResponseCallback(
response = superAppRetrofitService().fetchNaviLink(naviLinkIdentifier),
metricInfo = MetricInfo.CommonMetric(screen = screenName, isNae = { false }),
)
}

View File

@@ -22,6 +22,7 @@ import com.navi.common.utils.Constants.LOGIN_SOURCE
import com.navi.common.utils.isHomePageUrl
import com.naviapp.analytics.deeplink.DeeplinkManager
import com.naviapp.analytics.deeplink.DeeplinkManager.Companion.DEEPLINK_TYPE
import com.naviapp.analytics.deeplink.DeeplinkManager.Companion.NAVILINK_IDENTIFIER
import com.naviapp.analytics.utils.NaviAnalytics
import com.naviapp.common.navigator.NaviDeepLinkNavigator
import com.naviapp.common.navigator.NaviDeepLinkNavigator.HOME_SMALL
@@ -125,6 +126,7 @@ constructor(
type = deeplinkData?.deeplinkType.toString(),
deepLinkValue = deeplinkData?.deeplinkValue,
originalLink = deeplinkData?.originalDeeplink,
isDeeplinkNaviLink = deeplinkData?.isDeeplinkNaviLink,
) { bundle ->
deepLinkBundle = bundle
activity.source = deepLinkBundle?.getString(LOGIN_SOURCE)
@@ -163,29 +165,45 @@ constructor(
val deepLinkType = deepLinkBundle?.getString(DEEPLINK_TYPE)
if (deepLinkType.isNotNullAndNotEmpty()) {
analyticsTracker.deeplinkSuccess(deepLinkType)
registrationVM.getOnboardingAction(
screenName = screenName,
onboardingRequest =
OnboardingRequest(
onboardingActions =
listOf(
OnboardingActionRequest(
type = OnboardingActionType.DEEP_LINK_RESOLUTION.name,
data =
DeeplinkRequestData(
data = extractDataFromBundle(deepLinkBundle),
type = deepLinkType,
),
val naviLinkIdentifier = deepLinkBundle?.getString(NAVILINK_IDENTIFIER)
if (!naviLinkIdentifier.isNullOrEmpty()) {
registrationVM.fetchNaviLinkCta(
naviLinkIdentifier = naviLinkIdentifier,
screenName = screenName,
) { nextCta ->
analyticsTracker.sendNaviLinkSuccessEvent(nextCta, wasUserLoggedIn = false)
asyncHomePageResponseFetchAndRedirect(
homePageResponseFetchJob,
activity,
homeVM,
nextCta,
)
}
} else {
registrationVM.getOnboardingAction(
screenName = screenName,
onboardingRequest =
OnboardingRequest(
onboardingActions =
listOf(
OnboardingActionRequest(
type = OnboardingActionType.DEEP_LINK_RESOLUTION.name,
data =
DeeplinkRequestData(
data = extractDataFromBundle(deepLinkBundle),
type = deepLinkType,
),
)
)
)
),
) { nextCta ->
asyncHomePageResponseFetchAndRedirect(
homePageResponseFetchJob,
activity,
homeVM,
nextCta,
)
),
) { nextCta ->
asyncHomePageResponseFetchAndRedirect(
homePageResponseFetchJob,
activity,
homeVM,
nextCta,
)
}
}
} else {
if (deferredActionUseCase.get().isJobStarted()) {

View File

@@ -18,6 +18,7 @@ import com.navi.base.utils.FAILURE
import com.navi.base.utils.orFalse
import com.navi.common.network.authenticator.TokenAuthenticator
import com.navi.common.utils.CommonNaviAnalytics
import com.navi.common.utils.isValidResponse
import com.navi.common.viewmodel.BaseVM
import com.naviapp.models.request.GenerateOtpRequest
import com.naviapp.models.request.LoginType
@@ -34,6 +35,7 @@ import com.naviapp.network.ApiConstants.API_TOO_MANY_REQUESTS
import com.naviapp.network.ApiConstants.API_WRONG_OTP
import com.naviapp.network.ApiErrorTagType
import com.naviapp.registration.repositories.RegisterRepository
import com.naviapp.utils.Constants.DEEPLINK_FETCH_CTA_TIMEOUT
import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.TimeoutCancellationException
@@ -206,7 +208,7 @@ class RegistrationVM(private val registerRepository: RegisterRepository = Regist
viewModelScope.launch(Dispatchers.IO) {
var nextCta: CtaData? = null
try {
withTimeout(5000) {
withTimeout(DEEPLINK_FETCH_CTA_TIMEOUT) {
val response =
registerRepository.getOnboardingAction(
onboardingRequest = onboardingRequest,
@@ -241,6 +243,43 @@ class RegistrationVM(private val registerRepository: RegisterRepository = Regist
}
}
fun fetchNaviLinkCta(
naviLinkIdentifier: String,
screenName: String,
onComplete: (nextCta: CtaData?) -> Unit,
) {
viewModelScope.launch(Dispatchers.IO) {
var nextCta: CtaData? = null
try {
withTimeout(DEEPLINK_FETCH_CTA_TIMEOUT) {
val response =
registerRepository.fetchNaviLinkCta(
naviLinkIdentifier = naviLinkIdentifier,
screenName = screenName,
)
if (response.isValidResponse()) {
nextCta = response.data?.nextCta
}
}
} catch (e: Exception) {
Timber.e(e)
if (e is TimeoutCancellationException) {
NaviTrackEvent.trackEvent(
eventName = "fetchNaviLinkCta",
eventValues = mapOf("error" to "Timeout"),
)
} else {
NaviTrackEvent.trackEvent(
eventName = "fetchNaviLinkCta",
eventValues = mapOf("error" to e.toString()),
)
}
} finally {
onComplete(nextCta)
}
}
}
fun saveTokens(sessionToken: String?, refreshToken: String?) {
BaseUtils.saveSessionToken(sessionToken.orEmpty())
BaseUtils.saveRefreshToken(refreshToken.orEmpty())

View File

@@ -37,7 +37,11 @@ object Constants {
const val HOME_LOAN = "home"
const val PERSONAL_LOAN = "personal"
const val MESSAGE_ID = "messageId"
const val NAVILINK = "NAVILINK"
const val NAVILINK_SMALL = "navilink"
const val BRANCH = "branch"
const val DEEPLINK = "deeplink"
const val DEEPLINK_FETCH_CTA_TIMEOUT = 5000L
const val WEB_URL = "webUrl"
const val REPEAT_LOAN_TYPE = "repeat"
const val WIDGET_ID = "WIDGET_ID"