package com.kbchatmq.sdk import org.json.JSONObject import java.io.BufferedReader import java.io.InputStreamReader import java.net.HttpURLConnection import java.net.URL import java.nio.charset.StandardCharsets /** * KBChatMQ Hub — HTTP client (Kotlin, Android, không thêm dependency). * Chỉ [apiBase] từ URL Hub; mọi secret truyền khi gọi API. */ class KbChatMqClient(baseUrl: String) { private val apiBase: String = baseUrl.trim().trimEnd { it == '/' }.let { s -> if (s.endsWith("/api")) s else "$s/api" } data class JsonResult(val ok: Boolean, val status: Int, val data: JSONObject) private fun jsonRequest( path: String, method: String, body: JSONObject? = null ): JsonResult { val p = if (path.startsWith("/")) path else "/$path" val conn = URL(apiBase + p).openConnection() as HttpURLConnection conn.requestMethod = method conn.setRequestProperty("Accept", "application/json") conn.connectTimeout = 30_000 conn.readTimeout = 60_000 if (body != null && (method == "POST" || method == "PUT")) { conn.doOutput = true conn.setRequestProperty("Content-Type", "application/json; charset=utf-8") conn.outputStream.use { it.write(body.toString().toByteArray(StandardCharsets.UTF_8)) } } val status = conn.responseCode val stream = if (status in 200..299) conn.inputStream else conn.errorStream val text = stream?.use { ins -> BufferedReader(InputStreamReader(ins, StandardCharsets.UTF_8)).readText() } ?: "" val data = try { if (text.isBlank()) JSONObject() else JSONObject(text) } catch (_: Exception) { JSONObject().put("ok", false).put("error", "invalid_json") } val ok = status in 200..299 && data.optBoolean("ok", true) return JsonResult(ok, status, data) } fun loginWithPassword(userId: String, password: String) = jsonRequest("/auth/login", "POST", JSONObject().put("userId", userId).put("password", password)) fun loginWithUserToken(userToken: String) = jsonRequest("/auth/login-token", "POST", JSONObject().put("userToken", userToken)) fun loginVisitor(websiteToken: String, visitorId: String? = null): JsonResult { val o = JSONObject().put("websiteToken", websiteToken) visitorId?.let { o.put("visitorId", it) } return jsonRequest("/auth/login-visitor", "POST", o) } fun loginDevice(deviceToken: String, deviceId: String? = null): JsonResult { val o = JSONObject().put("deviceToken", deviceToken) deviceId?.let { o.put("deviceId", it) } return jsonRequest("/auth/login-device", "POST", o) } fun chatRooms(authBody: JSONObject) = jsonRequest("/auth/chat-rooms", "POST", authBody) fun getHeartbeatConfig() = jsonRequest("/chat/heartbeat-config", "GET", null) fun heartbeat(payload: JSONObject) = jsonRequest("/chat/heartbeat", "POST", payload) fun getPresence() = jsonRequest("/chat/presence", "GET", null) }