Updated on 2026-08-14

This commit is contained in:
Tangem 2023-07-14 11:37:10 +03:00
parent d8348e54df
commit de899b5678
5 changed files with 73 additions and 23 deletions

View file

@ -12,6 +12,7 @@ import com.tangem.tap.common.chat.opener.implementation.SprinklrChatOpener
import com.tangem.tap.common.chat.opener.implementation.ZendeskChatOpener
import com.tangem.tap.common.redux.AppState
import org.rekotlin.Store
import java.io.File
class ChatManager(
private val preferencesStorage: PreferencesDataSource,
@ -20,7 +21,7 @@ class ChatManager(
) {
private val openers = mutableMapOf<ChatConfig, ChatOpener>()
fun open(config: ChatConfig, feedbackDataBuilder: (Context) -> String) {
fun open(config: ChatConfig, createLogsFile: (Context) -> File?, createFeedbackFile: (Context) -> File?) {
val opener = openers.getOrPut(config) {
when (config) {
is SprinklrConfig -> SprinklrChatOpener(getSprinklrUserId(), config, store, foregroundActivityObserver)
@ -28,7 +29,10 @@ class ChatManager(
}
}
opener.open(feedbackDataBuilder)
opener.open(
createFeedbackFile = createFeedbackFile,
createLogsFile = createLogsFile,
)
}
private fun getZendeskUserId(): String {

View file

@ -1,7 +1,8 @@
package com.tangem.tap.common.chat.opener
import android.content.Context
import java.io.File
internal interface ChatOpener {
fun open(feedbackDataBuilder: (Context) -> String)
fun open(createFeedbackFile: (Context) -> File?, createLogsFile: (Context) -> File?)
}

View file

@ -2,14 +2,15 @@ package com.tangem.tap.common.chat.opener.implementation
import android.content.Context
import android.content.Intent
import com.tangem.datasource.config.models.SprinklrConfig
import com.tangem.tap.ForegroundActivityObserver
import com.tangem.tap.common.chat.opener.ChatOpener
import com.tangem.datasource.config.models.SprinklrConfig
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.features.sprinklr.redux.SprinklrAction
import com.tangem.tap.features.sprinklr.ui.SprinklrActivity
import com.tangem.tap.withForegroundActivity
import org.rekotlin.Store
import java.io.File
internal class SprinklrChatOpener(
private val userId: String,
@ -17,7 +18,7 @@ internal class SprinklrChatOpener(
private val store: Store<AppState>,
private val foregroundActivityObserver: ForegroundActivityObserver,
) : ChatOpener {
override fun open(feedbackDataBuilder: (Context) -> String) {
override fun open(createFeedbackFile: (Context) -> File?, createLogsFile: (Context) -> File?) {
store.dispatch(SprinklrAction.Init(userId, config))
foregroundActivityObserver.withForegroundActivity { activity ->
val intent = Intent(activity, SprinklrActivity::class.java)

View file

@ -2,34 +2,34 @@ package com.tangem.tap.common.chat.opener.implementation
import android.content.Context
import com.tangem.core.analytics.Analytics
import com.tangem.datasource.config.models.ZendeskConfig
import com.tangem.domain.common.LogConfig
import com.tangem.tap.ForegroundActivityObserver
import com.tangem.tap.common.chat.opener.ChatOpener
import com.tangem.datasource.config.models.ZendeskConfig
import com.tangem.tap.withForegroundActivity
import com.tangem.wallet.R
import com.zendesk.logger.Logger
import zendesk.chat.Chat
import zendesk.chat.ChatConfiguration
import zendesk.chat.ChatEngine
import zendesk.chat.ChatProvidersConfiguration
import zendesk.chat.VisitorInfo
import timber.log.Timber
import zendesk.chat.*
import zendesk.configurations.Configuration
import zendesk.messaging.MessagingActivity
import java.io.File
internal class ZendeskChatOpener(
private val userId: String,
private val config: ZendeskConfig,
private val foregroundActivityObserver: ForegroundActivityObserver,
) : ChatOpener {
private var isInitialized = false
override fun open(feedbackDataBuilder: (Context) -> String) {
override fun open(createFeedbackFile: (Context) -> File?, createLogsFile: (Context) -> File?) {
foregroundActivityObserver.withForegroundActivity { activity ->
initZendeskIfNeeded(activity.applicationContext)
setChatVisitorInfo()
setChatVisitorNote(feedbackDataBuilder(activity))
showMessagingActivity(activity)
sendFeedbackFile(createFeedbackFile(activity))
sendLogsFile(createLogsFile(activity))
}
}
@ -48,8 +48,20 @@ internal class ZendeskChatOpener(
ChatProvidersConfiguration.builder().withVisitorInfo(visitorInfo).build()
}
private fun setChatVisitorNote(note: String) {
Chat.INSTANCE.providers()?.profileProvider()?.setVisitorNote(note)
private fun sendFeedbackFile(feedbackFile: File?) {
if (isInitialized && feedbackFile != null) {
Chat.INSTANCE.providers()?.chatProvider()?.sendFile(feedbackFile) { _, bytesUploaded, _ ->
Timber.d("Log file sent", "bytesUploaded: $bytesUploaded")
}
}
}
private fun sendLogsFile(logsFile: File?) {
if (isInitialized && logsFile != null) {
Chat.INSTANCE.providers()?.chatProvider()?.sendFile(logsFile) { _, bytesUploaded, _ ->
Timber.d("Log file sent", "bytesUploaded: $bytesUploaded")
}
}
}
private fun showMessagingActivity(context: Context) {

View file

@ -1,9 +1,9 @@
package com.tangem.tap.common.feedback
import android.content.Context
import com.tangem.datasource.config.models.ChatConfig
import com.tangem.domain.common.TapWorkarounds
import com.tangem.tap.common.chat.ChatManager
import com.tangem.datasource.config.models.ChatConfig
import com.tangem.tap.common.extensions.sendEmail
import com.tangem.tap.common.log.TangemLogCollector
import com.tangem.tap.foregroundActivityObserver
@ -22,32 +22,61 @@ class FeedbackManager(
private val chatManager: ChatManager,
) {
private var sessionFeedbackFile: File? = null
private var sessionLogsFile: File? = null
fun sendEmail(feedbackData: FeedbackData, onFail: ((Exception) -> Unit)? = null) {
feedbackData.prepare(infoHolder)
foregroundActivityObserver.withForegroundActivity { activity ->
val fileLog = createLogFile(activity)
activity.sendEmail(
email = getSupportEmail(),
subject = activity.getString(feedbackData.subjectResId),
message = feedbackData.joinTogether(activity, infoHolder),
file = fileLog,
file = getLogFile(activity),
onFail = onFail,
)
}
}
fun openChat(config: ChatConfig, feedbackData: FeedbackData) {
chatManager.open(config) { context ->
feedbackData.run {
chatManager.open(
config = config,
createLogsFile = ::getLogFile,
createFeedbackFile = { context -> getFeedbackFile(context, feedbackData) },
)
}
private fun getFeedbackFile(context: Context, feedbackData: FeedbackData): File? {
return try {
if (sessionFeedbackFile != null) {
return sessionFeedbackFile
}
val file = File(context.filesDir, FEEDBACK_FILE)
file.delete()
file.createNewFile()
val feedback = feedbackData.run {
prepare(infoHolder)
joinTogether(context, infoHolder)
}
val fileWriter = FileWriter(file)
fileWriter.write(feedback)
fileWriter.close()
sessionFeedbackFile = file
sessionFeedbackFile
} catch (ex: Exception) {
Timber.e(ex, "Can't create the logs file")
null
}
}
private fun createLogFile(context: Context): File? {
private fun getLogFile(context: Context): File? {
return try {
val file = File(context.filesDir, "logs.txt")
if (sessionLogsFile != null) {
return sessionLogsFile
}
val file = File(context.filesDir, LOGS_FILE)
file.delete()
file.createNewFile()
@ -57,7 +86,8 @@ class FeedbackManager(
fileWriter.write(stringWriter.toString())
fileWriter.close()
logCollector.clearLogs()
file
sessionLogsFile = file
sessionLogsFile
} catch (ex: Exception) {
Timber.e(ex, "Can't create the logs file")
null
@ -75,5 +105,7 @@ class FeedbackManager(
companion object {
const val DEFAULT_SUPPORT_EMAIL = "support@tangem.com"
const val S2C_SUPPORT_EMAIL = "cardsupport@start2coin.com"
const val FEEDBACK_FILE = "feedback.txt"
const val LOGS_FILE = "logs.txt"
}
}