NTP-24283 | Navi link changes (#14927)
This commit is contained in:
committed by
GitHub
parent
a021f36bc2
commit
e868d70806
@@ -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) {
|
||||
|
||||
@@ -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 },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ constructor(
|
||||
originalLink = deeplinkData?.originalDeeplink,
|
||||
finish = finish,
|
||||
ctaData = deeplinkData?.ctaData,
|
||||
isDeeplinkNaviLink = deeplinkData?.isDeeplinkNaviLink,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,4 +19,5 @@ data class DeeplinkData(
|
||||
var originalDeeplink: String? = null,
|
||||
var deeplinkValue: String? = null,
|
||||
var ctaData: CtaData? = null,
|
||||
var isDeeplinkNaviLink: Boolean? = false,
|
||||
) : Serializable
|
||||
|
||||
12
android/app/src/main/java/com/naviapp/models/NaviLinkData.kt
Normal file
12
android/app/src/main/java/com/naviapp/models/NaviLinkData.kt
Normal 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)
|
||||
@@ -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>>
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 }),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user