Skip to content

Commit

Permalink
Some fixes for custom message payloads (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
wkal-pubnub authored Aug 26, 2024
1 parent b8ff729 commit d3abb18
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 32 deletions.
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ benmanes-versions = { id = "com.github.ben-manes.versions", version = "0.42.0" }
vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktech" }
gradle-nexus-publish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexus" }
kotlinx-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.16.2" }
mokkery = { id = "dev.mokkery", version = "2.0.0" }
mokkery = { id = "dev.mokkery", version = "2.2.0" }
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Tue Apr 09 13:01:56 CEST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
8 changes: 4 additions & 4 deletions pubnub-chat-api/api/pubnub-chat-api.api
Original file line number Diff line number Diff line change
Expand Up @@ -276,12 +276,12 @@ public final class com/pubnub/chat/config/ChatConfigurationKt {

public final class com/pubnub/chat/config/CustomPayloads {
public fun <init> ()V
public fun <init> (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Ljava/lang/String;)V
public synthetic fun <init> (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Ljava/lang/String;Ljava/lang/String;)V
public synthetic fun <init> (Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getDeleteMessageActionName ()Ljava/lang/String;
public final fun getEditMessageActionName ()Ljava/lang/String;
public final fun getGetMessagePublishBody ()Lkotlin/jvm/functions/Function2;
public final fun getGetMessageResponseBody ()Lkotlin/jvm/functions/Function1;
public final fun getGetMessagePublishBody ()Lkotlin/jvm/functions/Function3;
public final fun getGetMessageResponseBody ()Lkotlin/jvm/functions/Function3;
}

public final class com/pubnub/chat/config/LogLevel : java/lang/Enum {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@ import com.pubnub.api.JsonElement
import com.pubnub.chat.types.EventContent

class CustomPayloads(
val getMessagePublishBody: ((m: EventContent.TextMessageContent, channelId: String) -> Map<String, Any?>)? = null,
val getMessagePublishBody: (
(
m: EventContent.TextMessageContent,
channelId: String,
defaultMessagePublishBody: (m: EventContent.TextMessageContent) -> Map<String, Any?>
) -> Map<String, Any?>
)? = null,
val getMessageResponseBody: (
(m: JsonElement) -> EventContent.TextMessageContent
)? = null, // todo do we have tests that checks this functionality
(
m: JsonElement,
channelId: String,
defaultMessageResponseBody: (m: JsonElement) -> EventContent.TextMessageContent?
) -> EventContent.TextMessageContent?
)? = null,
val editMessageActionName: String? = null,
val deleteMessageActionName: String? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal val MINIMAL_TYPING_INDICATOR_TIMEOUT: Duration = 1.seconds
internal const val THREAD_ROOT_ID = "threadRootId"
internal const val INTERNAL_ADMIN_CHANNEL = "PUBNUB_INTERNAL_ADMIN_CHANNEL"

fun defaultGetMessagePublishBody(m: EventContent.TextMessageContent, channelId: String): Map<String, Any> =
fun defaultGetMessagePublishBody(m: EventContent.TextMessageContent): Map<String, Any> =
PNDataEncoder.encode(m as EventContent) as Map<String, Any>

fun defaultGetMessageResponseBody(message: JsonElement): EventContent.TextMessageContent? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,12 @@ abstract class BaseChannel<C : Channel, M : Message>(
usePost = usePost,
ttl = ttl,
).then { publishResult: PNPublishResult ->
try {
mentionedUsers?.forEach {
emitUserMention(it.value.id, publishResult.timetoken, text).async {}
mentionedUsers?.forEach {
emitUserMention(it.value.id, publishResult.timetoken, text).async {
it.onFailure { ex ->
log.warn(err = ex, msg = { ex.message })
}
}
} catch (e: Exception) {
log.error(err = e, msg = {})
}
publishResult
}
Expand Down Expand Up @@ -406,7 +406,7 @@ abstract class BaseChannel<C : Channel, M : Message>(
try {
if (
(
chat.config.customPayloads?.getMessageResponseBody?.invoke(pnMessageResult.message)
chat.config.customPayloads?.getMessageResponseBody?.invoke(pnMessageResult.message, pnMessageResult.channel, ::defaultGetMessageResponseBody)
?: defaultGetMessageResponseBody(pnMessageResult.message)
) == null
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ data class MessageImpl(
companion object {
internal fun fromDTO(chat: ChatInternal, pnMessageResult: PNMessageResult): Message {
val content =
chat.config.customPayloads?.getMessageResponseBody?.invoke(pnMessageResult.message)
chat.config.customPayloads?.getMessageResponseBody?.invoke(pnMessageResult.message, pnMessageResult.channel, ::defaultGetMessageResponseBody)
?: defaultGetMessageResponseBody(pnMessageResult.message)
?: EventContent.UnknownMessageFormat(pnMessageResult.message)
return MessageImpl(
Expand All @@ -58,7 +58,7 @@ data class MessageImpl(

internal fun fromDTO(chat: ChatInternal, messageItem: PNFetchMessageItem, channelId: String): Message {
val content =
chat.config.customPayloads?.getMessageResponseBody?.invoke(messageItem.message)
chat.config.customPayloads?.getMessageResponseBody?.invoke(messageItem.message, channelId, ::defaultGetMessageResponseBody)
?: defaultGetMessageResponseBody(messageItem.message)
?: EventContent.UnknownMessageFormat(messageItem.message)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ data class ThreadMessageImpl(

internal fun fromDTO(chat: ChatImpl, pnMessageResult: PNMessageResult, parentChannelId: String): ThreadMessage {
val content =
chat.config.customPayloads?.getMessageResponseBody?.invoke(pnMessageResult.message)
chat.config.customPayloads?.getMessageResponseBody?.invoke(pnMessageResult.message, pnMessageResult.channel, ::defaultGetMessageResponseBody)
?: defaultGetMessageResponseBody(pnMessageResult.message)
?: EventContent.UnknownMessageFormat(pnMessageResult.message)
return ThreadMessageImpl(
Expand All @@ -73,7 +73,7 @@ data class ThreadMessageImpl(

internal fun fromDTO(chat: ChatInternal, messageItem: PNFetchMessageItem, channelId: String, parentChannelId: String): ThreadMessage {
val content =
chat.config.customPayloads?.getMessageResponseBody?.invoke(messageItem.message)
chat.config.customPayloads?.getMessageResponseBody?.invoke(messageItem.message, channelId, ::defaultGetMessageResponseBody)
?: defaultGetMessageResponseBody(messageItem.message)
?: EventContent.UnknownMessageFormat(messageItem.message)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,16 @@ internal fun Any?.tryDouble(): Double? {

internal fun EventContent.TextMessageContent.encodeForSending(
channelId: String,
getMessagePublishBody: ((m: EventContent.TextMessageContent, channelId: String) -> Map<String, Any?>)? = null,
getMessagePublishBody: (
(
m: EventContent.TextMessageContent,
channelId: String,
defaultMessagePublishBody: (m: EventContent.TextMessageContent) -> Map<String, Any?>
) -> Map<String, Any?>
)? = null,
mergeMessageWith: Map<String, Any>? = null,
): Map<String, Any?> {
var finalMessage = getMessagePublishBody?.invoke(this, channelId) ?: defaultGetMessagePublishBody(this, channelId)
var finalMessage = getMessagePublishBody?.invoke(this, channelId, ::defaultGetMessagePublishBody) ?: defaultGetMessagePublishBody(this)
if (mergeMessageWith != null) {
finalMessage = buildMap {
putAll(finalMessage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class ChannelIntegrationTest : BaseChatIntegrationTest() {

pubnub.test(backgroundScope, checkAllEvents = false) {
val joinResult = CompletableDeferred<JoinResult>()
pubnub.awaitSubscribe {
pubnub.awaitSubscribe(listOf(channel.id)) {
channel.join { receivedMessage ->
message.complete(receivedMessage)
}.async {
Expand Down Expand Up @@ -124,7 +124,7 @@ class ChannelIntegrationTest : BaseChatIntegrationTest() {

pubnub.test(backgroundScope, checkAllEvents = false) {
var unsubscribe: AutoCloseable? = null
pubnub.awaitSubscribe {
pubnub.awaitSubscribe(listOf(channel.id)) {
unsubscribe = channel.connect {
message.complete(it)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,27 @@ import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse

class ChatConfigurationIntegrationTest : BaseChatIntegrationTest() {
@Test
fun custom_payloads_send_receive_msgs() = runTest {
val chat = ChatImpl(
ChatConfiguration(
customPayloads = CustomPayloads(
getMessagePublishBody = { content, channelId ->
getMessagePublishBody = { content, _, _ ->
mapOf(
"custom" to mapOf(
"payload" to mapOf(
"text" to content.text
)
),
"files" to content.files,
// "type" to "text"
)
},
getMessageResponseBody = { json: JsonElement ->
getMessageResponseBody = { json: JsonElement, _, _ ->
EventContent.TextMessageContent(
json.asMap()?.get("custom")?.asMap()?.get("payload")?.asMap()?.get("text")?.asString()!!,
json.asList()?.map {
json.asMap()?.get("files")?.asList()?.map {
File(
it.asMap()?.get("name")?.asString()!!,
it.asMap()?.get("id")?.asString()!!,
Expand All @@ -58,14 +56,77 @@ class ChatConfigurationIntegrationTest : BaseChatIntegrationTest() {

pubnub.test(backgroundScope, checkAllEvents = false) {
var unsubscribe: AutoCloseable? = null
pubnub.awaitSubscribe {
pubnub.awaitSubscribe(listOf(channel.id)) {
unsubscribe = channel.connect {
message.complete(it)
}
}
channel.sendText(messageText).await()
assertEquals(messageText, message.await().text)
assertFalse(channel.getMembers().await().members.any { it.user.id == chat.currentUser.id })
unsubscribe?.close()
}
}

@Test
fun custom_payloads_send_receive_msgs_single_channel() = runTest {
val chat = ChatImpl(
ChatConfiguration(
customPayloads = CustomPayloads(
getMessagePublishBody = { content, channelId, default ->
if (channelId == channel01.id) {
mapOf(
"custom" to mapOf(
"payload" to mapOf(
"text" to content.text
)
),
"files" to content.files,
)
} else {
default(content)
}
},
getMessageResponseBody = { json: JsonElement, channelId, default ->
if (channelId == channel01.id) {
EventContent.TextMessageContent(
json.asMap()?.get("custom")?.asMap()?.get("payload")?.asMap()?.get("text")
?.asString()!!,
json.asMap()?.get("files")?.asList()?.map {
File(
it.asMap()?.get("name")?.asString()!!,
it.asMap()?.get("id")?.asString()!!,
it.asMap()?.get("url")?.asString()!!,
it.asMap()?.get("type")?.asString(),
)
}
)
} else {
default(json)
}
}
)
),
pubnub
).initialize().await()
chat.createChannel(channel01.id).await()
chat.createChannel(channel02.id).await()
val messageText = randomString()
val message = CompletableDeferred<Message>()
val message2 = CompletableDeferred<Message>()

pubnub.test(backgroundScope, checkAllEvents = false) {
var unsubscribe: AutoCloseable? = null
pubnub.awaitSubscribe(listOf(channel01.id, channel02.id)) {
unsubscribe = channel01.connect {
message.complete(it)
}
unsubscribe = channel02.connect {
message2.complete(it)
}
}
channel01.sendText(messageText).await()
channel02.sendText(messageText).await()
assertEquals(messageText, message.await().text)
unsubscribe?.close()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ class ChatIntegrationTest : BaseChatIntegrationTest() {
var tt: Long = 0
pubnub.test(backgroundScope, checkAllEvents = false) {
var unsubscribe: AutoCloseable? = null
pubnub.awaitSubscribe {
pubnub.awaitSubscribe(listOf(channel.id)) {
unsubscribe = chat.listenForEvents<EventContent.Custom>(channel.id) {
event.complete(it)
}
Expand Down

0 comments on commit d3abb18

Please sign in to comment.