diff --git a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/Event.kt b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/Event.kt index f6bcd29..3b6a2c7 100644 --- a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/Event.kt +++ b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/Event.kt @@ -15,5 +15,5 @@ data class Event( override var timeStamp: String, override var contentType: String, override var id: String, - override var serializedContent: Map? = null + override var serializedContent: String? = null ) : TranscriptItem(id, timeStamp, contentType, serializedContent), EventProtocol diff --git a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/Message.kt b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/Message.kt index 451e19b..d703b0f 100644 --- a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/Message.kt +++ b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/Message.kt @@ -21,7 +21,7 @@ data class Message( override var id: String, override var timeStamp: String, override var contentType: String, - override var serializedContent: Map? = null, + override var serializedContent: String? = null, override var participant: String, override var text: String, override var displayName: String? = null, diff --git a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/MessageMetadata.kt b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/MessageMetadata.kt index f33bb7b..919154c 100644 --- a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/MessageMetadata.kt +++ b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/MessageMetadata.kt @@ -20,5 +20,5 @@ data class MessageMetadata( override var timeStamp: String, override var contentType: String, override var id: String, - override var serializedContent: Map? = null + override var serializedContent: String? = null ) : TranscriptItem(id, timeStamp, contentType, serializedContent), MessageMetadataProtocol diff --git a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/TranscriptItem.kt b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/TranscriptItem.kt index 6135436..ca7b236 100644 --- a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/TranscriptItem.kt +++ b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/model/TranscriptItem.kt @@ -4,14 +4,14 @@ interface TranscriptItemProtocol { val id: String val timeStamp: String var contentType: String - var serializedContent: Map? + var serializedContent: String? } open class TranscriptItem( override var id: String, override var timeStamp: String, override var contentType: String, - override var serializedContent: Map? = null + override var serializedContent: String? = null ) : TranscriptItemProtocol { internal fun updateId(newId: String) { diff --git a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/network/MessageReceiptsManager.kt b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/network/MessageReceiptsManager.kt index 4e5ce05..60f2053 100644 --- a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/network/MessageReceiptsManager.kt +++ b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/network/MessageReceiptsManager.kt @@ -3,6 +3,7 @@ package com.amazon.connect.chat.sdk.network import android.util.Log import com.amazon.connect.chat.sdk.model.MessageReceiptType import com.amazon.connect.chat.sdk.model.MessageReceipts +import com.amazon.connect.chat.sdk.utils.logger.SDKLogger import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -32,14 +33,12 @@ data class PendingMessageReceipts( var readReceiptMessageId: String? = null ) { fun clear() { - Log.d("PendingMessageReceipts", "Clearing pending message receipts.") deliveredReceiptMessageId = null readReceiptMessageId = null } fun checkAndRemoveDuplicateReceipt() { if (deliveredReceiptMessageId == readReceiptMessageId) { - Log.d("PendingMessageReceipts", "Duplicate receipt found. Removing delivered receipt for messageId: $deliveredReceiptMessageId") deliveredReceiptMessageId = null } } @@ -64,10 +63,8 @@ class MessageReceiptsManagerImpl : MessageReceiptsManager { messageId: String ): Result = suspendCancellableCoroutine { continuation -> - Log.d("MessageReceiptsManager", "Attempting to send message receipt for messageId: $messageId with event: $event") - if (!shouldSendMessageReceipts) { - Log.d("MessageReceiptsManager", "Sending message receipts is disabled.") + SDKLogger.logger.logDebug { "Sending message receipts is disabled." } continuation.resume(Result.failure(Exception("Sending message receipts is disabled"))) return@suspendCancellableCoroutine } @@ -76,7 +73,6 @@ class MessageReceiptsManagerImpl : MessageReceiptsManager { // Cancel the previous job if it's still active throttleJob?.cancel() - Log.d("MessageReceiptsManager", "Cancelled existing throttle job.") if (pendingMessageReceipts.readReceiptMessageId == null && pendingMessageReceipts.deliveredReceiptMessageId == null && numPendingDeliveredReceipts == 0) { return@suspendCancellableCoroutine @@ -86,43 +82,35 @@ class MessageReceiptsManagerImpl : MessageReceiptsManager { throttleJob = CoroutineScope(Dispatchers.Default).launch { delay((throttleTime * 1000).toLong()) try { - Log.d("MessageReceiptsManager", "Throttling with interval: ${throttleTime * 1000}ms") pendingMessageReceipts.checkAndRemoveDuplicateReceipt() - Log.d("MessageReceiptsManager", "Resuming continuation with pending receipts.") continuation.resume(Result.success(pendingMessageReceipts)) } catch (e: Exception) { - Log.e("MessageReceiptsManager", "Error during throttling: ${e.message}", e) + SDKLogger.logger.logError { "Error during throttling: ${e.message}" } continuation.resumeWithException(e) } } } override fun invalidateTimer() { - Log.d("MessageReceiptsManager", "Invalidating timer.") timer?.cancel() timer = null } override fun handleMessageReceipt(event: MessageReceiptType, messageId: String) { - Log.d("MessageReceiptsManager", "Handling message receipt for messageId: $messageId with event: $event") when (event) { MessageReceiptType.MESSAGE_DELIVERED -> { if (deliveredReceiptSet.contains(messageId) || readReceiptSet.contains(messageId)) { - Log.d("MessageReceiptsManager", "Receipt already handled for messageId: $messageId") return } deliveredReceiptSet.add(messageId) - Log.d("MessageReceiptsManager", "Added messageId: $messageId to deliveredReceiptSet") CoroutineScope(Dispatchers.Default).launch { - Log.d("MessageReceiptsManager", "Scheduling delivery throttle for messageId: $messageId with interval: ${deliveredThrottleTime * 1000}ms") numPendingDeliveredReceipts++ delay((deliveredThrottleTime * 1000).toLong()) if (readReceiptSet.contains(messageId)) { - Log.d("MessageReceiptsManager", "Read receipt already sent for messageId: $messageId") + SDKLogger.logger.logDebug { "Read receipt already sent for messageId: $messageId" } } else { - Log.d("MessageReceiptsManager", "Setting delivered receipt to pending for messageId: $messageId") pendingMessageReceipts.deliveredReceiptMessageId = messageId } numPendingDeliveredReceipts-- @@ -130,10 +118,8 @@ class MessageReceiptsManagerImpl : MessageReceiptsManager { } MessageReceiptType.MESSAGE_READ -> { if (readReceiptSet.contains(messageId)) { - Log.d("MessageReceiptsManager", "Read receipt already sent for messageId: $messageId") return } - Log.d("MessageReceiptsManager", "Adding messageId: $messageId to readReceiptSet") readReceiptSet.add(messageId) pendingMessageReceipts.readReceiptMessageId = messageId } diff --git a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/network/WebSocketManager.kt b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/network/WebSocketManager.kt index aa9da3b..9ce09b8 100644 --- a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/network/WebSocketManager.kt +++ b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/network/WebSocketManager.kt @@ -259,22 +259,22 @@ class WebSocketManagerImpl @Inject constructor( val type = WebSocketMessageType.fromType(typeString) return when (type) { - WebSocketMessageType.MESSAGE -> handleMessage(jsonObject) + WebSocketMessageType.MESSAGE -> handleMessage(jsonObject, jsonString) WebSocketMessageType.EVENT -> { val eventTypeString = jsonObject.optString("ContentType") when (val eventType = ContentType.fromType(eventTypeString)) { - ContentType.JOINED -> handleParticipantEvent(jsonObject) - ContentType.LEFT -> handleParticipantEvent(jsonObject) - ContentType.TYPING -> handleTyping(jsonObject) - ContentType.ENDED -> handleChatEnded(jsonObject) + ContentType.JOINED -> handleParticipantEvent(jsonObject, jsonString) + ContentType.LEFT -> handleParticipantEvent(jsonObject, jsonString) + ContentType.TYPING -> handleTyping(jsonObject, jsonString) + ContentType.ENDED -> handleChatEnded(jsonObject, jsonString) else -> { Log.w("WebSocket", "Unknown event: $eventType") null } } } - WebSocketMessageType.ATTACHMENT -> handleAttachment(jsonObject) - WebSocketMessageType.MESSAGE_METADATA -> handleMetadata(jsonObject) + WebSocketMessageType.ATTACHMENT -> handleAttachment(jsonObject, jsonString) + WebSocketMessageType.MESSAGE_METADATA -> handleMetadata(jsonObject, jsonString) else -> { Log.w("WebSocket", "Unknown websocket message type: $type") null @@ -354,7 +354,7 @@ class WebSocketManagerImpl @Inject constructor( // --- Helper Methods for websocket data --- - private fun handleMessage(innerJson: JSONObject): TranscriptItem { + private fun handleMessage(innerJson: JSONObject, rawData: String): TranscriptItem { val participantRole = innerJson.getString("ParticipantRole") val messageId = innerJson.getString("Id") val messageText = innerJson.getString("Content") @@ -368,12 +368,13 @@ class WebSocketManagerImpl @Inject constructor( contentType = innerJson.getString("ContentType"), timeStamp = time, id = messageId, - displayName = displayName + displayName = displayName, + serializedContent = rawData ) return message } - private fun handleParticipantEvent(innerJson: JSONObject): TranscriptItem { + private fun handleParticipantEvent(innerJson: JSONObject, rawData: String): TranscriptItem { val participantRole = innerJson.getString("ParticipantRole") val displayName = innerJson.getString("DisplayName") val time = innerJson.getString("AbsoluteTime") @@ -387,11 +388,12 @@ class WebSocketManagerImpl @Inject constructor( text = innerJson.getString("ContentType"), // TODO: Need to be removed and replaced in UI once callbacks are hooked contentType = innerJson.getString("ContentType"), eventDirection = MessageDirection.COMMON, + serializedContent = rawData ) return event } - private fun handleTyping(innerJson: JSONObject): TranscriptItem { + private fun handleTyping(innerJson: JSONObject, rawData: String): TranscriptItem { val participantRole = innerJson.getString("ParticipantRole") val time = innerJson.getString("AbsoluteTime") val displayName = innerJson.getString("DisplayName") @@ -402,12 +404,13 @@ class WebSocketManagerImpl @Inject constructor( contentType = innerJson.getString("ContentType"), id = eventId, displayName = displayName, - participant = participantRole + participant = participantRole, + serializedContent = rawData, ) return event } - private suspend fun handleChatEnded(innerJson: JSONObject): TranscriptItem { + private suspend fun handleChatEnded(innerJson: JSONObject, rawData: String): TranscriptItem { closeWebSocket("Chat Ended"); isChatActive = false; this._eventPublisher.emit(ChatEvent.ChatEnded) @@ -417,12 +420,13 @@ class WebSocketManagerImpl @Inject constructor( timeStamp = time, contentType = innerJson.getString("ContentType"), id = eventId, - eventDirection = MessageDirection.COMMON + eventDirection = MessageDirection.COMMON, + serializedContent = rawData ) return event } - private fun handleMetadata(innerJson: JSONObject): TranscriptItem { + private fun handleMetadata(innerJson: JSONObject, rawData: String): TranscriptItem { val messageMetadata = innerJson.getJSONObject("MessageMetadata") val messageId = messageMetadata.getString("MessageId") val receipts = messageMetadata.optJSONArray("Receipts") @@ -442,12 +446,13 @@ class WebSocketManagerImpl @Inject constructor( eventDirection = MessageDirection.OUTGOING, timeStamp = time, id = messageId, - status = status + status = status, + serializedContent = rawData ) return metadata } - private fun handleAttachment(innerJson: JSONObject): TranscriptItem? { + private fun handleAttachment(innerJson: JSONObject, rawData: String): TranscriptItem? { val participantRole = innerJson.getString("ParticipantRole") val time = innerJson.getString("AbsoluteTime") val displayName = innerJson.getString("DisplayName") @@ -481,7 +486,8 @@ class WebSocketManagerImpl @Inject constructor( timeStamp = time, attachmentId = attachmentId, id = messageId, - displayName = displayName + displayName = displayName, + serializedContent = rawData ) } diff --git a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/utils/TranscriptItemUtils.kt b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/utils/TranscriptItemUtils.kt index 6a37ca7..d5d4590 100644 --- a/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/utils/TranscriptItemUtils.kt +++ b/chat-sdk/src/main/java/com/amazon/connect/chat/sdk/utils/TranscriptItemUtils.kt @@ -10,7 +10,6 @@ import com.amazon.connect.chat.sdk.model.Message import com.amazon.connect.chat.sdk.model.MessageDirection import com.amazon.connect.chat.sdk.model.MessageMetadata import com.amazon.connect.chat.sdk.model.MessageStatus -import com.amazon.connect.chat.sdk.model.TranscriptItem import com.amazonaws.services.connectparticipant.model.Item import org.json.JSONObject import java.util.UUID @@ -20,11 +19,7 @@ object TranscriptItemUtils { fun createDummyEndedEvent(): Event { val isoTime = CommonUtils.getCurrentISOTime() - val serializedContent = mapOf( - "content" to "{\"AbsoluteTime\":\"$isoTime\",\"ContentType\":\"application/vnd.amazonaws.connect.event.chat.ended\",\"Id\":\"chat-ended-event\",\"Type\":\"EVENT\",\"InitialContactId\":\"chat-ended-event-id\"}", - "topic" to "aws/chat", - "contentType" to "application/json" - ) + val serializedContent = "{\"AbsoluteTime\":\"$isoTime\",\"ContentType\":\"application/vnd.amazonaws.connect.event.chat.ended\",\"Id\":\"chat-ended-event\",\"Type\":\"EVENT\",\"InitialContactId\":\"chat-ended-event-id\"}" return Event( text = null, @@ -54,14 +49,14 @@ object TranscriptItemUtils { attachmentId = attachmentId, id = randomId, displayName = displayName, - serializedContent = emptyMap(), + serializedContent = "", metadata = MessageMetadata( id = randomId, status = status, timeStamp = isoTime, contentType = contentType, eventDirection = MessageDirection.OUTGOING, - serializedContent = emptyMap() + serializedContent = "" ) ) }