central.sonatype.com ↗
Kurulumimplementation("io.signalbird:signalbird-sdk:2.10.1")

signalbird-sdk - Kotlin (Android)

İki istemci taşır:

Sınıf Ne için Anahtar Nerede
SignalbirdApp son kullanıcıya canlı sohbet + push kaydı sb_public_live_… (açık) Android uygulaması
SignalbirdClient Telsiz - log ve olay yazma sb_secret_live_… (gizli) sunucu tarafı Kotlin (Ktor, Spring)

Gizli anahtar APK'ya gömülmez: paket çözülebilir ve anahtar herkesin eline geçer. Mobil taraf sohbeti ve push kaydını açık anahtarla yapar.

Kurulum

kotlin
// build.gradle.kts
dependencies {
    implementation("io.signalbird:signalbird-sdk:2.10.1")
}
xml
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET" />

Tek dış bağımlılık coroutines'tir ve her Android projesinde zaten vardır. JSON için Android'in yerleşik org.json'ı kullanılır - OkHttp, Retrofit ya da Moshi dayatılmaz; bir SDK'nın müşterinin ağ ve serileştirme yığınını seçmesi, sürüm çakışmalarının en sık sebebidir.


Ziyaretçi sırrının saklanması

Depo vermek zorunludur. Varsayılan bellek deposudur ve yalnız test içindir: sır cihazda kalmazsa kullanıcı uygulamayı her açtığında sohbet geçmişini kaybeder.

kotlin
class PrefsStorage(context: Context) : SignalbirdStorage {
    private val prefs = context.getSharedPreferences("signalbird", Context.MODE_PRIVATE)

    override fun get(key: String): String? = prefs.getString(key, null)
    override fun set(key: String, value: String) { prefs.edit().putString(key, value).apply() }
    override fun remove(key: String) { prefs.edit().remove(key).apply() }
}

Saklanan kayıt uygulama anahtarını da taşır: anahtarı yenilerseniz eski kimlik otomatik yok sayılır ve yeni oturum açılır.


Canlı sohbet

kotlin
import io.signalbird.sdk.*

val client = SignalbirdApp(SignalbirdAppConfig(
    publicKey = "sb_public_live_…",
    chatKey = "destek",
    pushKey = "mobil",
    locale = "tr",
    storage = PrefsStorage(applicationContext),
))

chatKey sohbet kanalının, pushKey push kanalının modül anahtarıdır (panelde açtığınız kanal adları, gizli değildir). SDK cihaz ve push uçlarında (registerDevice, unregisterDevice, reportPushOpened) pushKey'i, sohbet uçlarında chatKey'i X-Signalbird-Module-Key başlığıyla gönderir; ilgili anahtar verilmezse API 400 MODULE_KEY_MISSING döner (2.10.0).

Uygulama anahtarını panelden (Gelen Kutusu → Ayarlar → Uygulamalar) ya da Yönetim SDK'sıyla createApp çağırarak alırsınız.

Açılış

kotlin
lifecycleScope.launch {
    val boot = client.bootstrap()
    val app = boot.json?.optJSONObject("app")

    if (app?.optBoolean("chat_enabled") != true) return@launch   // sohbet kapalı
}

Oturum ve konuşma

kotlin
lifecycleScope.launch {
    client.startSession(mapOf("name" to "Ayşe", "email" to "ayse@example.com"))

    val started = client.startConversation("Kargom nerede?")
    val conversationId = started.json
        ?.optJSONObject("conversation")
        ?.optString("id") ?: return@launch

    client.sendMessage(conversationId, "Sipariş no: 1234")
}

Yeni mesajları çekme

kotlin
val updates = client.getConversation(conversationId, after = lastMessageId)

WebSocket yoktur. Ekran öndeyken 3 saniyede bir, arka planda kademeli olarak seyrelen aralıklarla yoklayın ve uygulama arka plandayken turu atlayın - bağlantı kopmasında kendi kendini toparlar, pil yakmaz.

kotlin
// Yaşam döngüsüne bağlı yoklama
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.RESUMED) {
        while (isActive) {
            client.getConversation(conversationId, after = lastMessageId)
            delay(3_000)
        }
    }
}

Etkileşimler

kotlin
client.setTyping(conversationId, true)
client.markRead(conversationId, lastMessageId)
client.reactToMessage(conversationId, messageId, "👍")

// Yalnız kendi mesajı ve gönderimden sonraki 15 dakika içinde
client.editMessage(conversationId, messageId, "Düzeltme")
client.deleteMessage(conversationId, messageId)

client.rateConversation(conversationId, rating = 5, comment = "Teşekkürler")
client.closeConversation(conversationId)

Kimlik

kotlin
client.identify(mapOf(
    "external_id" to user.id,
    "email" to user.email,
    "name" to user.displayName,
    "attributes" to mapOf("plan" to "pro"),
))

client.signOut()   // yerel kimliği siler; sunucudaki kayıt kalır

Push (FCM)

kotlin
class SignalbirdMessagingService : FirebaseMessagingService() {
    override fun onNewToken(token: String) {
        CoroutineScope(Dispatchers.IO).launch {
            client.registerDevice(
                token = token,
                externalId = currentUser?.id,
                deviceName = Build.MODEL,
                appVersion = BuildConfig.VERSION_NAME,
            )
        }
    }
}

Android 13+ bildirim iznini istemek (POST_NOTIFICATIONS) ve token'ı almak uygulamanın işidir: izni ne zaman soracağınız bir ürün kararıdır. SDK yalnız token'ı iletir.

Çıkışta:

kotlin
client.unregisterDevice(token)   // kayıt silinmez, kapatılır

Telsiz (sunucu tarafı Kotlin)

kotlin
val radio = SignalbirdClient(SignalbirdConfig(
    domainKey = System.getenv("SIGNALBIRD_DOMAIN_KEY"),
    source = "api-01",
))

radio.critical("critical", "ödeme servisi yanıt vermiyor", mapOf(
    "service" to "iyzico",
))

radio.batch(listOf(
    mapOf("channel" to "deploy", "message" to "v2.4.0 yayında", "level" to "info"),
))

Beş seviye: SignalbirdLevel.DEBUG … CRITICAL.


Sonuç biçimi

kotlin
data class SbResult(
    val ok: Boolean,
    val status: Int,
    val data: Any?,          // JSONObject, JSONArray ya da null
    val code: String?,
    val message: String?,
) {
    val json: JSONObject?
    val array: JSONArray?
}
kotlin
val result = client.listConversations()

result.json?.optJSONArray("data")?.let { list ->
    for (i in 0 until list.length()) {
        val conversation = list.getJSONObject(i)
        // …
    }
}

Sürüm bildirimi

SDK her istekte sürümünü bildirir: X-Signalbird-Sdk: kotlin/<sürüm>. Yeni bir sürüm yayınlandığında API yanıtında Signalbird-Sdk-Status: outdated (ya da artık desteklenmiyorsa unsupported) döner ve SDK süreç başına bir kez uyarı yazar (System.err, Android'de logcat). Uyarı hata değildir: isteğin sonucu değişmez.

Panelde Domainler → [domain] → Anahtarlar her anahtarın hangi SDK sürümüyle kullanıldığını gösterir; eski sürümdeki anahtarlar için panelin tepesinde bir uyarı şeridi ve bildirim çıkar. Güncellemek için build.gradle.kts içindeki io.signalbird:signalbird-sdk sürümünü artırın.

Hata kodları

Kod Anlamı
WRONG_KEY_TYPE Kurucu IllegalArgumentException fırlatır
VISITOR_INVALID Sır geçersiz; yeni oturum açılmalı
CHAT_UNAVAILABLE Kota doldu ya da sohbet kapalı
MODULE_DISABLED Paketinizde chat ya da push modülü yok
NETWORK_ERROR / TIMEOUT Ağ (status 0)

Notlar

  • Tüm metotlar suspend'dir ve Dispatchers.IO üzerinde çalışır; ayrıca bir thread yönetmenize gerek yoktur.
  • PATCH istekleri POST + X-HTTP-Method-Override başlığıyla gider: Android'in HttpURLConnection'ı PATCH metodunu tanımaz. Sunucu tarafında fark yoktur.
  • Kurucudaki anahtar denetimi dışında hiçbir metot hata fırlatmaz; sonuç her zaman zarftır.