Skip to content

Commit

Permalink
[i116] Extend PushMessage to access extra data (#4945)
Browse files Browse the repository at this point in the history
* [i116] Extend PushMessage to access extra data

* [i116] add CHANGELOG
  • Loading branch information
kanat authored Sep 5, 2023
1 parent 674dd55 commit 4caa048
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- Fixed NPE in `StreamWebSocket.onFailure`. [#4942](https://github.com/GetStream/stream-chat-android/pull/4942)

### ⬆️ Improved
- Extended `PushMessage` to access extra data [#4945](https://github.com/GetStream/stream-chat-android/pull/4945)

### ✅ Added

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ object Versions {
internal const val SPOTLESS = "6.20.0"
internal const val STFALCON_IMAGE_VIEWER = "1.0.1"
internal const val STREAM_LOG = "1.1.4"
internal const val STREAM_PUSH = "1.1.3"
internal const val STREAM_PUSH = "1.1.4"
internal const val STREAM_RESULT = "1.1.0"
internal const val TEST_PARAMETER_INJECTOR = "1.12"
internal const val THREETENBP = "1.6.8"
Expand Down
1 change: 1 addition & 0 deletions stream-chat-android-client/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<ID>MaxLineLength:StringExtensionsKtTest.kt$StringExtensionsKtTest.Companion$"https://us-east.stream-io-cdn.com/1/images/IMAGE_NAME.jpg?Key-Pair-Id=SODHGWNRLG&amp;Policy=akIjUneI9Kmbds2&amp;Signature=dsnIjJ8-gfdgihih8-GkhdfgfdGFG32--KHJDFj349sfsdf~SFDf2~Fsdfgrg3~kjnooi23Jig-Kjoih34iW~k7Jbe2~Jnk33j-Fsiniiz2~Sfj23iJihn-Jinfnsiw2kS&amp;oh=$originalHeight&amp;ow=$originalWidth"</ID>
<ID>MaxLineLength:WaveformExtractor.kt$WaveformExtractor$logger.v { "[handle16bit] this.totalSamples: $totalSamples, sampleRate: $sampleRate, duration: $durationInSeconds" }</ID>
<ID>SwallowedException:WaveformExtractor.kt$WaveformExtractor$e: Exception</ID>
<ID>TooGenericExceptionCaught:StreamPayloadParser.kt$StreamPayloadParser$e: Throwable</ID>
<ID>TooGenericExceptionCaught:WaveformExtractor.kt$WaveformExtractor$e: Exception</ID>
<ID>UnusedPrivateMember:StreamAudioPlayer.kt$StreamMediaPlayer$private fun normalize(uri: String): String</ID>
</CurrentIssues>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import io.getstream.android.push.PushProvider
import io.getstream.android.push.delegate.PushDelegate
import io.getstream.chat.android.client.ChatClient
import io.getstream.chat.android.client.PayloadValidator
import io.getstream.chat.android.client.notifications.parser.StreamPayloadParser
import io.getstream.chat.android.models.Device
import io.getstream.chat.android.models.PushMessage
private typealias DevicePushProvider = io.getstream.chat.android.models.PushProvider
Expand All @@ -33,13 +34,19 @@ private typealias DevicePushProvider = io.getstream.chat.android.models.PushProv
*/
@Suppress("Unused")
internal class ChatPushDelegate(context: Context) : PushDelegate(context) {
override fun handlePushMessage(payload: Map<String, Any?>): Boolean =

private val expectedKeys = hashSetOf(KEY_CHANNEL_ID, KEY_MESSAGE_ID, KEY_CHANNEL_TYPE, KEY_GETSTREAM)

override fun handlePushMessage(metadata: Map<String, Any?>, payload: Map<String, Any?>): Boolean =
payload.ifValid {
ChatClient.handlePushMessage(
PushMessage(
channelId = payload.getValue("channel_id") as String,
messageId = payload.getValue("message_id") as String,
channelType = payload.getValue("channel_type") as String,
channelId = payload.getValue(KEY_CHANNEL_ID) as String,
messageId = payload.getValue(KEY_MESSAGE_ID) as String,
channelType = payload.getValue(KEY_CHANNEL_TYPE) as String,
getstream = StreamPayloadParser.parse(payload[KEY_GETSTREAM] as? String),
extraData = payload.filterKeys { it !in expectedKeys },
metadata = metadata,
),
)
}
Expand All @@ -54,6 +61,13 @@ internal class ChatPushDelegate(context: Context) : PushDelegate(context) {
effect.takeIf { isValid }?.invoke()
return isValid
}

private companion object {
private const val KEY_CHANNEL_ID = "channel_id"
private const val KEY_MESSAGE_ID = "message_id"
private const val KEY_CHANNEL_TYPE = "channel_type"
private const val KEY_GETSTREAM = "getstream"
}
}

internal fun PushDevice.toDevice(): Device =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2014-2023 Stream.io Inc. All rights reserved.
*
* Licensed under the Stream License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.getstream.chat.android.client.notifications.parser

import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import io.getstream.chat.android.core.internal.InternalStreamChatApi
import io.getstream.log.StreamLog

/**
* Helper class for parsing the payload of a push message.
*/
@InternalStreamChatApi
public object StreamPayloadParser {

private const val TAG = "StreamPayloadParser"

private val mapAdapter: JsonAdapter<MutableMap<String, Any?>> by lazy {
Moshi.Builder()
.build()
.adapter(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java))
}

/**
* Parses the [json] string into a [Map] of [String] to [Any].
*/
public fun parse(json: String?): Map<String, Any?> {
return try {
json?.takeIf { it.isNotBlank() }?.let { mapAdapter.fromJson(it) } ?: emptyMap()
} catch (e: Throwable) {
StreamLog.e(TAG, e) { "[parse] failed: $json" }
emptyMap()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2014-2023 Stream.io Inc. All rights reserved.
*
* Licensed under the Stream License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.getstream.chat.android.client.notifications.parser

import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test

public class StreamPayloadParserTest {

@Test
public fun parseNullContent() {
val parsedMap = StreamPayloadParser.parse(null)
parsedMap shouldBeEqualTo emptyMap()
}

@Test
public fun parseEmptyContent() {
val jsonString = ""

val parsedMap = StreamPayloadParser.parse(jsonString)
parsedMap shouldBeEqualTo emptyMap()
}

@Test
public fun parseExpectedContent() {
val jsonString = """{
"file_type": "file",
"message": "Retro",
"sender_name": "Dmitrii Bychkov",
"unread_message_count": "8",
"nested_object": {
"key1": "value1",
"key2": "value2",
"key3": null,
"key4": "null"
},
"nested_array": [
"item1",
"item2",
"item3"
]
}"""

val parsedMap = StreamPayloadParser.parse(jsonString)
parsedMap shouldBeEqualTo mapOf(
"file_type" to "file",
"message" to "Retro",
"sender_name" to "Dmitrii Bychkov",
"unread_message_count" to "8",
"nested_object" to mapOf(
"key1" to "value1",
"key2" to "value2",
"key3" to null,
"key4" to "null",
),
"nested_array" to listOf(
"item1",
"item2",
"item3",
),
)
}
}
12 changes: 9 additions & 3 deletions stream-chat-android-core/api/stream-chat-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -1297,16 +1297,22 @@ public final class io/getstream/chat/android/models/OrFilterObject : io/getstrea
}

public final class io/getstream/chat/android/models/PushMessage {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Ljava/lang/String;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lio/getstream/chat/android/models/PushMessage;
public static synthetic fun copy$default (Lio/getstream/chat/android/models/PushMessage;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lio/getstream/chat/android/models/PushMessage;
public final fun component4 ()Ljava/util/Map;
public final fun component5 ()Ljava/util/Map;
public final fun component6 ()Ljava/util/Map;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)Lio/getstream/chat/android/models/PushMessage;
public static synthetic fun copy$default (Lio/getstream/chat/android/models/PushMessage;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;ILjava/lang/Object;)Lio/getstream/chat/android/models/PushMessage;
public fun equals (Ljava/lang/Object;)Z
public final fun getChannelId ()Ljava/lang/String;
public final fun getChannelType ()Ljava/lang/String;
public final fun getExtraData ()Ljava/util/Map;
public final fun getGetstream ()Ljava/util/Map;
public final fun getMessageId ()Ljava/lang/String;
public final fun getMetadata ()Ljava/util/Map;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ public data class PushMessage(
val messageId: String,
val channelId: String,
val channelType: String,
val getstream: Map<String, Any?>,
val extraData: Map<String, Any?>,
val metadata: Map<String, Any?>,
)

0 comments on commit 4caa048

Please sign in to comment.