diff --git a/README.md b/README.md index 438e746..c782f6b 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ dependencies { ```kotlin XuqmSDK.initialize( context = this, - appId = "ak_your_app_id", + appKey = "ak_your_app_key", logLevel = if (BuildConfig.DEBUG) LogLevel.DEBUG else LogLevel.WARN ) ``` @@ -102,7 +102,7 @@ sample-app 里也提供了一个“环境设置”页面,可以直接在外网 | 参数 | 类型 | 说明 | |------|------|------| -| `appId` | String | 应用标识(租户平台获取) | +| `appKey` | String | 应用标识(租户平台获取) | | `logLevel` | LogLevel | 日志等级 | ### TokenStore diff --git a/gradle/publish.gradle.kts b/gradle/publish.gradle.kts index 1889b05..4c0ae3a 100644 --- a/gradle/publish.gradle.kts +++ b/gradle/publish.gradle.kts @@ -1,11 +1,14 @@ +import org.gradle.api.publish.PublishingExtension + apply(plugin = "maven-publish") afterEvaluate { - (extensions.findByType(com.android.build.gradle.LibraryExtension::class.java))?.let { + if (extensions.findByName("android") != null) { + val releaseComponent = components.findByName("release") ?: return@afterEvaluate extensions.configure { publications { register("release") { - from(components["release"]) + from(releaseComponent) groupId = rootProject.group.toString() artifactId = project.name version = rootProject.version.toString() @@ -13,10 +16,10 @@ afterEvaluate { } repositories { maven { - url = uri(rootProject.ext["nexusUrl"] as String) + url = uri(rootProject.extra["nexusUrl"] as String) credentials { - username = rootProject.ext["nexusUser"] as String - password = rootProject.ext["nexusPassword"] as String + username = rootProject.extra["nexusUser"] as String + password = rootProject.extra["nexusPassword"] as String } } } diff --git a/sample-app/src/main/java/com/xuqm/sdk/sample/XuqmSampleApp.kt b/sample-app/src/main/java/com/xuqm/sdk/sample/XuqmSampleApp.kt index 5404dd6..8f49941 100644 --- a/sample-app/src/main/java/com/xuqm/sdk/sample/XuqmSampleApp.kt +++ b/sample-app/src/main/java/com/xuqm/sdk/sample/XuqmSampleApp.kt @@ -18,7 +18,7 @@ class XuqmSampleApp : Application() { AppDependencies.init(this) XuqmSDK.initialize( context = this, - appId = "ak_demo_chat", + appKey = "ak_demo_chat", logLevel = if (BuildConfig.DEBUG) LogLevel.DEBUG else LogLevel.WARN, ) appScope.launch { diff --git a/sdk-core/src/main/java/com/xuqm/sdk/XuqmLoginSession.kt b/sdk-core/src/main/java/com/xuqm/sdk/XuqmLoginSession.kt index 663bdf8..58dba2d 100644 --- a/sdk-core/src/main/java/com/xuqm/sdk/XuqmLoginSession.kt +++ b/sdk-core/src/main/java/com/xuqm/sdk/XuqmLoginSession.kt @@ -1,7 +1,7 @@ package com.xuqm.sdk data class XuqmLoginSession( - val appId: String, + val appKey: String, val userId: String, val userSig: String, val nickname: String? = null, diff --git a/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt b/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt index a1e6968..ce32a16 100644 --- a/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt +++ b/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt @@ -27,10 +27,10 @@ object XuqmSDK { fun initialize( context: Context, - appId: String, + appKey: String, logLevel: LogLevel = LogLevel.WARN, ) { - config = SDKConfig(appId, logLevel) + config = SDKConfig(appKey, logLevel) appContext = context.applicationContext tokenStore = TokenStore(context.applicationContext) ApiClient.init(config, tokenStore) @@ -55,7 +55,7 @@ object XuqmSDK { check(initialized) { "XuqmSDK not initialized. Call XuqmSDK.initialize() first." } } - val appId: String get() = config.appId + val appKey: String get() = config.appKey val currentLoginSession: XuqmLoginSession? get() = loginSession @@ -68,7 +68,7 @@ object XuqmSDK { ): XuqmLoginSession = withContext(Dispatchers.IO) { requireInit() val session = XuqmLoginSession( - appId = appId, + appKey = appKey, userId = userId, userSig = userSig, nickname = nickname, diff --git a/sdk-core/src/main/java/com/xuqm/sdk/core/SDKConfig.kt b/sdk-core/src/main/java/com/xuqm/sdk/core/SDKConfig.kt index 36e45d7..dda4a3e 100644 --- a/sdk-core/src/main/java/com/xuqm/sdk/core/SDKConfig.kt +++ b/sdk-core/src/main/java/com/xuqm/sdk/core/SDKConfig.kt @@ -1,7 +1,7 @@ package com.xuqm.sdk.core data class SDKConfig( - val appId: String, + val appKey: String, val logLevel: LogLevel = LogLevel.WARN, ) diff --git a/sdk-im/src/main/java/com/xuqm/sdk/im/ImSDK.kt b/sdk-im/src/main/java/com/xuqm/sdk/im/ImSDK.kt index d4535b5..0a78f0b 100644 --- a/sdk-im/src/main/java/com/xuqm/sdk/im/ImSDK.kt +++ b/sdk-im/src/main/java/com/xuqm/sdk/im/ImSDK.kt @@ -144,10 +144,10 @@ object ImSDK { } suspend fun editMessage(messageId: String, content: String): ImMessage = - withContext(Dispatchers.IO) { api.editMessage(messageId, XuqmSDK.appId, EditMessageRequest(content)).data ?: throw IllegalStateException("edit message failed") } + withContext(Dispatchers.IO) { api.editMessage(messageId, XuqmSDK.appKey, EditMessageRequest(content)).data ?: throw IllegalStateException("edit message failed") } suspend fun revokeMessage(messageId: String): ImMessage = - withContext(Dispatchers.IO) { api.revokeMessage(messageId, XuqmSDK.appId).data ?: throw IllegalStateException("revoke message failed") } + withContext(Dispatchers.IO) { api.revokeMessage(messageId, XuqmSDK.appKey).data ?: throw IllegalStateException("revoke message failed") } fun sendImageMessage( toId: String, @@ -407,7 +407,7 @@ object ImSDK { withContext(Dispatchers.IO) { api.fetchHistory( toId, - XuqmSDK.appId, + XuqmSDK.appKey, msgType, keyword, startTime?.toString(), @@ -432,7 +432,7 @@ object ImSDK { withContext(Dispatchers.IO) { api.fetchGroupHistory( groupId, - XuqmSDK.appId, + XuqmSDK.appKey, msgType, keyword, startTime?.toString(), @@ -485,30 +485,30 @@ object ImSDK { } suspend fun listGroups(): List = - withContext(Dispatchers.IO) { api.listGroups(XuqmSDK.appId).data ?: emptyList() } + withContext(Dispatchers.IO) { api.listGroups(XuqmSDK.appKey).data ?: emptyList() } suspend fun createGroup(name: String, memberIds: List, groupType: String = "WORK"): ImGroup? = withContext(Dispatchers.IO) { - api.createGroup(XuqmSDK.appId, CreateGroupRequest(name, memberIds, groupType)).data + api.createGroup(XuqmSDK.appKey, CreateGroupRequest(name, memberIds, groupType)).data } suspend fun getGroupInfo(groupId: String): ImGroup? = withContext(Dispatchers.IO) { api.getGroupInfo(groupId).data } suspend fun listGroupMembers(groupId: String): List = - withContext(Dispatchers.IO) { api.listGroupMembers(groupId, XuqmSDK.appId).data ?: emptyList() } + withContext(Dispatchers.IO) { api.listGroupMembers(groupId, XuqmSDK.appKey).data ?: emptyList() } suspend fun searchGroupMembers(groupId: String, keyword: String, size: Int = 20): List = - withContext(Dispatchers.IO) { api.searchGroupMembers(groupId, XuqmSDK.appId, keyword, size).data ?: emptyList() } + withContext(Dispatchers.IO) { api.searchGroupMembers(groupId, XuqmSDK.appKey, keyword, size).data ?: emptyList() } suspend fun listPublicGroups(keyword: String? = null): List = - withContext(Dispatchers.IO) { api.listPublicGroups(XuqmSDK.appId, keyword).data ?: emptyList() } + withContext(Dispatchers.IO) { api.listPublicGroups(XuqmSDK.appKey, keyword).data ?: emptyList() } suspend fun searchUsers(keyword: String, size: Int = 20): List = - withContext(Dispatchers.IO) { api.searchUsers(XuqmSDK.appId, keyword, size).data ?: emptyList() } + withContext(Dispatchers.IO) { api.searchUsers(XuqmSDK.appKey, keyword, size).data ?: emptyList() } suspend fun searchGroups(keyword: String, size: Int = 20): List = - withContext(Dispatchers.IO) { api.searchGroups(XuqmSDK.appId, keyword, size).data ?: emptyList() } + withContext(Dispatchers.IO) { api.searchGroups(XuqmSDK.appKey, keyword, size).data ?: emptyList() } suspend fun searchMessages( keyword: String? = null, @@ -521,7 +521,7 @@ object ImSDK { ): PageResult = withContext(Dispatchers.IO) { api.searchMessages( - XuqmSDK.appId, + XuqmSDK.appKey, keyword, chatType, msgType, @@ -554,49 +554,49 @@ object ImSDK { withContext(Dispatchers.IO) { api.dismissGroup(groupId) } suspend fun sendGroupJoinRequest(groupId: String, remark: String? = null): GroupJoinRequest? = - withContext(Dispatchers.IO) { api.sendGroupJoinRequest(groupId, XuqmSDK.appId, remark).data } + withContext(Dispatchers.IO) { api.sendGroupJoinRequest(groupId, XuqmSDK.appKey, remark).data } suspend fun listGroupJoinRequests(groupId: String): List = - withContext(Dispatchers.IO) { api.listGroupJoinRequests(groupId, XuqmSDK.appId).data ?: emptyList() } + withContext(Dispatchers.IO) { api.listGroupJoinRequests(groupId, XuqmSDK.appKey).data ?: emptyList() } suspend fun acceptGroupJoinRequest(groupId: String, requestId: String): GroupJoinRequest? = - withContext(Dispatchers.IO) { api.acceptGroupJoinRequest(groupId, requestId, XuqmSDK.appId).data } + withContext(Dispatchers.IO) { api.acceptGroupJoinRequest(groupId, requestId, XuqmSDK.appKey).data } suspend fun rejectGroupJoinRequest(groupId: String, requestId: String): GroupJoinRequest? = - withContext(Dispatchers.IO) { api.rejectGroupJoinRequest(groupId, requestId, XuqmSDK.appId).data } + withContext(Dispatchers.IO) { api.rejectGroupJoinRequest(groupId, requestId, XuqmSDK.appKey).data } suspend fun listFriends(): List = - withContext(Dispatchers.IO) { api.listFriends(XuqmSDK.appId).data ?: emptyList() } + withContext(Dispatchers.IO) { api.listFriends(XuqmSDK.appKey).data ?: emptyList() } suspend fun addFriend(friendId: String) = - withContext(Dispatchers.IO) { api.addFriend(XuqmSDK.appId, friendId) } + withContext(Dispatchers.IO) { api.addFriend(XuqmSDK.appKey, friendId) } suspend fun removeFriend(friendId: String) = - withContext(Dispatchers.IO) { api.removeFriend(friendId, XuqmSDK.appId) } + withContext(Dispatchers.IO) { api.removeFriend(friendId, XuqmSDK.appKey) } suspend fun listFriendRequests(direction: String = "incoming"): List = - withContext(Dispatchers.IO) { api.listFriendRequests(XuqmSDK.appId, direction).data ?: emptyList() } + withContext(Dispatchers.IO) { api.listFriendRequests(XuqmSDK.appKey, direction).data ?: emptyList() } suspend fun sendFriendRequest(friendId: String, remark: String? = null): FriendRequest? = - withContext(Dispatchers.IO) { api.sendFriendRequest(XuqmSDK.appId, friendId, remark).data } + withContext(Dispatchers.IO) { api.sendFriendRequest(XuqmSDK.appKey, friendId, remark).data } suspend fun acceptFriendRequest(requestId: String): FriendRequest? = - withContext(Dispatchers.IO) { api.acceptFriendRequest(requestId, XuqmSDK.appId).data } + withContext(Dispatchers.IO) { api.acceptFriendRequest(requestId, XuqmSDK.appKey).data } suspend fun rejectFriendRequest(requestId: String): FriendRequest? = - withContext(Dispatchers.IO) { api.rejectFriendRequest(requestId, XuqmSDK.appId).data } + withContext(Dispatchers.IO) { api.rejectFriendRequest(requestId, XuqmSDK.appKey).data } suspend fun listBlacklist(): List = - withContext(Dispatchers.IO) { api.listBlacklist(XuqmSDK.appId).data ?: emptyList() } + withContext(Dispatchers.IO) { api.listBlacklist(XuqmSDK.appKey).data ?: emptyList() } suspend fun addToBlacklist(blockedUserId: String): BlacklistEntry? = - withContext(Dispatchers.IO) { api.addToBlacklist(XuqmSDK.appId, blockedUserId).data } + withContext(Dispatchers.IO) { api.addToBlacklist(XuqmSDK.appKey, blockedUserId).data } suspend fun removeFromBlacklist(blockedUserId: String) = - withContext(Dispatchers.IO) { api.removeFromBlacklist(XuqmSDK.appId, blockedUserId) } + withContext(Dispatchers.IO) { api.removeFromBlacklist(XuqmSDK.appKey, blockedUserId) } suspend fun getProfile(userId: String) = - withContext(Dispatchers.IO) { api.getProfile(userId, XuqmSDK.appId).data } + withContext(Dispatchers.IO) { api.getProfile(userId, XuqmSDK.appKey).data } suspend fun updateProfile( userId: String, @@ -604,11 +604,11 @@ object ImSDK { avatar: String? = null, gender: String? = null, ) = withContext(Dispatchers.IO) { - api.updateProfile(userId, XuqmSDK.appId, nickname, avatar, gender).data + api.updateProfile(userId, XuqmSDK.appKey, nickname, avatar, gender).data } suspend fun listConversations(): List = - withContext(Dispatchers.IO) { api.listConversations(XuqmSDK.appId).data ?: emptyList() } + withContext(Dispatchers.IO) { api.listConversations(XuqmSDK.appKey).data ?: emptyList() } suspend fun getTotalUnreadCount(): Int = withContext(Dispatchers.IO) { @@ -626,13 +626,13 @@ object ImSDK { } suspend fun markRead(targetId: String, chatType: String = "SINGLE") = - withContext(Dispatchers.IO) { api.markRead(targetId, XuqmSDK.appId, chatType) } + withContext(Dispatchers.IO) { api.markRead(targetId, XuqmSDK.appKey, chatType) } suspend fun setDraft(targetId: String, chatType: String, draft: String) = - withContext(Dispatchers.IO) { api.setDraft(targetId, XuqmSDK.appId, chatType, draft) } + withContext(Dispatchers.IO) { api.setDraft(targetId, XuqmSDK.appKey, chatType, draft) } suspend fun deleteConversation(targetId: String, chatType: String) = - withContext(Dispatchers.IO) { api.deleteConversation(targetId, XuqmSDK.appId, chatType) } + withContext(Dispatchers.IO) { api.deleteConversation(targetId, XuqmSDK.appKey, chatType) } fun addListener(listener: ImEventListener) { Log.d(TAG, "addListener listener=${listener.javaClass.name}") @@ -669,7 +669,7 @@ object ImSDK { _connectionState.value = ImConnectionState.Connecting currentToken = token Log.d(TAG, "connectWithToken userId=$currentUserId activeGroups=${activeGroupSubscriptions.size}") - client = ImClient(ServiceEndpointRegistry.imWsUrl, token, XuqmSDK.appId) + client = ImClient(ServiceEndpointRegistry.imWsUrl, token, XuqmSDK.appKey) client?.addListener(connectionListener) listeners.forEach { client?.addListener(it) } reconnectEnabled = true @@ -742,7 +742,7 @@ object ImSDK { ): ImMessage { return ImMessage( id = messageId, - appId = XuqmSDK.appId, + appId = XuqmSDK.appKey, fromId = currentUserId, toId = toId, chatType = chatType, @@ -769,7 +769,7 @@ object ImSDK { reconnectAttempts += 1 _connectionState.value = ImConnectionState.Connecting Log.d(TAG, "reconnect attempt=$reconnectAttempts") - client = ImClient(ServiceEndpointRegistry.imWsUrl, currentToken, XuqmSDK.appId) + client = ImClient(ServiceEndpointRegistry.imWsUrl, currentToken, XuqmSDK.appKey) client?.addListener(connectionListener) listeners.forEach { client?.addListener(it) } client?.connect() diff --git a/sdk-push/src/main/java/com/xuqm/sdk/push/PushSDK.kt b/sdk-push/src/main/java/com/xuqm/sdk/push/PushSDK.kt index 2111303..3274373 100644 --- a/sdk-push/src/main/java/com/xuqm/sdk/push/PushSDK.kt +++ b/sdk-push/src/main/java/com/xuqm/sdk/push/PushSDK.kt @@ -67,7 +67,7 @@ object PushSDK { scope.launch { runCatching { api.setReceivePush( - appId = XuqmSDK.appId, + appId = XuqmSDK.appKey, userId = resolvedUserId, enabled = enabled, ) @@ -95,7 +95,7 @@ object PushSDK { scope.launch { runCatching { api.registerDevice( - appId = XuqmSDK.appId, + appId = XuqmSDK.appKey, userId = userId, vendor = vendor.name, token = pushToken, @@ -114,7 +114,7 @@ object PushSDK { XuqmSDK.requireInit() scope.launch { runCatching { - api.unregisterDevice(XuqmSDK.appId, userId) + api.unregisterDevice(XuqmSDK.appKey, userId) registeredUserId.compareAndSet(userId, null) store(XuqmSDK.appContext).updateLastUserId(null) } diff --git a/sdk-update/scripts/xuqm_release.gradle.kts b/sdk-update/scripts/xuqm_release.gradle.kts index d31bb6e..e6d5ebb 100644 --- a/sdk-update/scripts/xuqm_release.gradle.kts +++ b/sdk-update/scripts/xuqm_release.gradle.kts @@ -10,8 +10,13 @@ * Config: xuqm.properties in the project root (or module root) * --- * xuqm.serverUrl=https://update.dev.xuqinmin.com - * xuqm.appId=your-app-id + * xuqm.appKey=your-app-key * xuqm.apiToken=your-api-token + * xuqm.storeTargets=HUAWEI,MI,OPPO # optional + * xuqm.autoPublishAfterReview=false + * xuqm.publishImmediately=false # optional: publish update-service record immediately + * xuqm.scheduledPublishAt= # optional ISO datetime + * xuqm.webhookUrl= # optional webhook for review status changes * --- * * The task: @@ -31,7 +36,6 @@ import java.net.URI import java.net.http.HttpClient import java.net.http.HttpRequest import java.net.http.HttpResponse -import java.nio.file.Files import java.util.Properties import java.util.UUID @@ -101,6 +105,35 @@ fun parseJson(json: String, key: String): String? = fun parseJsonInt(json: String, key: String): Int? = Regex("\"$key\"\\s*:\\s*(\\d+)").find(json)?.groupValues?.get(1)?.toIntOrNull() +fun promptLine(message: String): String? { + val console = System.console() ?: return null + print(message) + return console.readLine() +} + +fun promptYesNo(message: String, default: Boolean = false): Boolean { + val suffix = if (default) " [Y/n]: " else " [y/N]: " + val answer = promptLine(message + suffix)?.trim().orEmpty() + return when { + answer.isBlank() -> default + answer.equals("y", ignoreCase = true) || answer.equals("yes", ignoreCase = true) -> true + answer.equals("n", ignoreCase = true) || answer.equals("no", ignoreCase = true) -> false + else -> default + } +} + +fun promptReleaseMode(): String { + val answer = promptLine( + "Publish mode? [1=manual, 2=publish now, 3=scheduled, 4=auto after review]: " + )?.trim().orEmpty() + return when (answer) { + "2" -> "NOW" + "3" -> "SCHEDULED" + "4" -> "AUTO_REVIEW" + else -> "MANUAL" + } +} + // ── Task registration ───────────────────────────────────────────────────── tasks.register("xuqmRelease") { @@ -113,12 +146,20 @@ tasks.register("xuqmRelease") { doLast { val cfg = loadXuqmConfig(projectDir) val serverUrl = cfg.getProperty("xuqm.serverUrl") ?: throw GradleException("xuqm.serverUrl missing") - val appId = cfg.getProperty("xuqm.appId") ?: throw GradleException("xuqm.appId missing") + val appKey = cfg.getProperty("xuqm.appKey") ?: throw GradleException("xuqm.appKey missing") val apiToken = cfg.getProperty("xuqm.apiToken") ?: throw GradleException("xuqm.apiToken missing") val storeTargets = cfg.getProperty("xuqm.storeTargets", "") // e.g. "HUAWEI,MI,OPPO" val autoPublish = cfg.getProperty("xuqm.autoPublishAfterReview", "false").toBoolean() - val scheduledAt = cfg.getProperty("xuqm.scheduledPublishAt", "") + val publishImmediately = cfg.getProperty("xuqm.publishImmediately", "false").toBoolean() + var scheduledAt = cfg.getProperty("xuqm.scheduledPublishAt", "") val webhookUrl = cfg.getProperty("xuqm.webhookUrl", "") + var publishMode = cfg.getProperty("xuqm.publishMode", "").trim().uppercase() + if (publishMode.isBlank() && !publishImmediately && scheduledAt.isBlank() && !autoPublish && System.console() != null) { + publishMode = promptReleaseMode() + if (publishMode == "SCHEDULED" && scheduledAt.isBlank()) { + scheduledAt = promptLine("Scheduled publish time (ISO datetime): ")?.trim().orEmpty() + } + } // ── 1. Read local version ────────────────────────────────────────── val android = project.extensions.findByName("android") @@ -129,10 +170,10 @@ tasks.register("xuqmRelease") { val versionCode = (defaultConfig::class.java.getMethod("getVersionCode").invoke(defaultConfig) as? Int) ?: throw GradleException("versionCode not set") val applicationId = defaultConfig::class.java.getMethod("getApplicationId").invoke(defaultConfig) as? String ?: "" - println("[xuqm] Local version: $versionName ($versionCode), packageName: $applicationId") + println("[xuqm] Local version: $versionName ($versionCode), packageName: $applicationId, appKey: $appKey") // ── 2. Check server latest ───────────────────────────────────────── - val listResp = httpGet("$serverUrl/api/v1/updates/app/list?appId=$appId&platform=ANDROID", apiToken) + val listResp = httpGet("$serverUrl/api/v1/updates/app/list?appId=$appKey&platform=ANDROID", apiToken) // Find highest published versionCode val serverVersionCode = Regex("\"versionCode\"\\s*:\\s*(\\d+)").findAll(listResp) .mapNotNull { it.groupValues[1].toIntOrNull() } @@ -154,7 +195,7 @@ tasks.register("xuqmRelease") { // ── 4. Upload to update service ─────────────────────────────────── val parts = mutableMapOf( - "appId" to appId, + "appId" to appKey, "platform" to "ANDROID", "versionName" to versionName, "versionCode" to versionCode, @@ -166,6 +207,7 @@ tasks.register("xuqmRelease") { if (storeTargets.isNotBlank()) parts["storeSubmitTargets"] = "[\"${storeTargets.split(",").joinToString("\",\"")}\"]" if (scheduledAt.isNotBlank()) parts["scheduledPublishAt"] = scheduledAt if (webhookUrl.isNotBlank()) parts["webhookUrl"] = webhookUrl + if (publishMode == "NOW") parts["publishImmediately"] = "true" println("[xuqm] Uploading APK...") val uploadResp = httpMultipartPost("$serverUrl/api/v1/updates/app/upload", apiToken, parts) @@ -187,12 +229,24 @@ tasks.register("xuqmRelease") { println("[xuqm] Store submission triggered (HTTP ${storeResp.statusCode()})") } - println("[xuqm] Done. Version is in DRAFT state.") - if (scheduledAt.isNotBlank()) { - println("[xuqm] Will auto-publish at: $scheduledAt") + if (publishImmediately || publishMode == "NOW") { + println("[xuqm] Published immediately in update service.") + } else if (publishMode == "SCHEDULED" || scheduledAt.isNotBlank()) { + println("[xuqm] Will auto-publish at: ${scheduledAt.ifBlank { "(use update service scheduled publish config)" }}") } else if (autoPublish) { println("[xuqm] Will auto-publish after all store reviews pass.") - } else { + } else if (System.console() != null && promptYesNo("[xuqm] Publish now?", false)) { + val client = HttpClient.newHttpClient() + val req = HttpRequest.newBuilder(URI.create("$serverUrl/api/v1/updates/app/$versionId/publish")) + .header("Authorization", "Bearer $apiToken") + .POST(HttpRequest.BodyPublishers.noBody()) + .build() + val publishResp = client.send(req, HttpResponse.BodyHandlers.ofString()) + println("[xuqm] Publish HTTP ${publishResp.statusCode()}") + } + + println("[xuqm] Done. Version is in DRAFT state.") + if (!publishImmediately && publishMode != "NOW" && scheduledAt.isBlank() && !autoPublish) { println("[xuqm] Publish manually: POST $serverUrl/api/v1/updates/app/$versionId/publish") } } diff --git a/sdk-update/src/main/java/com/xuqm/sdk/update/UpdateSDK.kt b/sdk-update/src/main/java/com/xuqm/sdk/update/UpdateSDK.kt index 90b17f3..be527fe 100644 --- a/sdk-update/src/main/java/com/xuqm/sdk/update/UpdateSDK.kt +++ b/sdk-update/src/main/java/com/xuqm/sdk/update/UpdateSDK.kt @@ -36,7 +36,7 @@ object UpdateSDK { val versionCode = context.packageManager .getPackageInfo(context.packageName, 0).longVersionCode.toInt() runCatching { - api.checkUpdate(XuqmSDK.appId, "ANDROID", versionCode).data?.let { + api.checkUpdate(XuqmSDK.appKey, "ANDROID", versionCode).data?.let { it.copy(downloadUrl = normalizeDownloadUrl(it.downloadUrl) ?: it.downloadUrl) } }.getOrNull()