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 Kindly
import Combine
var cancellables = Set<AnyCancellable>()
KindlySDK.sendMessage("Hi, I have a question about my order")
.sink(
receiveCompletion: { completion in
if case .failure(let error) = completion {
print("Send failed: \(error)")
}
},
receiveValue: { (message: ExternalChatMessage) in
print("Sent â server id: \(message.id)")
}
)
.store(in: &cancellables)If you don't need the reconciled message, just call it and ignore the promise:
KindlySDK.sendMessage("Hi, I have a question about my order")With per-call context
Attach key/value context to this message only â overrides any context previously staged via setNewContext(_:):
KindlySDK.sendMessage(
"Where is my order?",
newContext: ["orderId": "12345", "tier": "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:
KindlySDK.events
.sink { event in
if case .message(let newMessage, _) = event.detail {
print("\(newMessage.sender) said: \(newMessage.text ?? "")")
}
}
.store(in: &cancellables)Errors
The promise rejects with a KindlySDKError in these cases:
Error | Cause |
|---|---|
.sdkNotInitialized | KindlySDK.start(...) was never called. |
.chatNotConnected | The chat is not currently connected. Observe KindlySDK.state for isConnected == true before calling, or call displayChat() first. |
.invalidData | The message text is empty or only whitespace. |
Other | Network or server errors are forwarded as-is. |
Behaviour summary
- Trims whitespace; empty input rejects with .invalidData.
- Optimistic local render â bubble appears immediately with a temp id.
- POSTs to /message, reconciles temp id â server id on success.
- Emits KindlyEvent.message for the user's message (consumers of KindlySDK.events see it like any other message).
- Per-call newContext overrides global setNewContext(_:) 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.