implementation("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
// build.gradle.kts
dependencies {
implementation("io.signalbird:signalbird-sdk:2.10.1")
}<!-- 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.
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
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ış
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
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
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.
// 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
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
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ırPush (FCM)
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:
client.unregisterDevice(token) // kayıt silinmez, kapatılırTelsiz (sunucu tarafı 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
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?
}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 veDispatchers.IOüzerinde çalışır; ayrıca bir thread yönetmenize gerek yoktur. - PATCH istekleri POST +
X-HTTP-Method-Overridebaşlığıyla gider: Android'inHttpURLConnection'ı 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.