Send a Message Programmatically¶
Drive the chat from the host app: send a message as the user without going through the input field. Useful for guided flows, in-app actions ("ask Kindly about my order"), or composing a message from contextual UI.
Usage¶
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import no.kindly.chatsdk.chat.KindlySDK
lifecycleScope.launch {
try {
val message = KindlySDK.sendMessage("Hi, I have a question about my order").await()
println("Sent — server id: ${message.id}")
} catch (e: Exception) {
println("Send failed: ${e.message}")
}
}
If you don't need the reconciled message back, just call it and ignore the Deferred:
You can also observe completion without a coroutine via invokeOnCompletion:
KindlySDK.sendMessage("Hi").invokeOnCompletion { error ->
if (error != null) println("Send failed: $error")
}
With per-call context¶
Attach key/value context to this message only — overrides any context previously staged via setNewContext(...):
KindlySDK.sendMessage(
message = "Where is my order?",
newContext = mapOf("orderId" to "12345", "tier" to "premium"),
)
Important: do not also display the message yourself¶
The SDK renders the bubble locally with a temporary id the moment you call sendMessage, then reconciles with the server-assigned id when the POST response returns. If you also add the message to a chat log you maintain, you'll see it twice.
The message also fires through the unified event stream:
import no.kindly.chatsdk.chat.models.KindlyEvent
lifecycleScope.launch {
KindlySDK.events.collect { event ->
if (event.detail is KindlyEvent.Detail.Message) {
val msg = (event.detail as KindlyEvent.Detail.Message).newMessage
println("${msg.sender}: ${msg.text}")
}
}
}
Errors¶
The Deferred completes exceptionally with a KindlySDKError in these cases:
| Error | Cause |
|---|---|
KindlySDKError.SDKNotInitialized |
KindlySDK.start(...) was never called. |
KindlySDKError.ChatNotConnected |
The chat is not currently connected. Observe KindlySDK.state for isConnected == true before calling, or call launchChat(context) first. |
KindlySDKError.InvalidData |
The message text is empty or only whitespace. |
KindlySDKError.ApiError / other |
Network or server errors are forwarded. |
Behaviour summary¶
- Trims whitespace; empty input completes exceptionally with
KindlySDKError.InvalidData. - Optimistic local render — bubble appears immediately with a temp id.
- POSTs to
/message, reconciles temp id → server id on success. - Emits
KindlyEvent.messagefor the user's message (consumers ofKindlySDK.eventssee it like any other message). - Per-call
newContextoverrides globalsetNewContext(...)for this single call. - Works whether or not the chat UI is currently displayed — the message is delivered, and when the user opens the chat next, they see it in place.