diff --git a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt index 7c1054f8cc..cb137f937d 100644 --- a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt +++ b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt @@ -495,6 +495,8 @@ internal class ChildFactory @Inject constructor( context = context, params = UsedeskComponent.Params( userWalletId = route.walletMetaInfo.userWalletId?.stringValue, + source = route.source, + prefilledMessage = route.prefilledMessage, ), componentFactory = usedeskComponentFactory, ) diff --git a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt index 63c6e73fdb..c358ce8fe7 100644 --- a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt +++ b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt @@ -100,9 +100,19 @@ sealed class AppRoute(val path: String) : Route { val userWalletId: UserWalletId, ) : AppRoute(path = "/details/security") + /** + * Support chat (Usedesk) screen. + * + * @property walletMetaInfo wallet meta info; its user wallet id is sent to Usedesk as the client email + * @property source source of the chat opening (Settings by default, Swap for FR-02). Drives both + * analytics and the Usedesk additional fields mapped by the component. + * @property prefilledMessage optional message sent to the chat on behalf of the user right after init + */ @Serializable data class Usedesk( val walletMetaInfo: WalletMetaInfo, + val source: AnalyticsParam.ScreensSources = AnalyticsParam.ScreensSources.Settings, + val prefilledMessage: String? = null, ) : AppRoute(path = "/usedesk/${walletMetaInfo.userWalletId}") @Serializable diff --git a/features/usedesk/api/build.gradle.kts b/features/usedesk/api/build.gradle.kts index b7114cd803..f7ffa922ac 100644 --- a/features/usedesk/api/build.gradle.kts +++ b/features/usedesk/api/build.gradle.kts @@ -13,5 +13,6 @@ dependencies { /** Core */ implementation(projects.core.decompose) implementation(projects.core.ui) + implementation(projects.core.analytics.models) } \ No newline at end of file diff --git a/features/usedesk/api/src/main/java/com/tangem/feature/usedesk/api/UsedeskComponent.kt b/features/usedesk/api/src/main/java/com/tangem/feature/usedesk/api/UsedeskComponent.kt index aa2cd6922c..7f620c614d 100644 --- a/features/usedesk/api/src/main/java/com/tangem/feature/usedesk/api/UsedeskComponent.kt +++ b/features/usedesk/api/src/main/java/com/tangem/feature/usedesk/api/UsedeskComponent.kt @@ -1,5 +1,6 @@ package com.tangem.feature.usedesk.api +import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.decompose.factory.ComponentFactory import com.tangem.core.ui.decompose.ComposableContentComponent @@ -8,6 +9,13 @@ interface UsedeskComponent : ComposableContentComponent { data class Params( /** User wallet id (hex string) sent to Usedesk as the client email to identify the user. */ val userWalletId: String? = null, + /** + * Source of the chat opening. Drives the analytics source and the Usedesk additional fields, + * which the component maps internally (e.g. [AnalyticsParam.ScreensSources.Swap] -> `swap`). + */ + val source: AnalyticsParam.ScreensSources = AnalyticsParam.ScreensSources.Settings, + /** Optional message sent to the chat on behalf of the user right after initialization. */ + val prefilledMessage: String? = null, ) interface Factory : ComponentFactory diff --git a/features/usedesk/impl/src/main/java/com/tangem/feature/usedesk/model/UsedeskModel.kt b/features/usedesk/impl/src/main/java/com/tangem/feature/usedesk/model/UsedeskModel.kt index a0056b0721..e99816ae43 100644 --- a/features/usedesk/impl/src/main/java/com/tangem/feature/usedesk/model/UsedeskModel.kt +++ b/features/usedesk/impl/src/main/java/com/tangem/feature/usedesk/model/UsedeskModel.kt @@ -2,7 +2,7 @@ package com.tangem.feature.usedesk.model import androidx.compose.runtime.Stable import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.core.analytics.models.AnalyticsParam +import com.tangem.core.analytics.models.AnalyticsParam.ScreensSources import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -52,6 +52,8 @@ internal class UsedeskModel @Inject constructor( channelId = CHANNEL_ID, clientId = clientId, clientEmail = params.userWalletId, + clientInitMessage = params.prefilledMessage, + additionalFields = additionalFieldsFor(params.source), ), ) } @@ -61,7 +63,7 @@ internal class UsedeskModel @Inject constructor( if (isScreenLoadEventSent) return isScreenLoadEventSent = true analyticsEventHandler.send( - UsedeskAnalyticsEvents.ChatScreenOpened(source = AnalyticsParam.ScreensSources.Settings), + UsedeskAnalyticsEvents.ChatScreenOpened(source = params.source), ) } @@ -87,6 +89,11 @@ internal class UsedeskModel @Inject constructor( super.onDestroy() } + private fun additionalFieldsFor(source: ScreensSources): Map = when (source) { + ScreensSources.Swap -> mapOf(SWAP_ADDITIONAL_FIELD_ID to SWAP_ADDITIONAL_FIELD_VALUE) + else -> emptyMap() + } + private suspend fun getOrCreateClientId(): String { var clientId = "" appPreferencesStore.editData { preferences -> @@ -105,5 +112,8 @@ internal class UsedeskModel @Inject constructor( const val URL_CHAT_API = "https://ud.tangem.org" const val COMPANY_ID = "2" const val CHANNEL_ID = "54" + + const val SWAP_ADDITIONAL_FIELD_ID = 245L + const val SWAP_ADDITIONAL_FIELD_VALUE = "swap" } } \ No newline at end of file