Updated on 2026-08-14
This commit is contained in:
parent
692c6514fc
commit
bba915b9ec
10 changed files with 138 additions and 0 deletions
|
|
@ -66,6 +66,7 @@ import com.tangem.tap.common.analytics.handlers.BlockchainExceptionHandler
|
|||
import com.tangem.tap.common.analytics.handlers.amplitude.AmplitudeAnalyticsHandler
|
||||
import com.tangem.tap.common.analytics.handlers.appsflyer.AppsFlyerAnalyticsHandler
|
||||
import com.tangem.tap.common.analytics.handlers.appsflyer.AppsFlyerClient
|
||||
import com.tangem.tap.common.analytics.handlers.customerio.CustomerIoAnalyticsHandler
|
||||
import com.tangem.tap.common.analytics.handlers.firebase.FirebaseAnalyticsHandler
|
||||
import com.tangem.tap.common.images.createCoilImageLoader
|
||||
import com.tangem.tap.common.log.TangemAppLoggerInitializer
|
||||
|
|
@ -410,6 +411,7 @@ open class TangemApplication : Application(), ImageLoaderFactory, Configuration.
|
|||
factory.addHandlerBuilder(AmplitudeAnalyticsHandler.Builder())
|
||||
factory.addHandlerBuilder(FirebaseAnalyticsHandler.Builder())
|
||||
factory.addHandlerBuilder(AppsFlyerAnalyticsHandler.Builder(appsFlyerClientFactory))
|
||||
factory.addHandlerBuilder(CustomerIoAnalyticsHandler.Builder())
|
||||
|
||||
factory.addFilter(oneTimeEventFilter)
|
||||
factory.addFilter(AppsFlyerEventFilter())
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.tap.common.analytics.handlers.customerio
|
||||
|
||||
import com.tangem.core.analytics.api.UserIdHolder
|
||||
|
||||
/**
|
||||
* Client interface for Customer.io SDK operations.
|
||||
*/
|
||||
interface CustomerIoAnalyticsClient : UserIdHolder
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.tangem.tap.common.analytics.handlers.customerio
|
||||
|
||||
import com.tangem.core.analytics.api.AnalyticsHandler
|
||||
import com.tangem.core.analytics.api.AnalyticsUserIdHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
|
||||
/**
|
||||
* Customer.io analytics handler.
|
||||
*/
|
||||
class CustomerIoAnalyticsHandler(
|
||||
private val client: CustomerIoAnalyticsClient,
|
||||
) : AnalyticsHandler, AnalyticsUserIdHandler {
|
||||
|
||||
override fun id(): String = ID
|
||||
|
||||
override fun setUserId(userId: String) {
|
||||
client.setUserId(userId)
|
||||
}
|
||||
|
||||
override fun clearUserId() {
|
||||
client.clearUserId()
|
||||
}
|
||||
|
||||
override fun send(event: AnalyticsEvent) {
|
||||
// No-op: product events are not sent to Customer.io.
|
||||
// Triggers are configured to come from Amplitude directly.
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ID = "CustomerIO"
|
||||
}
|
||||
|
||||
class Builder : AnalyticsHandlerBuilder {
|
||||
override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsHandler? {
|
||||
return if (data.logConfig.isCustomerIoLogEnabled) {
|
||||
CustomerIoAnalyticsHandler(client = CustomerIoLogClient())
|
||||
} else if (data.config.customerIoCdpApiKey.isNotBlank()) {
|
||||
CustomerIoAnalyticsHandler(
|
||||
client = CustomerIoClient(
|
||||
application = data.application,
|
||||
cdpApiKey = data.config.customerIoCdpApiKey,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.tangem.tap.common.analytics.handlers.customerio
|
||||
|
||||
import android.app.Application
|
||||
import io.customer.messagingpush.ModuleMessagingPushFCM
|
||||
import io.customer.sdk.CustomerIO
|
||||
import io.customer.sdk.CustomerIOBuilder
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Real Customer.io SDK client.
|
||||
*
|
||||
* Initializes the SDK with the given CDP API key and provides:
|
||||
* - User identification (identify / clearIdentify)
|
||||
*
|
||||
* Auto-tracking of application lifecycle events is disabled since it is not needed.
|
||||
* Auto-tracking of screen views is disabled.
|
||||
*/
|
||||
internal class CustomerIoClient(
|
||||
application: Application,
|
||||
cdpApiKey: String,
|
||||
) : CustomerIoAnalyticsClient {
|
||||
|
||||
init {
|
||||
CustomerIOBuilder(
|
||||
applicationContext = application,
|
||||
cdpApiKey = cdpApiKey,
|
||||
)
|
||||
.trackApplicationLifecycleEvents(false)
|
||||
.autoTrackActivityScreens(false)
|
||||
.addCustomerIOModule(ModuleMessagingPushFCM())
|
||||
.build()
|
||||
|
||||
Timber.d("CustomerIO SDK initialized")
|
||||
}
|
||||
|
||||
override fun setUserId(userId: String) {
|
||||
CustomerIO.instance().identify(userId = userId)
|
||||
}
|
||||
|
||||
override fun clearUserId() {
|
||||
CustomerIO.instance().clearIdentify()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.tangem.tap.common.analytics.handlers.customerio
|
||||
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Log client for Customer.io (used in debug mode).
|
||||
*
|
||||
* Logs all operations to Timber instead of sending them to Customer.io.
|
||||
*/
|
||||
internal class CustomerIoLogClient : CustomerIoAnalyticsClient {
|
||||
|
||||
private var userId: String? = null
|
||||
|
||||
override fun setUserId(userId: String) {
|
||||
this.userId = userId
|
||||
Timber.tag(CustomerIoAnalyticsHandler.ID).d("identify: userId=$userId")
|
||||
}
|
||||
|
||||
override fun clearUserId() {
|
||||
Timber.tag(CustomerIoAnalyticsHandler.ID).d("clearIdentify: previous userId=$userId")
|
||||
this.userId = null
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.tap.common.pushes
|
|||
import android.annotation.SuppressLint
|
||||
import com.google.firebase.messaging.FirebaseMessagingService
|
||||
import com.google.firebase.messaging.RemoteMessage
|
||||
import io.customer.messagingpush.CustomerIOFirebaseMessagingService
|
||||
import timber.log.Timber
|
||||
|
||||
@SuppressLint("MissingFirebaseInstanceTokenRefresh")
|
||||
|
|
@ -15,11 +16,15 @@ internal class TangemPushNotificationService : FirebaseMessagingService() {
|
|||
override fun onNewToken(token: String) {
|
||||
super.onNewToken(token)
|
||||
Timber.d("New FCM token received: $token")
|
||||
|
||||
CustomerIOFirebaseMessagingService.onNewToken(applicationContext, token)
|
||||
}
|
||||
|
||||
override fun onMessageReceived(message: RemoteMessage) {
|
||||
super.onMessageReceived(message)
|
||||
|
||||
CustomerIOFirebaseMessagingService.onMessageReceived(applicationContext, message)
|
||||
|
||||
val notification = message.notification ?: return
|
||||
val channelId = notification.channelId ?: TANGEM_CHANNEL_ID
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue