diff --git a/lib/src/main/kotlin/push/kotlin/sdk/Env.kt b/lib/src/main/kotlin/push/kotlin/sdk/Env.kt index a2bdc81..dcdb41a 100644 --- a/lib/src/main/kotlin/push/kotlin/sdk/Env.kt +++ b/lib/src/main/kotlin/push/kotlin/sdk/Env.kt @@ -131,6 +131,9 @@ object PushURI { fun getSubscribers(channel: String, page: Number, limit: Number, env: ENV): String { return "${getBaseUri(env)}/channels/${channel}/subscribers?&page=${page}&limit=${limit}" } + fun getChannelNotifications(channel: String, query: String, env: ENV): String { + return "${getBaseUri(env, version = "v2")}/channels/${channel}/notifications?${query}" + } fun isUserSubscribed(env: ENV): String { if (env == ENV.prod){ diff --git a/lib/src/main/kotlin/push/kotlin/sdk/Helpers/Helper.kt b/lib/src/main/kotlin/push/kotlin/sdk/Helpers/Helper.kt index 617a735..db866d7 100644 --- a/lib/src/main/kotlin/push/kotlin/sdk/Helpers/Helper.kt +++ b/lib/src/main/kotlin/push/kotlin/sdk/Helpers/Helper.kt @@ -60,6 +60,10 @@ class Helpers { return WalletUtils.isValidAddress(address) } + fun getQueryParams(params: Map): String { + return params.entries.joinToString("&") { "${it.key}=${it.value}" } + } + } } diff --git a/lib/src/main/kotlin/push/kotlin/sdk/PushAPI/GroupParticipants.kt b/lib/src/main/kotlin/push/kotlin/sdk/PushAPI/GroupParticipants.kt index 6c89c69..0be2b9e 100644 --- a/lib/src/main/kotlin/push/kotlin/sdk/PushAPI/GroupParticipants.kt +++ b/lib/src/main/kotlin/push/kotlin/sdk/PushAPI/GroupParticipants.kt @@ -46,7 +46,7 @@ class GroupParticipants( page = options.page, pending = options.filter?.pending, limit = options.limit, - role = if (options.filter?.role == Group.GroupRoles.MEMBER) "admin" else "member", + role = if (options.filter?.role == Group.GroupRoles.ADMIN) "admin" else "member", ), env ) diff --git a/lib/src/main/kotlin/push/kotlin/sdk/PushAPI/PushAPI.kt b/lib/src/main/kotlin/push/kotlin/sdk/PushAPI/PushAPI.kt index ae01a8a..73537d9 100644 --- a/lib/src/main/kotlin/push/kotlin/sdk/PushAPI/PushAPI.kt +++ b/lib/src/main/kotlin/push/kotlin/sdk/PushAPI/PushAPI.kt @@ -2,6 +2,7 @@ package push.kotlin.sdk.PushAPI import push.kotlin.sdk.DecryptPgp import push.kotlin.sdk.ENV +import push.kotlin.sdk.PushNotification.ChannelAPI import push.kotlin.sdk.PushUser import push.kotlin.sdk.Signer @@ -15,15 +16,23 @@ class PushAPI( ) { var chat: Chat var profile: Profile + var channel: ChannelAPI init { chat = Chat(account, env, decryptedPgpPvtKey, signer) profile = Profile(account, env, decryptedPgpPvtKey, signer) + channel = ChannelAPI(account, env, decryptedPgpPvtKey, signer) } - - data class PushAPIInitializeOptions(val version: PushUser.ENCRYPTION_TYPE = PushUser.ENCRYPTION_TYPE.PGP_V3, val versionMeta: Map>? = null, val autoUpgrade: Boolean = true, val origin: String? = null, val showHttpLog: Boolean = false, val env: ENV = ENV.prod) + data class PushAPIInitializeOptions( + val version: PushUser.ENCRYPTION_TYPE = PushUser.ENCRYPTION_TYPE.PGP_V3, + val versionMeta: Map>? = null, + val autoUpgrade: Boolean = true, + val origin: String? = null, + val showHttpLog: Boolean = false, + val env: ENV = ENV.prod + ) companion object { diff --git a/lib/src/main/kotlin/push/kotlin/sdk/PushNotification/ChannelAPI.kt b/lib/src/main/kotlin/push/kotlin/sdk/PushNotification/ChannelAPI.kt new file mode 100644 index 0000000..d797c8f --- /dev/null +++ b/lib/src/main/kotlin/push/kotlin/sdk/PushNotification/ChannelAPI.kt @@ -0,0 +1,53 @@ +package push.kotlin.sdk.PushNotification + +import push.kotlin.sdk.ENV +import push.kotlin.sdk.Signer +import push.kotlin.sdk.channels.* + +class ChannelAPI( + private val account: String, + val env: ENV, + private val decryptedPgpPvtKey: String, + private val signer: Signer, +) { + + data class ChannelInfoOptions( + val channel: String, + val page: Int = 1, + val limit: Int = 10, + val category: Int? = null, + val setting: Boolean = false, + ) + + + fun info(channel: String): PushChannel? { + return Channel.getChannel(channel, env) + } + + fun search(query: String, page: Int, limit: Int): Result { + return ChannelSearch.searchChannels(query, page, limit, "", env) + } + + fun subscribers(options: ChannelInfoOptions): Result { + return ChannelSubscriber.getSubscribers(options.channel, options.page, options.limit, env) + } + + fun notification(account: String, options: ChannelFeedsOptions = ChannelFeedsOptions()): Result { + + val option = ChannelNotification.GetChannelOptionsType( + channel = account, env = env, page = options.page, limit = options.limit, raw = options.raw, filter = options.filter) + + return ChannelNotification.getChannelNotifications(option) + } + + data class ChannelFeedsOptions( + val page: Int = 1, + val limit: Int = 10, + val raw: Boolean = true, + val filter: NotificationType? = null + ) + + fun list(){ + + } +} \ No newline at end of file diff --git a/lib/src/main/kotlin/push/kotlin/sdk/channels/ChannelNotification.kt b/lib/src/main/kotlin/push/kotlin/sdk/channels/ChannelNotification.kt new file mode 100644 index 0000000..37b3743 --- /dev/null +++ b/lib/src/main/kotlin/push/kotlin/sdk/channels/ChannelNotification.kt @@ -0,0 +1,127 @@ +package push.kotlin.sdk.channels + +import com.google.gson.Gson +import com.google.gson.annotations.SerializedName +import okhttp3.OkHttpClient +import okhttp3.Request +import push.kotlin.sdk.ENV +import push.kotlin.sdk.Helpers +import push.kotlin.sdk.PushURI +import java.net.URL + +enum class NotificationType(val value: Int) { + BROADCAST(1), + TARGETED(3), + SUBSET(4) +} +class ChannelNotification { + companion object { + fun getChannelNotifications(options: GetChannelOptionsType): Result { + val channel = Helpers.walletToCAIP(options.env, options.channel) + val queryParams = Helpers. getQueryParams( + if (options.filter != null) { + mapOf( + "page" to options.page.toString(), + "limit" to options.limit.toString(), + "notificationType" to options.filter.toString(), + "raw" to options.raw.toString() + ) + } else { + mapOf( + "page" to options.page.toString(), + "limit" to options.limit.toString(), + "raw" to options.raw.toString() + ) + } + ) + + val url = PushURI.getChannelNotifications( channel, queryParams, options.env) + val obj = URL(url) + + val client = OkHttpClient() + val request = Request.Builder().url(obj).build() + val response = client.newCall(request).execute() + + return if(response.isSuccessful) { + val jsonResponse = response.body?.string() + val gson = Gson() + val apiResponse = gson.fromJson(jsonResponse, ChannelNotificationsData::class.java) + Result.success(apiResponse) + } else { + Result.failure(IllegalStateException("Error ${response.code} ${response.message}")) + } + } + } + + data class GetChannelOptionsType( + val channel: String, + val env: ENV, + val page: Int = 1, + val limit: Int = 10, + val filter: NotificationType? = null, + val raw: Boolean = true + ) + + + + data class Notification( + val timestamp: String, + val from: String, + val to: List, + @SerializedName("notifID") val notifId: Long, + val channel: Channel, + val meta: Meta, + val message: Message, + val config: Config, + val source: String, + val raw: Raw + ) + + data class Channel( + val name: String, + val icon: String, + val url: String + ) + + data class Meta( + val type: String + ) + + data class Message( + val notification: NotificationData, + val payload: Payload + ) + + data class NotificationData( + val title: String, + val body: String + ) + + data class Payload( + val title: String, + val body: String, + val cta: String, + val embed: String, + val meta: MetaData + ) + + data class MetaData( + val domain: String + ) + + data class Config( + val expiry: String?, // Adjust the type if expiry is not a String + val silent: Boolean, + val hidden: Boolean + ) + + data class Raw( + val verificationProof: String + ) + + data class ChannelNotificationsData( + val notifications: List, + val total: Int + ) + +} \ No newline at end of file diff --git a/lib/src/test/kotlin/push/kotlin/sdk/Channels/ChannelTests.kt b/lib/src/test/kotlin/push/kotlin/sdk/Channels/ChannelTests.kt index 299196c..8d87b84 100644 --- a/lib/src/test/kotlin/push/kotlin/sdk/Channels/ChannelTests.kt +++ b/lib/src/test/kotlin/push/kotlin/sdk/Channels/ChannelTests.kt @@ -4,22 +4,27 @@ import MockEIP712OptOutSigner import MockEIP712OptinSigner import org.junit.jupiter.api.Test import push.kotlin.sdk.ENV -import push.kotlin.sdk.channels.Channel -import push.kotlin.sdk.channels.ChannelOpt -import push.kotlin.sdk.channels.ChannelSearch -import push.kotlin.sdk.channels.ChannelSubscriber +import push.kotlin.sdk.channels.* import kotlin.test.assertEquals class ChannelTests { @Test - fun GettingChannel(){ + fun GettingChannelNotification() { val channelAddress = "0x2AEcb6DeE3652dA1dD6b54D5fd4f7D8F43DaEb78" - val res = Channel.getChannel(channelAddress, ENV.staging)!! + val option = ChannelNotification.GetChannelOptionsType(channel = "0xD8634C39BBFd4033c0d3289C4515275102423681", env = ENV.staging) + val res = ChannelNotification.getChannelNotifications(option).getOrThrow() + assert(res.total > 0) + } + + @Test + fun GettingChannel() { + val channelAddress = "0x2AEcb6DeE3652dA1dD6b54D5fd4f7D8F43DaEb78" + val res = Channel.getChannel(channelAddress, ENV.staging)!! assertEquals(channelAddress, res.channel) } @Test - fun GettingAllChannels () { + fun GettingAllChannels() { val result = Channel.getAllChannels(1, 10, ENV.staging) val expectedCount = 10 assertEquals(expectedCount, result.channels.size) @@ -34,7 +39,7 @@ class ChannelTests { @Test fun SearchChannelByName() { - val res = ChannelSearch.searchChannels(query ="rayan", page= 1, limit = 10, order = "desc", env = ENV.staging ).getOrThrow() + val res = ChannelSearch.searchChannels(query = "rayan", page = 1, limit = 10, order = "desc", env = ENV.staging).getOrThrow() val actual = res.itemcount assertEquals(true, actual > 1) } @@ -49,7 +54,7 @@ class ChannelTests { @Test fun testNoexistingChannelsOnSearch() { - val res = ChannelSearch.searchChannels("rayansdsdsdsd",1, 10, "desc", ENV.staging).getOrThrow() + val res = ChannelSearch.searchChannels("rayansdsdsdsd", 1, 10, "desc", ENV.staging).getOrThrow() val asExpected = 0 assertEquals(asExpected, res.itemcount) } @@ -76,16 +81,16 @@ class ChannelTests { val optOutSinger = MockEIP712OptOutSigner() val userAddress = optInSigner.getAddress().getOrThrow() - var success = ChannelOpt.subscribe( "0x2AEcb6DeE3652dA1dD6b54D5fd4f7D8F43DaEb78", userAddress, optInSigner, ENV.staging).getOrThrow() + var success = ChannelOpt.subscribe("0x2AEcb6DeE3652dA1dD6b54D5fd4f7D8F43DaEb78", userAddress, optInSigner, ENV.staging).getOrThrow() assert(success) - success = ChannelOpt.unsubscribe( "0x2AEcb6DeE3652dA1dD6b54D5fd4f7D8F43DaEb78", userAddress, optOutSinger, ENV.staging).getOrThrow() + success = ChannelOpt.unsubscribe("0x2AEcb6DeE3652dA1dD6b54D5fd4f7D8F43DaEb78", userAddress, optOutSinger, ENV.staging).getOrThrow() assert(success) - success = ChannelOpt.subscribe( "0x2AEcb6DeE3652dA1dD6b54D5fd4f7D8F43DaEb78", userAddress, optInSigner, ENV.staging).getOrThrow() + success = ChannelOpt.subscribe("0x2AEcb6DeE3652dA1dD6b54D5fd4f7D8F43DaEb78", userAddress, optInSigner, ENV.staging).getOrThrow() assert(success) - success = ChannelOpt.unsubscribe( "0x2AEcb6DeE3652dA1dD6b54D5fd4f7D8F43DaEb78", userAddress, optOutSinger, ENV.staging).getOrThrow() + success = ChannelOpt.unsubscribe("0x2AEcb6DeE3652dA1dD6b54D5fd4f7D8F43DaEb78", userAddress, optOutSinger, ENV.staging).getOrThrow() assert(success) } } \ No newline at end of file diff --git a/lib/src/test/kotlin/push/kotlin/sdk/GroupTests/UpdateGroupTest.kt b/lib/src/test/kotlin/push/kotlin/sdk/GroupTests/UpdateGroupTest.kt index f49dfe7..e101950 100644 --- a/lib/src/test/kotlin/push/kotlin/sdk/GroupTests/UpdateGroupTest.kt +++ b/lib/src/test/kotlin/push/kotlin/sdk/GroupTests/UpdateGroupTest.kt @@ -7,6 +7,7 @@ import push.kotlin.sdk.* import push.kotlin.sdk.ChatFunctions.ApproveOptions import push.kotlin.sdk.ChatFunctions.ChatApprover import push.kotlin.sdk.Group.PushGroup +import push.kotlin.sdk.PushAPI.PushAPI import kotlin.test.assertEquals class UpdateGroupTest { @@ -254,4 +255,51 @@ class UpdateGroupTest { assertEquals(members.size, 1) assertEquals(members[0].address, Helpers.walletToPCAIP(newAddress)) } + + @Test + fun testGroupMember_(){ + + val (newAddress, signer) = getNewSinger() + + val newUser = PushUser.createUser(signer, ENV.staging).getOrThrow() + val pgpPK = DecryptPgp.decryptPgpKey(newUser.encryptedPrivateKey, signer).getOrThrow() + + val userBob = PushAPI.initialize(signer= signer) + val status = userBob.chat.group.participants.status(chartId = "4c40c821f8486069e401817dd69a54ff404c7d3cdd03a26998960e09d359c6b4", overrideAccount = "0x941aB2Bc7E26BF5Df6e1d4c5a0f12bc5012B922B") +println("Status $status") + + val (member1,_) = getNewSinger() + val (member2,_) = getNewSinger() + val (member3,_) = getNewSinger() + + + val createOptions = PushGroup.CreateGroupOptionsV2( + name = "$newAddress group", + description = "group made my the user $newAddress for testing", + image = BASE_64_IMAGE, + members = mutableListOf(member1), + creatorAddress = newAddress, + isPublic = false, + creatorPgpPrivateKey = pgpPK, + env = ENV.staging, + admins = mutableListOf(), + config = PushGroup.GroupConfig(), + rules = mapOf() + ) + + val group = PushGroup.createGroupV2(createOptions).getOrThrow() + + val options = PushGroup.UpdateGroupMemberOptions( + account = newAddress, + chatId = group.chatId, + pgpPrivateKey = pgpPK, + upsert = PushGroup.UpsertData( + members = listOf(member2), + admins = listOf(member3) + ) + ) + val updatedGroup = PushGroup.updateGroupMember(options, ENV.staging).getOrThrow() + + assertEquals(updatedGroup.chatId, group.chatId) + } } \ No newline at end of file diff --git a/lib/src/test/kotlin/push/kotlin/sdk/PushAPITest/PushAPITest.kt b/lib/src/test/kotlin/push/kotlin/sdk/PushAPITest/PushAPITest.kt index ed23e42..cd4792b 100644 --- a/lib/src/test/kotlin/push/kotlin/sdk/PushAPITest/PushAPITest.kt +++ b/lib/src/test/kotlin/push/kotlin/sdk/PushAPITest/PushAPITest.kt @@ -11,7 +11,7 @@ class PushAPITest { val (newAddress, signer) = getNewSinger() val pushAPI = PushAPI.initialize(signer) - val info = pushAPI.info(); + val info = pushAPI.profile.info(); assertEquals("eip155:$newAddress", info?.did) } } \ No newline at end of file